Changeset: c0b5e08a910f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c0b5e08a910f
Modified Files:
sql/server/rel_optimizer.c
sql/server/rel_rel.c
sql/server/rel_rel.h
sql/server/rel_select.c
Branch: subquery
Log Message:
fixing crashes, ie save handling of expressions in order/rank and group by
diffs (truncated from 570 to 300 lines):
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -6821,6 +6821,18 @@ rel_dce(mvc *sql, sql_rel *rel)
}
rel_dce_refs(sql, rel, refs);
+ if (refs) {
+ node *n;
+
+ for(n = refs->h; n; n = n->next) {
+ sql_rel *i = n->data;
+
+ while (!rel_is_ref(i) && i->l && !is_base(i->op))
+ i = i->l;
+ if (i)
+ rel_used(i);
+ }
+ }
rel = rel_add_projects(sql, rel);
rel_used(rel);
rel_dce_sub(sql, rel, refs);
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -265,7 +265,7 @@ rel_bind_column( mvc *sql, sql_rel *rel,
{
sql_rel *p = NULL;
- if (is_sql_sel(f) && rel && is_project(rel->op) && !is_processed(rel))
+ if (is_sql_sel(f) && rel && is_simple_project(rel->op) &&
!is_processed(rel))
rel = rel->l;
if (!rel || (rel = rel_bind_column_(sql, &p, rel, cname)) == NULL)
diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h
--- a/sql/server/rel_rel.h
+++ b/sql/server/rel_rel.h
@@ -19,6 +19,7 @@
#define sql_orderby 16
#define sql_groupby 32 //ORed
#define sql_partitionby 64 //ORed
+#define sql_aggr 128 //ORed
#define is_sql_from(X) ((X & sql_from) == sql_from)
#define is_sql_where(X) ((X & sql_where) == sql_where)
@@ -27,6 +28,7 @@
#define is_sql_orderby(X) ((X & sql_orderby) == sql_orderby)
#define is_sql_groupby(X) ((X & sql_groupby) == sql_groupby)
#define is_sql_partitionby(X) ((X & sql_partitionby) == sql_partitionby)
+#define is_sql_aggr(X) ((X & sql_aggr) == sql_aggr)
#define ERR_AMBIGUOUS 050000
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -998,7 +998,7 @@ rel_column_ref(sql_query *query, sql_rel
return rel_var_ref(sql, name, 0);
}
if (!exp && !var) {
- if (rel && *rel && (*rel)->card <= CARD_AGGR &&
is_sql_sel(f)) {
+ if (rel && *rel && (*rel)->card <= CARD_AGGR &&
is_sql_sel(f) && !is_sql_aggr(f)) {
sql_rel *gb = *rel;
while(gb->l && !is_groupby(gb->op))
@@ -1010,6 +1010,9 @@ rel_column_ref(sql_query *query, sql_rel
return sql_error(sql, 02, SQLSTATE(42000)
"SELECT: cannot use non GROUP BY column '%s' in query results without an
aggregate function", name);
return sql_error(sql, 02, SQLSTATE(42000) "SELECT:
identifier '%s' unknown", name);
}
+ if (exp && rel && *rel && (*rel)->card <= CARD_AGGR &&
exp->card > CARD_AGGR && is_sql_sel(f) && !is_sql_aggr(f)) {
+ return sql_error(sql, 02, SQLSTATE(42000) "SELECT:
cannot use non GROUP BY column '%s' in query results without an aggregate
function", name);
+ }
} else if (dlist_length(l) == 2) {
char *tname = l->h->data.sval;
@@ -1043,7 +1046,7 @@ rel_column_ref(sql_query *query, sql_rel
}
}
if (!exp) {
- if (rel && *rel && (*rel)->card == CARD_AGGR &&
is_sql_sel(f)) {
+ if (rel && *rel && (*rel)->card == CARD_AGGR &&
is_sql_sel(f) && !is_sql_aggr(f)) {
sql_rel *gb = *rel;
while(gb->l && !is_groupby(gb->op) &&
is_project(gb->op))
@@ -1055,6 +1058,9 @@ rel_column_ref(sql_query *query, sql_rel
return sql_error(sql, 02, SQLSTATE(42S22)
"SELECT: cannot use non GROUP BY column '%s.%s' in query results without an
aggregate function", tname, cname);
return sql_error(sql, 02, SQLSTATE(42S22) "SELECT: no
such column '%s.%s'", tname, cname);
}
+ if (exp && rel && *rel && (*rel)->card == CARD_AGGR &&
exp->card > CARD_AGGR && is_sql_sel(f) && !is_sql_aggr(f)) {
+ return sql_error(sql, 02, SQLSTATE(42000) "SELECT:
cannot use non GROUP BY column '%s.%s' in query results without an aggregate
function", tname, cname);
+ }
} else if (dlist_length(l) >= 3) {
return sql_error(sql, 02, SQLSTATE(42000) "TODO: column names
of level >= 3");
}
@@ -1934,13 +1940,13 @@ rel_in_value_exp(sql_query *query, sql_r
for (; n; n = n->next) {
sql_rel *z = NULL;
- r = rel_value_exp(query, &z, n->data.sym, sql_where /*
ie no result project */, ek);
+ r = rel_value_exp(query, &z, n->data.sym, f /* ie no
result project */, ek);
if (l && !r) {
/* reset error */
sql->session->status = 0;
sql->errstr[0] = 0;
- r = rel_value_exp(query, &left, n->data.sym,
sql_where /* ie no result project */, ek);
+ r = rel_value_exp(query, &left, n->data.sym, f
/* ie no result project */, ek);
if (r && !pexps)
*rel = left;
}
@@ -1995,7 +2001,7 @@ rel_in_value_exp(sql_query *query, sql_r
sql->errstr[0] = 0;
query_push_outer(query, left);
- r = rel_value_exp(query, &z, n->data.sym,
sql_where /* ie no result project */, ek);
+ r = rel_value_exp(query, &z, n->data.sym, f /*
ie no result project */, ek);
query_pop_outer(query);
if (z)
r = rel_lastexp(sql, z);
@@ -2659,14 +2665,14 @@ rel_in_exp(sql_query *query, sql_rel *re
for (; n; n = n->next) {
sql_rel *z = NULL;
- r = rel_value_exp(query, &z, n->data.sym, sql_where /*
ie no result project */, ek);
+ r = rel_value_exp(query, &z, n->data.sym, f /* ie no
result project */, ek);
if (!r) {
/* reset error */
sql->session->status = 0;
sql->errstr[0] = 0;
- r = rel_value_exp(query, &left, n->data.sym,
sql_where /* ie no result project */, ek);
+ r = rel_value_exp(query, &left, n->data.sym, f
/* ie no result project */, ek);
if (r)
l_used = is_join(left->op);
}
@@ -2676,7 +2682,7 @@ rel_in_exp(sql_query *query, sql_rel *re
sql->errstr[0] = 0;
query_push_outer(query, left);
- r = rel_value_exp(query, &z, n->data.sym,
sql_where /* ie no result project */, ek);
+ r = rel_value_exp(query, &z, n->data.sym, f /*
ie no result project */, ek);
query_pop_outer(query);
if (!r)
return NULL;
@@ -3799,41 +3805,6 @@ rel_intermediates_add_exp(mvc *sql, sql_
}
}
-static sql_rel *
-rel_bind_groupby(sql_query *query, sql_rel **rel)
-{
- mvc *sql = query->sql;
- sql_rel *groupby = *rel, *l;
-
- if (!groupby)
- return NULL;
- if (!groupby->l) {
- if (groupby->op != op_groupby)
- *rel = groupby = rel_project2groupby(sql, groupby);
- return groupby;
- }
- l = groupby->l;
- if (groupby && groupby->l && !is_processed(groupby) &&
!is_groupby(groupby->op) && is_groupby(l->op))
- groupby = groupby->l;
- if (groupby->op != op_groupby) { /* implicit groupby */
- sql_rel *np = rel_project2groupby(sql, groupby);
-
- if (*rel == groupby) {
- *rel = np;
- } else {
- sql_rel *l = *rel;
- while(l->l && l->l != groupby) {
- l = l->l;
- }
- if (l->l && l->l == groupby)
- l->l = np;
- }
- }
- if (!*rel)
- return NULL;
- return groupby;
-}
-
static sql_exp *
_rel_aggr(sql_query *query, sql_rel **rel, int distinct, sql_schema *s, char
*aname, dnode *args, int f)
{
@@ -3841,24 +3812,25 @@ static sql_exp *
exp_kind ek = {type_value, card_column, FALSE};
sql_subaggr *a = NULL;
int no_nil = 0, group = 0, freevar = 1;
- sql_rel *groupby = *rel, *gr = NULL;//, *sel = NULL, *og = NULL, *r =
(groupby)?groupby->l:NULL;
+ sql_rel *groupby = *rel, *sel = NULL, *gr, *og = NULL;
list *exps = NULL;
-#if 0
+ (void)sel;
+
/* find having select */
if (groupby && groupby->l && !is_processed(groupby) &&
is_sql_having(f)) {
- sql_rel *gl = groupby->l;
+ sql_rel *gl = NULL;
og = groupby;
- while(groupby->l && !is_processed(groupby)) {
+ while(groupby->l && !is_processed(groupby) &&
!is_base(groupby->op)) {
gl = groupby->l;
if (is_select(gl->op))
break;
groupby = gl;
}
- if (gl && is_select(gl->op)) {
+ if (groupby && is_select(groupby->op) &&
!is_processed(groupby)) {
group = 1;
- sel = groupby = gl;
+ sel = groupby;
/* At the end we switch back to the old projection
relation og.
* During the partitioning and ordering we add the
expressions to the intermediate relations. */
}
@@ -3867,12 +3839,6 @@ static sql_exp *
if (sel && sel->l)
groupby = sel->l;
-
- if (groupby && groupby->op == op_project && groupby->l)
- r = groupby->l;
-
- if (r && r->op == op_groupby)
- groupby = r;
}
/* find groupby */
@@ -3880,7 +3846,7 @@ static sql_exp *
sql_rel *gl = groupby->l;
og = groupby;
- while(groupby->l && !is_processed(groupby)) {
+ while(groupby->l && !is_processed(groupby) &&
!is_base(groupby->op)) {
gl = groupby->l;
if (gl->op == op_groupby)
break;
@@ -3903,7 +3869,7 @@ static sql_exp *
if (uaname)
GDKfree(uaname);
return e;
- } else if(is_sql_groupby(f) || (is_sql_partitionby(f) && !r && r->op !=
op_groupby)) {
+ } else if(is_sql_groupby(f) || (is_sql_partitionby(f) && groupby->op !=
op_groupby)) {
const char *clause = is_sql_groupby(f) ? "GROUP BY":"PARTITION
BY";
char *uaname = GDKmalloc(strlen(aname) + 1);
sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate
function '%s' not allowed in %s clause",
@@ -3913,18 +3879,18 @@ static sql_exp *
return e;
}
- if (!query_has_outer(query) && groupby->op != op_groupby) {
/* implicit groupby */
- sql_rel *ng = rel_project2groupby(sql, groupby);
+ if (groupby->op != op_groupby) { /* implicit groupby */
+ sql_rel *np = rel_project2groupby(sql, groupby);
if (*rel == groupby) {
- *rel = ng;
+ *rel = np;
} else {
sql_rel *l = *rel;
while(l->l && l->l != groupby) {
l = l->l;
}
if (l->l && l->l == groupby)
- l->l = ng;
+ l->l = np;
}
}
if (!*rel)
@@ -3938,20 +3904,9 @@ static sql_exp *
GDKfree(uaname);
return e;
}
-#endif
- if (!(groupby = rel_bind_groupby(query, rel))) {
- char *uaname = GDKmalloc(strlen(aname) + 1);
- sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s: missing
group by",
- uaname ? toUpperCopy(uaname,
aname) : aname);
- if (uaname)
- GDKfree(uaname);
- return e;
- }
- gr = groupby;
if (!args->data.sym) { /* count(*) case */
sql_exp *e;
- sql_rel *p = groupby;
if (strcmp(aname, "count") != 0) {
char *uaname = GDKmalloc(strlen(aname) + 1);
@@ -3961,34 +3916,48 @@ static sql_exp *
GDKfree(uaname);
return e;
}
-
a = sql_bind_aggr(sql->sa, s, aname, NULL);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list