Changeset: b7455c736e0b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b7455c736e0b
Modified Files:
        sql/server/rel_rel.c
        sql/server/rel_rel.h
        sql/server/rel_select.c
        sql/test/miscellaneous/Tests/groupby_expressions.sql
        sql/test/miscellaneous/Tests/groupby_expressions.stable.err
Branch: groupby-expressions
Log Message:

Using a bitmask for distinct SQL clauses. Via this way, we can identify easily 
where in the query the compiler is handling and throw better error messages.


diffs (truncated from 489 to 300 lines):

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
@@ -261,7 +261,7 @@ rel_bind_column( mvc *sql, sql_rel *rel,
 {
        sql_rel *p = NULL;
 
-       if (f == sql_sel && rel && is_project(rel->op) && !is_processed(rel))
+       if (is_sql_sel(f) && rel && is_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
@@ -12,11 +12,19 @@
 #include "sql_relation.h"
 #include "sql_mvc.h"
 
-#define sql_from       0
-#define sql_where      1
-#define sql_sel        2       
-#define sql_having     3
-#define sql_orderby    4       
+#define sql_from     1
+#define sql_where    2
+#define sql_sel      4
+#define sql_having   8
+#define sql_orderby 16
+#define sql_groupby 32 //ORed
+
+#define is_sql_from(X)    ((X & sql_from) == sql_from)
+#define is_sql_where(X)   ((X & sql_where) == sql_where)
+#define is_sql_sel(X)     ((X & sql_sel) == sql_sel)
+#define is_sql_having(X)  ((X & sql_having) == sql_having)
+#define is_sql_orderby(X) ((X & sql_orderby) == sql_orderby)
+#define is_sql_groupby(X) ((X & sql_groupby) == sql_groupby)
 
 #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
@@ -1098,7 +1098,7 @@ rel_column_ref(mvc *sql, sql_rel **rel, 
                        return rel_var_ref(sql, name, 0);
                }
                if (!exp && !var) {
-                       if (rel && *rel && (*rel)->card <= CARD_AGGR && f == 
sql_sel) {
+                       if (rel && *rel && (*rel)->card <= CARD_AGGR && 
is_sql_sel(f)) {
                                sql_rel *gb = *rel;
 
                                while(gb->l && !is_groupby(gb->op))
@@ -1106,7 +1106,7 @@ rel_column_ref(mvc *sql, sql_rel **rel, 
                                if (gb && gb->l && rel_bind_column(sql, gb->l, 
name, f)) 
                                        return sql_error(sql, 02, 
SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results 
without an aggregate function", name);
                        }
-                       if (f == sql_having)
+                       if (is_sql_having(f))
                                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);
                }
@@ -1140,7 +1140,7 @@ rel_column_ref(mvc *sql, sql_rel **rel, 
                                if (gb && is_groupby(gb->op) && gb->l && 
rel_bind_column2(sql, gb->l, tname, cname, 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);
                        }
-                       if (f == sql_having)
+                       if (is_sql_having(f))
                                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);
                }
@@ -1779,14 +1779,14 @@ rel_compare(mvc *sql, sql_rel *rel, symb
                        /* reset error */
                        sql->session->status = 0;
                        sql->errstr[0] = 0;
-                       r = rel_subquery(sql, rel, ro, ek, f == 
sql_sel?APPLY_LOJ:APPLY_JOIN);
+                       r = rel_subquery(sql, rel, ro, ek, 
is_sql_sel(f)?APPLY_LOJ:APPLY_JOIN);
 
                        /* get inner queries result value, ie
                           get last expression of r */
                        if (r) {
                                rs = rel_lastexp(sql, r);
 
-                               if (f == sql_sel && r->card > CARD_ATOM && 
quantifier != 1) {
+                               if (is_sql_sel(f) && r->card > CARD_ATOM && 
quantifier != 1) {
                                        sql_subaggr *zero_or_one = 
sql_bind_aggr(sql->sa, sql->session->schema, compare_aggr_op(compare_op, 
quantifier), exp_subtype(rs));
                                        rs = exp_aggr1(sql->sa, rs, 
zero_or_one, 0, 0, CARD_ATOM, 0);
 
@@ -2013,7 +2013,7 @@ rel_logical_value_exp(mvc *sql, sql_rel 
                                sql->session->status = 0;
                                sql->errstr[0] = 0;
                                if (!r)
-                                       r = rel_subquery(sql, *rel, ro, ek, f 
== sql_sel?APPLY_LOJ:APPLY_JOIN);
+                                       r = rel_subquery(sql, *rel, ro, ek, 
is_sql_sel(f)?APPLY_LOJ:APPLY_JOIN);
 
                                /* get inner queries result value, ie
                                   get last expression of r */
@@ -2021,7 +2021,7 @@ rel_logical_value_exp(mvc *sql, sql_rel 
                                        rs = rel_lastexp(sql, r);
                                        *rel = r;
                                        e = exp_compare(sql->sa, ls, rs, 
compare_str2type(compare_op));
-                                       if (f != sql_sel)
+                                       if (!is_sql_sel(f))
                                                return e;
                        
                                        /* For selection we need to convert 
back into Boolean */
@@ -2036,7 +2036,7 @@ rel_logical_value_exp(mvc *sql, sql_rel 
                                if (!l) {
                                        l = *rel = rel_project(sql->sa, NULL, 
new_exp_list(sql->sa));
                                        ls = rel_project_add_exp(sql, l, ls);
-                               } else if (f == sql_sel) { /* allways add left 
side in case of selections phase */
+                               } else if (is_sql_sel(f)) { /* allways add left 
side in case of selections phase */
                                        if (!l->processed) { /* add all 
expressions to the project */
                                                l->exps = list_merge(l->exps, 
rel_projections(sql, l->l, NULL, 1, 1), (fdup)NULL);
                                                l->exps = 
list_distinct(l->exps, (fcmp)exp_equal, (fdup)NULL);
@@ -2071,7 +2071,7 @@ rel_logical_value_exp(mvc *sql, sql_rel 
                int needproj = 0, vals_only = 1, is_new = 0;
                list *vals = NULL, *pexps = NULL;
 
-               if (outer && f == sql_sel && is_project(outer->op) && 
!is_processed(outer) && !list_empty(outer->exps)) {
+               if (outer && is_sql_sel(f) && is_project(outer->op) && 
!is_processed(outer) && !list_empty(outer->exps)) {
                        needproj = 1;
                        pexps = outer->exps;
                        if (!outer->l) { /* list of constants */
@@ -2092,7 +2092,7 @@ rel_logical_value_exp(mvc *sql, sql_rel 
                        }
                }
 
-               if (!left || (!left->l && f == sql_sel && 
list_empty(left->exps))) {
+               if (!left || (!left->l && is_sql_sel(f) && 
list_empty(left->exps))) {
                        needproj = (left != NULL);
                        left = rel_project_exp(sql->sa, l);
                        is_new = 1;
@@ -2140,7 +2140,7 @@ rel_logical_value_exp(mvc *sql, sql_rel 
                                                                return NULL;
                                                }
                                        }
-                                       if (r && z && is_project(z->op) && z->l 
&& f == sql_sel) {
+                                       if (r && z && is_project(z->op) && z->l 
&& is_sql_sel(f)) {
                                                sql_rel *gp = z->l;
                                                r = rel_project_add_exp(sql, z, 
r);
                                                reset_processed(gp);
@@ -2220,7 +2220,7 @@ rel_logical_value_exp(mvc *sql, sql_rel 
                                reset_processed(left);
                        } else
                                *rel = left;
-                       if (f == sql_sel) {
+                       if (is_sql_sel(f)) {
                                e = rel_unop_(sql, r, NULL, "isnull", 
card_value);
                                if (sc->token == SQL_IN)
                                        e = rel_unop_(sql, e, NULL, "not", 
card_value);
@@ -3144,12 +3144,12 @@ rel_unop(mvc *sql, sql_rel **rel, symbol
                e = rel_value_exp(sql, rel, l->next->data.sym, fs, iek);
        if (!e) {
                if (!f && *rel && (*rel)->card == CARD_AGGR) {
-                       if (fs == sql_having)
+                       if (is_sql_having(fs) || is_sql_orderby(fs))
                                return NULL;
                        /* reset error */
                        sql->session->status = 0;
                        sql->errstr[0] = '\0';
-                       return sql_error(sql, 02, "SELECT: no such aggregate 
'%s'", fname);
+                       return sql_error(sql, 02, SQLSTATE(42000) "SELECT: no 
such aggregate '%s'", fname);
                }
                return NULL;
        }
@@ -3447,12 +3447,12 @@ rel_binop(mvc *sql, sql_rel **rel, symbo
        if (!l || !r)
                sf = find_func(sql, s, fname, 2, F_AGGR, NULL);
        if (!sf && (!l || !r) && *rel && (*rel)->card == CARD_AGGR) {
-               if (f == sql_having)
+               if (is_sql_having(f) || is_sql_orderby(f))
                        return NULL;
                /* reset error */
                sql->session->status = 0;
                sql->errstr[0] = '\0';
-               return sql_error(sql, 02, "SELECT: no such aggregate '%s'", 
fname);
+               return sql_error(sql, 02, SQLSTATE(42000) "SELECT: no such 
aggregate '%s'", fname);
        }
        if (!l && !r && sf) { /* possibly we cannot resolve the argument as the 
function maybe an aggregate */
                /* reset error */
@@ -3547,12 +3547,12 @@ rel_nop(mvc *sql, sql_rel **rel, symbol 
        /* first try aggregate */
        f = find_func(sql, s, fname, nr_args, F_AGGR, NULL);
        if (!f && err && *rel && (*rel)->card == CARD_AGGR) {
-               if (fs == sql_having)
+               if (is_sql_having(fs) || is_sql_orderby(fs))
                        return NULL;
                /* reset error */
                sql->session->status = 0;
                sql->errstr[0] = '\0';
-               return sql_error(sql, 02, "SELECT: no such aggregate '%s'", 
fname);
+               return sql_error(sql, 02, SQLSTATE(42000) "SELECT: no such 
aggregate '%s'", fname);
        }
        if (f) {
                if (err) {
@@ -3586,22 +3586,22 @@ static sql_exp *
                return e;
        }
 
-       if (f == sql_having && is_select(groupby->op))
+       if (is_sql_having(f) && is_select(groupby->op))
                groupby = groupby->l;
 
        if (groupby->l && groupby->op == op_project) {
                sql_rel *r = groupby->l;        
 
-               if (!is_processed(r) && f == sql_sel && r->op == op_project) {
+               if (!is_processed(r) && is_sql_sel(f) && r->op == op_project) {
                        project = r;
                        r = r->l;
                }
 
-               if (f == sql_having)
+               if (is_sql_having(f))
                        project = groupby;
-               if (f == sql_having && r->op == op_select && r->l) 
+               if (is_sql_having(f) && r->op == op_select && r->l)
                        r = r->l;
-               if (f == sql_having && r->op == op_project && r->l) {
+               if (is_sql_having(f) && r->op == op_project && r->l) {
                        iproject = r;
                        r = r->l;
                }
@@ -3615,7 +3615,7 @@ static sql_exp *
        if (!*rel)
                return NULL;
 
-       if (f == sql_where) {
+       if (is_sql_where(f)) {
                char *uaname = GDKmalloc(strlen(aname) + 1);
                sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s: not 
allowed in WHERE clause",
                                       uaname ? toUpperCopy(uaname, aname) : 
aname);
@@ -3637,7 +3637,7 @@ static sql_exp *
                }
                a = sql_bind_aggr(sql->sa, s, aname, NULL);
                e = exp_aggr(sql->sa, NULL, a, distinct, 0, groupby->card, 0);
-               if (*rel == groupby && f == sql_sel) /* selection */
+               if (*rel == groupby && is_sql_sel(f)) /* selection */
                        return e;
                if (!project)
                        return rel_groupby_add_aggr(sql, groupby, e);
@@ -3778,7 +3778,7 @@ static sql_exp *
        if (a && execute_priv(sql,a->aggr)) {
                sql_exp *e = exp_aggr(sql->sa, exps, a, distinct, no_nil, 
groupby->card, have_nil(exps));
 
-               if (*rel != groupby || f != sql_sel) { /* selection */
+               if (*rel != groupby || !is_sql_sel(f)) { /* selection */
                        e = rel_groupby_add_aggr(sql, groupby, e);
                        if (!e || !project)
                                return e;
@@ -3787,7 +3787,7 @@ static sql_exp *
                                e = exp_column(sql->sa, exp_relname(e), 
exp_name(e), exp_subtype(e), exp_card(e), has_nil(e), is_intern(e));
                        }
                        e = rel_project_add_exp(sql, project, e);
-                       if (iproject || f != sql_sel)
+                       if (iproject || !is_sql_sel(f))
                                e = exp_column(sql->sa, exp_relname(e), 
exp_name(e), exp_subtype(e), exp_card(e), has_nil(e), is_intern(e));
                }
                return e;
@@ -4176,13 +4176,13 @@ rel_order_by_simple_column_exp(mvc *sql,
        set_processed(r);
        if (dlist_length(l) == 1) {
                char *name = l->h->data.sval;
-               e = rel_bind_column(sql, r, name, sql_sel);
+               e = rel_bind_column(sql, r, name, sql_sel | sql_orderby);
        }
        if (dlist_length(l) == 2) {
                char *tname = l->h->data.sval;
                char *name = l->h->next->data.sval;
 
-               e = rel_bind_column2(sql, r, tname, name, sql_sel);
+               e = rel_bind_column2(sql, r, tname, name, sql_sel | 
sql_orderby);
        }
        if (!e) {
                /* now we need to rewrite r
@@ -4192,7 +4192,7 @@ rel_order_by_simple_column_exp(mvc *sql,
        }
        if (e)
                return e;
-       return sql_error(sql, 02, SQLSTATE(42000) "ORDER BY: absolute column 
names not supported");
+       return NULL;
 }
 
 static list *
@@ -4342,7 +4342,7 @@ rel_order_by_column_exp(mvc *sql, sql_re
        sql_exp *e = NULL;
        exp_kind ek = {type_value, card_column, FALSE};
 
-       if (f == sql_orderby) {
+       if (is_sql_orderby(f)) {
                assert(is_project(r->op));
                r = r->l;
        }
@@ -4357,7 +4357,7 @@ rel_order_by_column_exp(mvc *sql, sql_re
        if (!e) {
                sql_rel *or = r;
 
-               e = rel_value_exp(sql, &r, column_r, sql_sel, ek);
+               e = rel_value_exp(sql, &r, column_r, sql_sel | sql_orderby, ek);
                if (r && or != r)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to