Changeset: ce47a38f5294 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ce47a38f5294 Modified Files: sql/include/sql_relation.h sql/server/rel_rel.c sql/server/rel_select.c sql/test/BugTracker-2017/Tests/aggr_udf_with_more_than_2params.Bug-6385.stable.err sql/test/BugTracker-2018/Tests/sqlitelogictest-groupby-coalesce-error-message.Bug-6608.stable.err sql/test/subquery/Tests/subquery4.stable.out Branch: default Log Message:
fixed proper use of nested aggregation reduced complexity in the rel_unop, rel_binop and rel_nop cases, ie first try if we have an aggregation function with the required number of arguments, iff so continue with rel_aggr else continue in the functional route. diffs (truncated from 301 to 300 lines): diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h --- a/sql/include/sql_relation.h +++ b/sql/include/sql_relation.h @@ -267,6 +267,7 @@ typedef struct relation { dependent:1, /* dependent join */ distinct:1, processed:1, /* fully processed or still in the process of building */ + grouped:1, /* groupby processed all the group by exps */ subquery:1; /* is this part a subquery, this is needed for proper name binding */ void *p; /* properties for the optimizer, distribution */ } sql_rel; 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 @@ -900,6 +900,7 @@ rel_groupby(mvc *sql, sql_rel *l, list * rel->exps = aggrs; rel->nrcols = l->nrcols; rel->op = op_groupby; + rel->grouped = 1; return rel; } 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 @@ -2858,40 +2858,16 @@ rel_unop(sql_query *query, sql_rel **rel exp_kind iek = {type_value, card_column, FALSE}; sql_exp *e = NULL; sql_subfunc *sf = NULL; - sql_ftype type = (ek.card == card_loader)?F_LOADER:((ek.card == card_none)?F_PROC:F_FUNC); if (sname && !(s = mvc_bind_schema(sql, sname))) return sql_error(sql, 02, SQLSTATE(3F000) "SELECT: no such schema '%s'", sname); + sf = find_func(sql, s, fname, 1, F_AGGR, NULL); + if (sf) + return rel_aggr(query, rel, se, f); + e = rel_value_exp(query, rel, l->next->next->data.sym, f|sql_farg, iek); if (!e) - sf = find_func(sql, s, fname, 1, F_AGGR, NULL); - - if (!sf && !e && *rel && (*rel)->card == CARD_AGGR) { - 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, SQLSTATE(42000) "SELECT: no such aggregate '%s'", fname); - } - if (!e && sf) { /* possibly we cannot resolve the argument as the function maybe an aggregate */ - /* reset error */ - sql->session->status = 0; - sql->errstr[0] = '\0'; - return rel_aggr(query, rel, se, f); - } - if (type == F_FUNC) { - sf = find_func(sql, s, fname, 1, F_AGGR, NULL); - if (sf) { - if (!e) { /* reset error */ - sql->session->status = 0; - sql->errstr[0] = '\0'; - } - return _rel_aggr(query, rel, l->next->data.i_val, s, fname, l->next->next, f); - } - } - if (!e) return NULL; return rel_unop_(sql, rel ? *rel : NULL, e, s, fname, ek.card); } @@ -3137,42 +3113,17 @@ rel_binop(sql_query *query, sql_rel **re char *sname = qname_schema(dl->data.lval); sql_schema *s = cur_schema(sql); exp_kind iek = {type_value, card_column, FALSE}; - sql_ftype type = (ek.card == card_loader)?F_LOADER:((ek.card == card_none)?F_PROC:F_FUNC); sql_subfunc *sf = NULL; if (sname && !(s = mvc_bind_schema(sql, sname))) return sql_error(sql, 02, SQLSTATE(3F000) "SELECT: no such schema '%s'", sname); + sf = find_func(sql, s, fname, 2, F_AGGR, NULL); + if (sf) + return rel_aggr(query, rel, se, f); + l = rel_value_exp(query, rel, dl->next->next->data.sym, f|sql_farg, iek); r = rel_value_exp(query, rel, dl->next->next->next->data.sym, f|sql_farg, iek); - - if (!l || !r) - sf = find_func(sql, s, fname, 2, F_AGGR, NULL); - if (!sf && (!l || !r) && *rel && (*rel)->card == CARD_AGGR) { - if (mvc_status(sql) || 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, 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 */ - sql->session->status = 0; - sql->errstr[0] = '\0'; - return rel_aggr(query, rel, se, f); - } - if (type == F_FUNC) { - sf = find_func(sql, s, fname, 2, F_AGGR, NULL); - if (sf) { - if (!l || !r) { /* reset error */ - sql->session->status = 0; - sql->errstr[0] = '\0'; - } - return _rel_aggr(query, rel, dl->next->data.i_val, s, fname, dl->next->next, f); - } - } - if (!l || !r) return NULL; return rel_binop_(sql, rel ? *rel : NULL, l, r, s, fname, ek.card); @@ -3204,15 +3155,15 @@ rel_nop_(mvc *sql, sql_rel *rel, sql_exp } static sql_exp * -rel_nop(sql_query *query, sql_rel **rel, symbol *se, int fs, exp_kind ek) +rel_nop(sql_query *query, sql_rel **rel, symbol *se, int f, exp_kind ek) { mvc *sql = query->sql; - int nr_args = 0; dnode *l = se->data.lval->h; + int nr_args = dlist_length(l->next->next->data.lval); dnode *ops = l->next->next->data.lval->h; list *exps = new_exp_list(sql->sa); list *tl = sa_list(sql->sa); - sql_subfunc *f = NULL; + sql_subfunc *sf = NULL; sql_subtype *obj_type = NULL; char *fname = qname_fname(l->data.lval); char *sname = qname_schema(l->data.lval); @@ -3223,8 +3174,12 @@ rel_nop(sql_query *query, sql_rel **rel, if (sname && !(s = mvc_bind_schema(sql, sname))) return sql_error(sql, 02, SQLSTATE(3F000) "SELECT: no such schema '%s'", sname); - for (; ops; ops = ops->next, nr_args++) { - sql_exp *e = rel_value_exp(query, rel, ops->data.sym, fs|sql_farg, iek); + sf = find_func(sql, s, fname, nr_args, F_AGGR, NULL); + if (sf) /* We have to pas the arguments properly, so skip call to rel_aggr */ + return _rel_aggr(query, rel, l->next->data.i_val, s, fname, l->next->next->data.lval->h, f); + + for (nr_args = 0; ops; ops = ops->next, nr_args++) { + sql_exp *e = rel_value_exp(query, rel, ops->data.sym, f|sql_farg, iek); sql_subtype *tpe; if (!e) @@ -3237,25 +3192,6 @@ rel_nop(sql_query *query, sql_rel **rel, append(tl, tpe); } } - - /* first try aggregate */ - f = find_func(sql, s, fname, nr_args, F_AGGR, NULL); - if (!f && err && *rel && (*rel)->card == CARD_AGGR) { - 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, SQLSTATE(42000) "SELECT: no such aggregate '%s'", fname); - } - if (f) { - if (err) { - /* reset error */ - sql->session->status = 0; - sql->errstr[0] = '\0'; - } - return _rel_aggr(query, rel, l->next->data.i_val, s, fname, l->next->next->data.lval->h, fs); - } if (err) return NULL; return _rel_nop(sql, s, fname, tl, rel ? *rel : NULL, exps, obj_type, nr_args, ek); @@ -3352,6 +3288,14 @@ static sql_exp * has_args = true; if (gl && gl != ogl) { + if (groupby->grouped) { + char *uaname = GDKmalloc(strlen(aname) + 1); + sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions cannot be nested", + uaname ? toUpperCopy(uaname, aname) : aname); + if (uaname) + GDKfree(uaname); + return e; + } if (!base) groupby->l = subquery = gl; else @@ -3367,7 +3311,7 @@ static sql_exp * GDKfree(uaname); return e; } - all_aggr &= (exp_card(e) <= CARD_AGGR && !exp_is_atom(e) && !is_func(e->type) && (!groupby || !is_groupby(groupby->op) || !groupby->r || !exps_find_exp(groupby->r, e))); + all_aggr &= (exp_card(e) <= CARD_AGGR && !exp_is_atom(e) && is_aggr(e->type) && !is_func(e->type) && (!groupby || !is_groupby(groupby->op) || !groupby->r || !exps_find_exp(groupby->r, e))); has_freevar |= exp_has_freevar(sql, e); all_freevar &= (is_freevar(e)>0); list_append(exps, e); @@ -3709,7 +3653,7 @@ static sql_exp * type = exp_subtype(e)->type->sqlname; } - e = sql_error(sql, 02, SQLSTATE(42000) "%s: no such operator '%s(%s)'", + e = sql_error(sql, 02, SQLSTATE(42000) "%s: no such aggregate '%s(%s)'", uaname ? toUpperCopy(uaname, aname) : aname, aname, type); if (uaname) @@ -5291,7 +5235,6 @@ rel_where_groupby_nodes(sql_query *query if (rel->op != op_groupby) rel = rel_groupby(sql, rel, NULL); } - return rel; } diff --git a/sql/test/BugTracker-2017/Tests/aggr_udf_with_more_than_2params.Bug-6385.stable.err b/sql/test/BugTracker-2017/Tests/aggr_udf_with_more_than_2params.Bug-6385.stable.err --- a/sql/test/BugTracker-2017/Tests/aggr_udf_with_more_than_2params.Bug-6385.stable.err +++ b/sql/test/BugTracker-2017/Tests/aggr_udf_with_more_than_2params.Bug-6385.stable.err @@ -31,11 +31,11 @@ stderr of test 'aggr_udf_with_more_than_ MAPI = (monetdb) /var/tmp/mtest-31488/.s.monetdb.35710 QUERY = SELECT groupnr, aggr2(value) FROM grouped_ints GROUP BY groupnr; -ERROR = !SELECT: no such aggregate 'aggr2' +ERROR = !SELECT: cannot use non GROUP BY column 'value' in query results without an aggregate function CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-7242/.s.monetdb.39126 QUERY = SELECT groupnr, aggr2(value, value, value) FROM grouped_ints GROUP BY groupnr; -ERROR = !SELECT: no such aggregate 'aggr2' +ERROR = !SELECT: cannot use non GROUP BY column 'value' in query results without an aggregate function CODE = 42000 # 16:36:13 > diff --git a/sql/test/BugTracker-2018/Tests/sqlitelogictest-groupby-coalesce-error-message.Bug-6608.stable.err b/sql/test/BugTracker-2018/Tests/sqlitelogictest-groupby-coalesce-error-message.Bug-6608.stable.err --- a/sql/test/BugTracker-2018/Tests/sqlitelogictest-groupby-coalesce-error-message.Bug-6608.stable.err +++ b/sql/test/BugTracker-2018/Tests/sqlitelogictest-groupby-coalesce-error-message.Bug-6608.stable.err @@ -30,7 +30,7 @@ stderr of test 'sqlitelogictest-groupby- MAPI = (monetdb) /var/tmp/mtest-4323/.s.monetdb.30108 QUERY = SELECT DISTINCT - COALESCE ( - 86, + cor0.col1, cor0.col1, - cor0.col0 ) AS col2 FROM tab0 AS cor0 GROUP BY cor0.col2, cor0.col0; -ERROR = !SELECT: no such aggregate 'sql_neg' +ERROR = !SELECT: cannot use non GROUP BY column 'cor0.col1' in query results without an aggregate function CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-4323/.s.monetdb.30108 QUERY = SELECT COALESCE ( - 86, + cor0.col1, cor0.col1, - cor0.col0 ) AS col2 FROM tab0 AS cor0 GROUP BY cor0.col2, cor0.col0; @@ -38,7 +38,7 @@ ERROR = !SELECT: cannot use non GROUP BY CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-381150/.s.monetdb.38204 QUERY = SELECT ALL + 33 * - COALESCE ( - 86, tab1.col2 ) + + col1 FROM tab1 GROUP BY tab1.col1; -ERROR = !SELECT: no such aggregate 'sql_neg' +ERROR = !SELECT: cannot use non GROUP BY column 'tab1.col2' in query results without an aggregate function CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-4323/.s.monetdb.30108 QUERY = SELECT COALESCE ( - 86, tab1.col2 ) FROM tab1 GROUP BY tab1.col1; @@ -46,7 +46,7 @@ ERROR = !SELECT: cannot use non GROUP BY CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-381150/.s.monetdb.38204 QUERY = SELECT ALL + COALESCE ( - cor0.col1, cor0.col1, 63, - cor0.col2 ) * - cor0.col1 AS col1 FROM tab0 cor0 GROUP BY cor0.col0, col1; -ERROR = !SELECT: no such aggregate 'sql_neg' +ERROR = !SELECT: cannot use non GROUP BY column 'cor0.col2' in query results without an aggregate function CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-4323/.s.monetdb.30108 QUERY = SELECT ALL + COALESCE ( - cor0.col1, cor0.col1, 63, cor0.col2 ) AS col1 FROM tab0 cor0 GROUP BY cor0.col0, col1; @@ -54,7 +54,7 @@ ERROR = !SELECT: cannot use non GROUP BY CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-381150/.s.monetdb.38204 QUERY = SELECT - 38 + - tab1.col1 - tab1.col1 / COALESCE ( + 20, - tab1.col0 ) FROM tab1 GROUP BY tab1.col1; -ERROR = !SELECT: no such aggregate 'sql_neg' +ERROR = !SELECT: cannot use non GROUP BY column 'tab1.col0' in query results without an aggregate function CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-4323/.s.monetdb.30108 QUERY = SELECT COALESCE ( + 20, tab1.col0 ) FROM tab1 GROUP BY tab1.col1; @@ -62,7 +62,7 @@ ERROR = !SELECT: cannot use non GROUP BY CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-381150/.s.monetdb.38204 QUERY = SELECT DISTINCT COALESCE ( - 82, - cor0.col0, - CAST ( NULL AS INTEGER ) ) / - 70 FROM tab0 AS cor0 GROUP BY cor0.col2; -ERROR = !SELECT: no such aggregate 'sql_neg' +ERROR = !SELECT: cannot use non GROUP BY column 'cor0.col0' in query results without an aggregate function CODE = 42000 MAPI = (monetdb) /var/tmp/mtest-4323/.s.monetdb.30108 QUERY = SELECT DISTINCT COALESCE ( - 82, cor0.col0, - CAST ( NULL AS INTEGER ) ) FROM tab0 AS cor0 GROUP BY cor0.col2; diff --git a/sql/test/subquery/Tests/subquery4.stable.out b/sql/test/subquery/Tests/subquery4.stable.out --- a/sql/test/subquery/Tests/subquery4.stable.out +++ b/sql/test/subquery/Tests/subquery4.stable.out @@ -135,6 +135,14 @@ stdout of test 'subquery4` in directory [ 1 ] [ 2 ] [ 3 ] +#SELECT +# (SELECT MAX(i2.i) FROM (SELECT MIN(i1.i)) AS i2(i)) +#FROM integers i1; +% .%2 # table_name +% %2 # name +% int # type +% 1 # length +[ 1 ] #UPDATE another_T SET col4 = (SELECT SUM(col4 + ColID) FROM tbl_ProductSales); [ 4 ] _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list