Changeset: fe5f0bea4b9b for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=fe5f0bea4b9b
Modified Files:
        sql/server/rel_select.c
        sql/server/sql_parser.y
Branch: Feb2013
Log Message:

fix full qualified names with aggregation
select sys.median() ... now works correctly.


diffs (truncated from 314 to 300 lines):

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
@@ -3232,7 +3232,7 @@ rel_unop_(mvc *sql, sql_exp *e, sql_sche
        return NULL;
 }
 
-static sql_exp * _rel_aggr(mvc *sql, sql_rel **rel, int distinct, char 
*aggrstr, dnode *arguments, int f);
+static sql_exp * _rel_aggr(mvc *sql, sql_rel **rel, int distinct, sql_schema 
*s, char *aname, dnode *arguments, int f);
 
 static sql_exp *
 rel_unop(mvc *sql, sql_rel **rel, symbol *se, int fs, exp_kind ek)
@@ -3258,7 +3258,7 @@ rel_unop(mvc *sql, sql_rel **rel, symbol
        if (!f)
                f = sql_bind_func(sql->sa, s, fname, t, NULL, F_AGGR);
        if (f && IS_AGGR(f->func))
-               return _rel_aggr(sql, rel, 0, fname, l->next, fs);
+               return _rel_aggr(sql, rel, 0, s, fname, l->next, fs);
        return rel_unop_(sql, e, s, fname, ek.card);
 }
 
@@ -3558,7 +3558,7 @@ rel_nop(mvc *sql, sql_rel **rel, symbol 
 }
 
 static sql_exp *
-_rel_aggr(mvc *sql, sql_rel **rel, int distinct, char *aggrstr, dnode *args, 
int f)
+_rel_aggr(mvc *sql, sql_rel **rel, int distinct, sql_schema *s, char *aname, 
dnode *args, int f)
 {
        exp_kind ek = {type_value, card_column, FALSE};
        sql_subaggr *a = NULL;
@@ -3567,10 +3567,10 @@ static sql_exp *
        list *exps = NULL;
 
        if (!groupby) {
-               char *uaggrstr = malloc(strlen(aggrstr) + 1);
+               char *uaname = malloc(strlen(aname) + 1);
                sql_exp *e = sql_error(sql, 02, "%s: missing group by",
-                               toUpperCopy(uaggrstr, aggrstr));
-               free(uaggrstr);
+                               toUpperCopy(uaname, aname));
+               free(uaname);
                return e;
        }
 
@@ -3597,24 +3597,24 @@ static sql_exp *
        }
 
        if (f == sql_where) {
-               char *uaggrstr = malloc(strlen(aggrstr) + 1);
+               char *uaname = malloc(strlen(aname) + 1);
                sql_exp *e = sql_error(sql, 02, "%s: not allowed in WHERE 
clause",
-                               toUpperCopy(uaggrstr, aggrstr));
-               free(uaggrstr);
+                               toUpperCopy(uaname, aname));
+               free(uaname);
                return e;
        }
        
        if (!args->data.sym) {  /* count(*) case */
                sql_exp *e;
 
-               if (strcmp(aggrstr, "count") != 0) {
-                       char *uaggrstr = malloc(strlen(aggrstr) + 1);
+               if (strcmp(aname, "count") != 0) {
+                       char *uaname = malloc(strlen(aname) + 1);
                        sql_exp *e = sql_error(sql, 02, "%s: unable to perform 
'%s(*)'",
-                                       toUpperCopy(uaggrstr, aggrstr), 
aggrstr);
-                       free(uaggrstr);
+                                       toUpperCopy(uaname, aname), aname);
+                       free(uaname);
                        return e;
                }
-               a = sql_bind_aggr(sql->sa, sql->session->schema, aggrstr, NULL);
+               a = sql_bind_aggr(sql->sa, s, aname, NULL);
                /* add aggr expression to the groupby, and return a
                        column expression */
 
@@ -3660,9 +3660,9 @@ static sql_exp *
        }
        groupby->l = gr;
 
-       a = sql_bind_aggr_(sql->sa, sql->session->schema, aggrstr, 
exp_types(sql->sa, exps));
+       a = sql_bind_aggr_(sql->sa, s, aname, exp_types(sql->sa, exps));
        if (!a) { /* find aggr + convert */
-               a = sql_find_aggr(sql->sa, sql->session->schema, aggrstr);
+               a = sql_find_aggr(sql->sa, s, aname);
                if (a) {
                        node *n, *op = a->aggr->ops->h;
                        list *nexps = sa_list(sql->sa);
@@ -3690,7 +3690,7 @@ static sql_exp *
        } else {
                sql_exp *e;
                char *type = "unknown";
-               char *uaggrstr = malloc(strlen(aggrstr) + 1);
+               char *uaname = malloc(strlen(aname) + 1);
 
                if (exps->h) {
                        sql_exp *e = exps->h->data;
@@ -3698,9 +3698,9 @@ static sql_exp *
                }
 
                e = sql_error(sql, 02, "%s: no such operator '%s(%s)'",
-                               toUpperCopy(uaggrstr, aggrstr), aggrstr, type);
-
-               free(uaggrstr);
+                               toUpperCopy(uaname, aname), aname, type);
+
+               free(uaname);
                return e;
        }
 }
@@ -3710,10 +3710,14 @@ rel_aggr(mvc *sql, sql_rel **rel, symbol
 {
        dlist *l = se->data.lval;
        int distinct = l->h->next->data.i_val;
-       char *aggrstr = l->h->data.sval;
+       char *aname = qname_fname(l->h->data.lval);
+       char *sname = qname_schema(l->h->data.lval);
+       sql_schema *s = sql->session->schema;
 
        assert(l->h->next->type == type_int);
-       return _rel_aggr( sql, rel, distinct, aggrstr, l->h->next->next, f);
+       if (sname)
+               s = mvc_bind_schema(sql, sname);
+       return _rel_aggr( sql, rel, distinct, s, aname, l->h->next->next, f);
 }
 
 static sql_exp *
@@ -4361,24 +4365,31 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
        dlist *l = se->data.lval;
        symbol *window_function = l->h->data.sym;
        dlist *window_specification = l->h->next->data.lval;
-       char *aggrstr = NULL;
+       char *aname = NULL;
+       char *sname = NULL;
        sql_subfunc *wf = NULL;
        sql_exp *e = NULL;
        sql_rel *r = *rel;
        list *gbe = NULL, *obe = NULL;
        sql_subtype *idtype = sql_bind_localtype("oid");
+       sql_schema *s = sql->session->schema;
        
        if (window_function->token == SQL_RANK) {
-               aggrstr = window_function->data.sval;
+               aname = qname_fname(window_function->data.lval);
+               sname = qname_schema(window_function->data.lval);
        } else { /* window aggr function */
-               aggrstr = window_function->data.lval->h->data.sval;
-       }
+               dnode *n = window_function->data.lval->h;
+               aname = qname_fname(n->data.lval);
+               sname = qname_schema(n->data.lval);
+       }
+       if (sname)
+               s = mvc_bind_schema(sql, sname);
 
        if (f == sql_where) {
-               char *uaggrstr = malloc(strlen(aggrstr) + 1);
+               char *uaname = malloc(strlen(aname) + 1);
                e = sql_error(sql, 02, "%s: not allowed in WHERE clause",
-                               toUpperCopy(uaggrstr, aggrstr));
-               free(uaggrstr);
+                               toUpperCopy(uaname, aname));
+               free(uaname);
                return e;
        }
 
@@ -4406,9 +4417,9 @@ rel_rankop(mvc *sql, sql_rel **rel, symb
                if (!obe)
                        return NULL;
        }
-       wf = sql_bind_func(sql->sa, sql->session->schema, aggrstr, idtype, 
NULL, F_FUNC);
+       wf = sql_bind_func(sql->sa, s, aname, idtype, NULL, F_FUNC);
        if (!wf)
-               return sql_error(sql, 02, "SELECT: function '%s' not found", 
aggrstr );
+               return sql_error(sql, 02, "SELECT: function '%s' not found", 
aname );
        /* now we need the gbe and obe lists */
        e = exp_op(sql->sa, gbe, wf);
        /* make sure the expression has the proper cardinality */
@@ -4991,9 +5002,22 @@ rel_query(mvc *sql, sql_rel *rel, symbol
 
                for (n = fl->h; n ; n = n->next) {
                        fnd = table_ref(sql, NULL, n->data.sym);
-                       if (!fnd && rel) {
+                       if (!fnd && rel && sql->session->status != 
-ERR_AMBIGUOUS) {
+                               /* reset error */
+                               sql->session->status = 0;
+                               sql->errstr[0] = 0;
                                if (used)
                                        rel = rel_dup(rel);
+                               if (!used) {
+                                       sql_rel *o = rel;
+
+                                       /* remove the outer (running) project */
+                                       if (!is_processed(o) && 
is_project(o->op))
+                                               o = rel->l;
+                                       outer = rel;
+                                       /* create dummy single row project */
+                                       rel = rel_project(sql->sa, NULL, 
applyexps = rel_projections(sql, o, NULL, 1, 1)); 
+                               }
                                fnd = table_ref(sql, rel, n->data.sym);
                                used = 1;
                        }
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -314,6 +314,9 @@ int yydebug=1;
        row_commalist
        qname
        qfunc
+       qrank
+       qaggr
+       qaggr2
        routine_name
        sort_specification_list
        opt_schema_element_list
@@ -3511,7 +3514,7 @@ window_function:
   ;
 
 window_function_type:
-       RANK '(' ')'    { $$ = _symbol_create( SQL_RANK, $1 ); }
+       qrank '(' ')'   { $$ = _symbol_create_list( SQL_RANK, $1 ); }
   |    aggr_ref
   ;
 
@@ -3782,50 +3785,59 @@ atom:
        }
  ;
 
+qrank:
+       RANK            { $$ = append_string(L(), $1); }
+ |      ident '.' RANK { $$ = append_string(
+                         append_string(L(), $1), $3);}
+ ;
+
+qaggr:
+       AGGR            { $$ = append_string(L(), $1); }
+ |      ident '.' AGGR { $$ = append_string(
+                         append_string(L(), $1), $3);}
+ ;
+
+qaggr2:
+       AGGR2           { $$ = append_string(L(), $1); }
+ |      ident '.' AGGR2        { $$ = append_string(
+                         append_string(L(), $1), $3);}
+ ;
 
 /* change to set function */
 aggr_ref:
-    AGGR '(' '*' ')'
+    qaggr '(' '*' ')'
                { dlist *l = L();
-                 append_string(l, $1);
+                 append_list(l, $1);
                  append_int(l, FALSE);
                  append_symbol(l, NULL);
                  $$ = _symbol_create_list( SQL_AGGR, l ); }
- |  AGGR '(' ident '.' '*' ')'
+ |  qaggr '(' ident '.' '*' ')'
                { dlist *l = L();
-                 append_string(l, $1);
+                 append_list(l, $1);
                  append_int(l, FALSE);
                  append_symbol(l, NULL);
                  $$ = _symbol_create_list( SQL_AGGR, l ); }
-/*
- |  AGGR '(' DISTINCT column_ref ')'
+ |  qaggr '(' DISTINCT case_scalar_exp ')'
                { dlist *l = L();
-                 append_string(l, $1);
-                 append_int(l, TRUE);
-                 append_symbol(l, _symbol_create_list(SQL_COLUMN, $4));
-                 $$ = _symbol_create_list( SQL_AGGR, l ); }
-*/
- |  AGGR '(' DISTINCT case_scalar_exp ')'
-               { dlist *l = L();
-                 append_string(l, $1);
+                 append_list(l, $1);
                  append_int(l, TRUE);
                  append_symbol(l, $4);
                  $$ = _symbol_create_list( SQL_AGGR, l ); }
- |  AGGR '(' ALL case_scalar_exp ')'
+ |  qaggr '(' ALL case_scalar_exp ')'
                { dlist *l = L();
-                 append_string(l, $1);
+                 append_list(l, $1);
                  append_int(l, FALSE);
                  append_symbol(l, $4);
                  $$ = _symbol_create_list( SQL_AGGR, l ); }
- |  AGGR '(' case_scalar_exp ')'
+ |  qaggr '(' case_scalar_exp ')'
                { dlist *l = L();
-                 append_string(l, $1);
+                 append_list(l, $1);
                  append_int(l, FALSE);
                  append_symbol(l, $3);
                  $$ = _symbol_create_list( SQL_AGGR, l ); }
- |  AGGR2 '(' case_scalar_exp ',' case_scalar_exp ')'
+ |  qaggr2 '(' case_scalar_exp ',' case_scalar_exp ')'
                { dlist *l = L();
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to