Changeset: 34ab77de43c5 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=34ab77de43c5
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_scenario.c
        sql/server/rel_schema.c
        sql/server/rel_select.c
        sql/server/rel_updates.c
        sql/server/sql_mvc.c
        sql/server/sql_mvc.h
        sql/server/sql_parser.y
        sql/server/sql_qc.c
        sql/server/sql_qc.h
        sql/server/sql_semantic.c
        sql/server/sql_symbol.c
        sql/server/sql_symbol.h
        sql/server/sql_tokens.h
        sql/test/miscellaneous/Tests/groupby_expressions.sql
        sql/test/miscellaneous/Tests/groupby_expressions.stable.err
        sql/test/miscellaneous/Tests/groupby_expressions.stable.out
Branch: groupby-expressions
Log Message:

Introducing SQL_IDENT token to distinguish arguments from column references. 
This allows a more fined grained symbol comparison.

Also moved symbol_cmp code to sql_mvc to eliminate a circular dependency.


diffs (truncated from 764 to 300 lines):

diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -1163,7 +1163,7 @@ rel_parse_value(backend *be, char *query
        /* get out the single value as we don't want an enclosing projection! */
        if (m->sym->token == SQL_SELECT) {
                SelectNode *sn = (SelectNode *)m->sym;
-               if (sn->selection->h->data.sym->token == SQL_COLUMN) {
+               if (sn->selection->h->data.sym->token == SQL_COLUMN || 
sn->selection->h->data.sym->token == SQL_IDENT) {
                        int is_last = 0;
                        sql_rel *rel = NULL;
                        sql_exp *e = rel_value_exp2(m, &rel, 
sn->selection->h->data.sym->data.lval->h->data.sym, sql_sel, ek, &is_last);
diff --git a/sql/backends/monet5/sql_scenario.c 
b/sql/backends/monet5/sql_scenario.c
--- a/sql/backends/monet5/sql_scenario.c
+++ b/sql/backends/monet5/sql_scenario.c
@@ -1190,7 +1190,7 @@ SQLparser(Client c)
                        goto finalize;
                }
                scanner_query_processed(&(m->scanner));
-       } else if (caching(m) && cachable(m, NULL) && m->emode != m_prepare && 
(be->q = qc_match(m->qc, m->sym, m->args, m->argc, m->scanner.key ^ 
m->session->schema->base.id)) != NULL) {
+       } else if (caching(m) && cachable(m, NULL) && m->emode != m_prepare && 
(be->q = qc_match(m->qc, m, m->sym, m->args, m->argc, m->scanner.key ^ 
m->session->schema->base.id)) != NULL) {
                /* query template was found in the query cache */
                scanner_query_processed(&(m->scanner));
                m->no_mitosis = be->q->no_mitosis;
diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c
--- a/sql/server/rel_schema.c
+++ b/sql/server/rel_schema.c
@@ -430,7 +430,7 @@ column_option(
                symbol *sym = s->data.sym;
                char *err = NULL, *r;
 
-               if (sym->token == SQL_COLUMN) {
+               if (sym->token == SQL_COLUMN || sym->token == SQL_IDENT) {
                        sql_exp *e = rel_logical_value_exp(sql, NULL, sym, 
sql_sel);
                        
                        if (e && is_atom(e->type)) {
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
@@ -1051,7 +1051,7 @@ rel_column_ref(mvc *sql, sql_rel **rel, 
        sql_exp *exp = NULL;
        dlist *l = NULL;
 
-       assert(column_r->token == SQL_COLUMN && column_r->type == type_list);
+       assert((column_r->token == SQL_COLUMN || column_r->token == SQL_IDENT) 
&& column_r->type == type_list);
        l = column_r->data.lval;
 
        if (dlist_length(l) == 1 && l->h->type == type_int) {
@@ -2375,6 +2375,7 @@ rel_logical_value_exp(mvc *sql, sql_rel 
                        return exp_atom(sql->sa, atom_dup(sql->sa, an->a));
                }
        }
+       case SQL_IDENT:
        case SQL_COLUMN:
                return rel_column_ref(sql, rel, sc, f);
        case SQL_UNION:
@@ -3010,6 +3011,7 @@ rel_logical_exp(mvc *sql, sql_rel *rel, 
                sql_exp *e = exp_atom(sql->sa, atom_dup(sql->sa, an->a));
                return rel_select(sql->sa, rel, e);
        }
+       case SQL_IDENT:
        case SQL_COLUMN: {
                sql_rel *or = rel;
                sql_exp *e = rel_column_ref(sql, &rel, sc, f);
@@ -4063,7 +4065,8 @@ rel_selection_ref(mvc *sql, sql_rel **re
        name = gl->h->data.sval;
        for (n = selection->h; n; n = n->next) {
                /* we only look for columns */
-               if (n->data.sym->token == SQL_COLUMN) {
+               tokens to = n->data.sym->token;
+               if (to == SQL_COLUMN || to == SQL_IDENT) {
                        dlist *l = n->data.sym->data.lval;
                        /* AS name */
                        if (l->h->next->data.sval &&
@@ -4079,12 +4082,12 @@ rel_selection_ref(mvc *sql, sql_rel **re
                                        */
                                        dlist_append_string(sql->sa, l,
                                                sa_strdup(sql->sa, name));
-                                       sym = symbol_create_list(sql->sa, 
SQL_COLUMN, l);
+                                       sym = symbol_create_list(sql->sa, to, 
l);
                                        l = dlist_create(sql->sa);
                                        dlist_append_symbol(sql->sa, l, sym);
                                        /* no alias */
                                        dlist_append_symbol(sql->sa, l, NULL);
-                                       n->data.sym = 
symbol_create_list(sql->sa, SQL_COLUMN, l);
+                                       n->data.sym = 
symbol_create_list(sql->sa, to, l);
                                
                                }
                                return ve;
@@ -4140,7 +4143,7 @@ rel_order_by_simple_column_exp(mvc *sql,
 
        if (!r || !is_project(r->op) || column_r->type == type_int)
                return NULL;
-       assert(column_r->token == SQL_COLUMN && column_r->type == type_list);
+       assert((column_r->token == SQL_COLUMN || column_r->token == SQL_IDENT) 
&& column_r->type == type_list);
 
        r = r->l;
        if (!r)
@@ -4164,7 +4167,7 @@ rel_order_by_simple_column_exp(mvc *sql,
        }
        if (e)
                return e;
-       return NULL;
+       return sql_error(sql, 02, SQLSTATE(42000) "ORDER BY: absolute column 
names not supported");
 }
 
 static list *
@@ -4378,12 +4381,12 @@ rel_order_by(mvc *sql, sql_rel **R, symb
        for (; o; o = o->next) {
                symbol *order = o->data.sym;
 
-               if (order->token == SQL_COLUMN) {
+               if (order->token == SQL_COLUMN || order->token == SQL_IDENT) {
                        symbol *col = order->data.lval->h->data.sym;
                        int direction = order->data.lval->h->next->data.i_val;
                        sql_exp *e = NULL;
 
-                       if (col->token == SQL_COLUMN || col->token == SQL_ATOM) 
{
+                       if (col->token == SQL_COLUMN || col->token == SQL_IDENT 
|| col->token == SQL_ATOM) {
                                int is_last = 0;
                                exp_kind ek = {type_value, card_column, FALSE};
 
@@ -4413,7 +4416,7 @@ rel_order_by(mvc *sql, sql_rel **R, symb
                        assert(order->data.lval->h->next->type == type_int);
                        if (or != rel)
                                return NULL;
-                       if (!e && sql->session->status != -ERR_AMBIGUOUS && 
col->token == SQL_COLUMN) {
+                       if (!e && sql->session->status != -ERR_AMBIGUOUS && 
(col->token == SQL_COLUMN || col->token == SQL_IDENT)) {
                                /* reset error */
                                sql->session->status = 0;
                                sql->errstr[0] = '\0';
@@ -5093,6 +5096,7 @@ rel_value_exp2(mvc *sql, sql_rel **rel, 
                return rel_aggr(sql, rel, se, f);
        case SQL_RANK:
                return rel_rankop(sql, rel, se, f);
+       case SQL_IDENT:
        case SQL_COLUMN:
                return rel_column_ref(sql, rel, se, f );
        case SQL_NAME:
@@ -5328,7 +5332,7 @@ rel_table_exp(mvc *sql, sql_rel **rel, s
 sql_exp *
 rel_column_exp(mvc *sql, sql_rel **rel, symbol *column_e, int f)
 {
-       if (column_e->token == SQL_COLUMN) {
+       if (column_e->token == SQL_COLUMN || column_e->token == SQL_IDENT) {
                return column_exp(sql, rel, column_e, f);
        }
        return NULL;
diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c
--- a/sql/server/rel_updates.c
+++ b/sql/server/rel_updates.c
@@ -1847,7 +1847,7 @@ rel_parse_val(mvc *m, char *query, char 
        /* get out the single value as we don't want an enclosing projection! */
        if (m->sym && m->sym->token == SQL_SELECT) {
                SelectNode *sn = (SelectNode *)m->sym;
-               if (sn->selection->h->data.sym->token == SQL_COLUMN) {
+               if (sn->selection->h->data.sym->token == SQL_COLUMN || 
sn->selection->h->data.sym->token == SQL_IDENT) {
                        int is_last = 0;
                        sql_rel *r = from;
                        symbol* sq = 
sn->selection->h->data.sym->data.lval->h->data.sym;
diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c
--- a/sql/server/sql_mvc.c
+++ b/sql/server/sql_mvc.c
@@ -1648,7 +1648,7 @@ stack_get_groupby_expression(mvc *sql, s
 {
        if(sql->has_groupby_expressions) {
                for (int i = sql->topvars-1; i >= 0; i--) {
-                       if (!sql->vars[i].frame && sql->vars[i].exp && 
sql->vars[i].exp->token == def->token && symbol_cmp(sql->vars[i].exp->sdef, 
def)==0) {
+                       if (!sql->vars[i].frame && sql->vars[i].exp && 
sql->vars[i].exp->token == def->token && symbol_cmp(sql, 
sql->vars[i].exp->sdef, def)==0) {
                                return sql->vars[i].exp->exp;
                        }
                }
@@ -2082,3 +2082,159 @@ mvc_find_subexp(mvc *m, const char *rnam
        }
        return NULL;
 }
+
+static inline int dlist_cmp(mvc *sql, dlist *l1, dlist *l2);
+
+static inline int
+dnode_cmp(mvc *sql, dnode *d1, dnode *d2)
+{
+       if (d1 == d2)
+               return 0;
+
+       if (!d1 || !d2)
+               return -1;
+
+       if (d1->type == d2->type) {
+               switch (d1->type) {
+                       case type_int:
+                               return (d1->data.i_val - d2->data.i_val);
+                       case type_lng: {
+                               lng c = d1->data.l_val - d2->data.l_val;
+                               assert((lng) GDK_int_min <= c && c <= (lng) 
GDK_int_max);
+                               return (int) c;
+                       }
+                       case type_string:
+                               if (d1->data.sval == d2->data.sval)
+                                       return 0;
+                               if (!d1->data.sval || !d2->data.sval)
+                                       return -1;
+                               return strcmp(d1->data.sval, d2->data.sval);
+                       case type_list:
+                               return dlist_cmp(sql, d1->data.lval, 
d2->data.lval);
+                       case type_symbol:
+                               return symbol_cmp(sql, d1->data.sym, 
d2->data.sym);
+                       case type_type:
+                               return subtype_cmp(&d1->data.typeval, 
&d2->data.typeval);
+                       default:
+                               assert(0);
+               }
+       }
+       return -1;
+}
+
+static inline int
+dlist_cmp(mvc *sql, dlist *l1, dlist *l2)
+{
+       int res = 0;
+       dnode *d1, *d2;
+
+       if (l1 == l2)
+               return 0;
+
+       if (!l1 || !l2 || dlist_length(l1) != dlist_length(l2))
+               return -1;
+
+       for (d1 = l1->h, d2 = l2->h; !res && d1; d1 = d1->next, d2 = d2->next) {
+               res = dnode_cmp(sql, d1, d2);
+       }
+       return res;
+}
+
+static inline int
+AtomNodeCmp(AtomNode *a1, AtomNode *a2)
+{
+       if (a1 == a2)
+               return 0;
+       if (!a1 || !a2)
+               return -1;
+       if (a1->a && a2->a)
+               return atom_cmp(a1->a, a2->a);
+       return -1;
+}
+
+static inline int
+SelectNodeCmp(mvc *sql, SelectNode *s1, SelectNode *s2)
+{
+       if (s1 == s2)
+               return 0;
+       if (!s1 || !s2)
+               return -1;
+
+       if (symbol_cmp(sql, s1->limit, s2->limit) == 0 &&
+               symbol_cmp(sql, s1->offset, s2->offset) == 0 &&
+               symbol_cmp(sql, s1->sample, s2->sample) == 0 &&
+               s1->distinct == s2->distinct &&
+               s1->lateral == s2->lateral &&
+               symbol_cmp(sql, s1->name, s2->name) == 0 &&
+               symbol_cmp(sql, s1->orderby, s2->orderby) == 0 &&
+               symbol_cmp(sql, s1->having, s2->having) == 0 &&
+               symbol_cmp(sql, s1->groupby, s2->groupby) == 0 &&
+               symbol_cmp(sql, s1->where, s2->where) == 0 &&
+               symbol_cmp(sql, s1->from, s2->from) == 0 &&
+               symbol_cmp(sql, s1->window, s2->window) == 0 &&
+               dlist_cmp(sql, s1->selection, s2->selection) == 0)
+               return 0;
+       return -1;
+}
+
+static inline int
+_symbol_cmp(mvc *sql, symbol *s1, symbol *s2)
+{
+       if (s1 == s2)
+               return 0;
+       if (!s1 || !s2)
+               return -1;
+       if (s1->token != s2->token || s1->type != s2->type)
+               return -1;
+       switch (s1->type) {
+               case type_int:
+                       return (s1->data.i_val - s2->data.i_val);
+               case type_lng: {
+                       lng c = s1->data.l_val - s2->data.l_val;
+                       assert((lng) GDK_int_min <= c && c <= (lng) 
GDK_int_max);
+                       return (int) c;
+               }
+               case type_string:
+                       if (s1->data.sval == s2->data.sval)
+                               return 0;
+                       if (!s1->data.sval || !s2->data.sval)
+                               return -1;
+                       return strcmp(s1->data.sval, s2->data.sval);
+               case type_list: {
+                       if (s1->token == SQL_IDENT) {
+                               atom *at1, *at2;
+
+                               if (s2->token != SQL_IDENT)
+                                       return -1;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to