Changeset: 466f075c39c2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/466f075c39c2 Modified Files: sql/server/rel_select.c sql/test/SQLancer/Tests/sqlancer23.test Branch: default Log Message:
Validate aggregates without parameters inside subqueries diffs (143 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 @@ -3418,14 +3418,14 @@ static sql_exp * mvc *sql = query->sql; exp_kind ek = {type_value, card_column, FALSE}; sql_subfunc *a = NULL; - int no_nil = 0, group = 0; + int no_nil = 0, group = 0, all_aggr = query_has_outer(query), i; unsigned int all_freevar = 0; sql_rel *groupby = rel ? *rel : NULL, *sel = NULL, *gr, *og = NULL, *res = groupby; sql_rel *subquery = NULL; - list *exps = NULL; + list *exps = NULL, *ungrouped_cols = NULL; bool is_grouping = !strcmp(aname, "grouping"), has_args = false, found = false, used_rel = false; - if (!query_has_outer(query)) { + if (!all_aggr) { if (!groupby) { char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); return sql_error(sql, 02, SQLSTATE(42000) "%s: missing group by", toUpperCopy(uaname, aname)); @@ -3458,9 +3458,7 @@ static sql_exp * exps = sa_list(sql->sa); if (args && args->data.sym) { - int i, all_aggr = query_has_outer(query); bool arguments_correlated = true, all_const = true; - list *ungrouped_cols = NULL; all_freevar = all_aggr?1:0; for (i = 0; args && args->data.sym; args = args->next, i++) { @@ -3496,54 +3494,54 @@ static sql_exp * } if (all_const) all_freevar = 0; - if (!all_freevar) { - if (is_sql_groupby(f)) { - char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); - return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate function '%s' not allowed in GROUP BY clause", toUpperCopy(uaname, aname), aname); - } else if (is_sql_aggr(f) && groupby->grouped) { - char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); - return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions cannot be nested", toUpperCopy(uaname, aname)); - } else if (is_sql_values(f)) { - char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); - return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed on an unique value", toUpperCopy(uaname, aname)); - } else if (is_sql_join(f)) { /* the is_sql_join test must come before is_sql_where, because the join conditions are handled with sql_where */ - char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); - return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in JOIN conditions", toUpperCopy(uaname, aname)); - } else if (is_sql_where(f)) { - char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); - return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in WHERE clause", toUpperCopy(uaname, aname)); - } else if (is_sql_from(f)) { - char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); - return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in functions in FROM", toUpperCopy(uaname, aname)); - } else if (!all_aggr && ungrouped_cols && !list_empty(ungrouped_cols)) { - for (node *n = ungrouped_cols->h ; n ; n = n->next) { - sql_rel *outer; - sql_exp *e = (sql_exp*) n->data; - - if ((outer = query_fetch_outer(query, is_freevar(e)-1))) { - int of = query_fetch_outer_state(query, is_freevar(e)-1); - if (outer->grouped) { - bool err = false, was_processed = false; - - if (is_processed(outer)) { - was_processed = true; - reset_processed(outer); - } - if (!is_groupby_col(outer, e)) - err = true; - if (was_processed) - set_processed(outer); - if (err) { - if (exp_name(e) && exp_relname(e) && !has_label(e)) - return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\" from outer query", exp_relname(e), exp_name(e)); - return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query"); - } - } else if (!used_rel && is_sql_where(of)) { - char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); - return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in WHERE clause", toUpperCopy(uaname, aname)); - } else if (!is_sql_aggr(of)) { - set_outer(outer); + } + if (!all_freevar) { + if (is_sql_groupby(f)) { + char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); + return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate function '%s' not allowed in GROUP BY clause", toUpperCopy(uaname, aname), aname); + } else if (is_sql_aggr(f) && groupby->grouped) { + char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); + return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions cannot be nested", toUpperCopy(uaname, aname)); + } else if (is_sql_values(f)) { + char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); + return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed on an unique value", toUpperCopy(uaname, aname)); + } else if (is_sql_join(f)) { /* the is_sql_join test must come before is_sql_where, because the join conditions are handled with sql_where */ + char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); + return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in JOIN conditions", toUpperCopy(uaname, aname)); + } else if (is_sql_where(f)) { + char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); + return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in WHERE clause", toUpperCopy(uaname, aname)); + } else if (is_sql_from(f)) { + char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); + return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in functions in FROM", toUpperCopy(uaname, aname)); + } else if (!all_aggr && !list_empty(ungrouped_cols)) { + for (node *n = ungrouped_cols->h ; n ; n = n->next) { + sql_rel *outer; + sql_exp *e = (sql_exp*) n->data; + + if ((outer = query_fetch_outer(query, is_freevar(e)-1))) { + int of = query_fetch_outer_state(query, is_freevar(e)-1); + if (outer->grouped) { + bool err = false, was_processed = false; + + if (is_processed(outer)) { + was_processed = true; + reset_processed(outer); } + if (!is_groupby_col(outer, e)) + err = true; + if (was_processed) + set_processed(outer); + if (err) { + if (exp_name(e) && exp_relname(e) && !has_label(e)) + return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\" from outer query", exp_relname(e), exp_name(e)); + return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query"); + } + } else if (!used_rel && is_sql_where(of)) { + char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1); + return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in WHERE clause", toUpperCopy(uaname, aname)); + } else if (!is_sql_aggr(of)) { + set_outer(outer); } } } diff --git a/sql/test/SQLancer/Tests/sqlancer23.test b/sql/test/SQLancer/Tests/sqlancer23.test --- a/sql/test/SQLancer/Tests/sqlancer23.test +++ b/sql/test/SQLancer/Tests/sqlancer23.test @@ -235,3 +235,6 @@ SELECT (SELECT min(min(x.x + y.y)) FROM statement error 42000!SELECT: cannot use non GROUP BY column 'x.x' in query results without an aggregate function SELECT (VALUES (prod(x.x - 1)), (x.x)) FROM (VALUES (1), (0.058128458)) x(x) + +statement error 42000!COUNT: aggregate functions not allowed in WHERE clause +SELECT (SELECT 1 WHERE count(*) = 1) _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org