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
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list