Changeset: 186a23b9f3a4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/186a23b9f3a4
Modified Files:
sql/server/rel_select.c
sql/server/sql_query.c
sql/server/sql_query.h
Branch: default
Log Message:
make sure the freevar lookups on the outer stack stay within the bounds.
diffs (111 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
@@ -3517,43 +3517,47 @@ static sql_exp *
all_freevar = vf;
exp = e;
}
- int sql_state = query_fetch_outer_state(query,all_freevar-1);
- res = groupby = query_fetch_outer(query, all_freevar-1);
- card = query_outer_used_card(query, all_freevar-1);
- /* given groupby validate all input expressions */
- char *err;
- if ((err = exps_valid(query, exps, all_freevar)) != NULL) {
- strcpy(sql->errstr, err);
- sql->session->status = -ERR_GROUPBY;
- return NULL;
- }
- if (exp && !is_groupby_col(res, exp)) {
- if (is_sql_groupby(sql_state))
- return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate function '%s' not allowed in GROUP BY clause", aname);
- if (is_sql_aggr(sql_state))
- return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate function calls cannot be nested");
- if (is_sql_values(sql_state))
- return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate functions not allowed on an unique value");
- if (is_sql_update_set(sql_state) || is_sql_psm(f))
- return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate functions not allowed in SET, WHILE, IF, ELSE, CASE, WHEN,
RETURN, ANALYZE clauses");
- if (is_sql_join(sql_state))
- return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate functions not allowed in JOIN conditions");
- if (is_sql_where(sql_state))
- return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate functions not allowed in WHERE clause");
- if (is_psm_call(sql_state))
- return sql_error(sql, 05, SQLSTATE(42000)
"CALL: aggregate functions not allowed inside CALL");
- if (is_sql_from(sql_state))
- return sql_error(sql, 05, SQLSTATE(42000)
"SELECT: aggregate functions not allowed in functions in FROM");
- if (card > CARD_AGGR) { /* used an expression before on
the non grouped relation */
- sql_exp *lu = query_outer_last_used(query,
all_freevar-1);
- if (lu->type == e_column)
- return sql_error(sql, ERR_GROUPBY,
SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\" from outer
query", (char*)lu->l, (char*)lu->r);
- if (exp_name(lu) && exp_relname(lu) &&
!has_label(lu))
- return sql_error(sql, ERR_GROUPBY,
SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\" from outer
query", exp_relname(lu), exp_name(lu));
- return sql_error(sql, ERR_GROUPBY,
SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query");
+ if (query_has_outer(query) >= all_freevar) {
+ int sql_state =
query_fetch_outer_state(query,all_freevar-1);
+ res = groupby = query_fetch_outer(query, all_freevar-1);
+ card = query_outer_used_card(query, all_freevar-1);
+ /* given groupby validate all input expressions */
+ char *err;
+ if ((err = exps_valid(query, exps, all_freevar)) !=
NULL) {
+ strcpy(sql->errstr, err);
+ sql->session->status = -ERR_GROUPBY;
+ return NULL;
}
- if (is_outer(groupby))
- return sql_error(sql, ERR_GROUPBY,
SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query");
+ if (exp && !is_groupby_col(res, exp)) {
+ if (is_sql_groupby(sql_state))
+ return sql_error(sql, 05,
SQLSTATE(42000) "SELECT: aggregate function '%s' not allowed in GROUP BY
clause", aname);
+ if (is_sql_aggr(sql_state))
+ return sql_error(sql, 05,
SQLSTATE(42000) "SELECT: aggregate function calls cannot be nested");
+ if (is_sql_values(sql_state))
+ return sql_error(sql, 05,
SQLSTATE(42000) "SELECT: aggregate functions not allowed on an unique value");
+ if (is_sql_update_set(sql_state) ||
is_sql_psm(f))
+ return sql_error(sql, 05,
SQLSTATE(42000) "SELECT: aggregate functions not allowed in SET, WHILE, IF,
ELSE, CASE, WHEN, RETURN, ANALYZE clauses");
+ if (is_sql_join(sql_state))
+ return sql_error(sql, 05,
SQLSTATE(42000) "SELECT: aggregate functions not allowed in JOIN conditions");
+ if (is_sql_where(sql_state))
+ return sql_error(sql, 05,
SQLSTATE(42000) "SELECT: aggregate functions not allowed in WHERE clause");
+ if (is_psm_call(sql_state))
+ return sql_error(sql, 05,
SQLSTATE(42000) "CALL: aggregate functions not allowed inside CALL");
+ if (is_sql_from(sql_state))
+ return sql_error(sql, 05,
SQLSTATE(42000) "SELECT: aggregate functions not allowed in functions in FROM");
+ if (card > CARD_AGGR) { /* used an expression
before on the non grouped relation */
+ sql_exp *lu =
query_outer_last_used(query, all_freevar-1);
+ if (lu->type == e_column)
+ return sql_error(sql,
ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\"
from outer query", (char*)lu->l, (char*)lu->r);
+ if (exp_name(lu) && exp_relname(lu) &&
!has_label(lu))
+ return sql_error(sql,
ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\"
from outer query", exp_relname(lu), exp_name(lu));
+ return sql_error(sql, ERR_GROUPBY,
SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query");
+ }
+ if (is_outer(groupby))
+ return sql_error(sql, ERR_GROUPBY,
SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query");
+ }
+ } else {
+ all_freevar = 0;
}
} else if (!subquery && groupby && is_outer(groupby) &&
!is_groupby(groupby->op))
return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT:
subquery uses ungrouped column from outer query");
diff --git a/sql/server/sql_query.c b/sql/server/sql_query.c
--- a/sql/server/sql_query.c
+++ b/sql/server/sql_query.c
@@ -79,7 +79,7 @@ query_update_outer(sql_query *q, sql_rel
sq->grouped = is_groupby(r->op);
}
-int
+unsigned int
query_has_outer(sql_query *q)
{
return sql_stack_top(q->outer);
diff --git a/sql/server/sql_query.h b/sql/server/sql_query.h
--- a/sql/server/sql_query.h
+++ b/sql/server/sql_query.h
@@ -33,7 +33,7 @@ extern sql_rel *query_pop_outer(sql_quer
extern sql_rel *query_fetch_outer(sql_query *q, int i);
extern int query_fetch_outer_state(sql_query *q, int i);
extern void query_update_outer(sql_query *q, sql_rel *r, int i);
-extern int query_has_outer(sql_query *q); /* returns number of outer relations
*/
+extern unsigned int query_has_outer(sql_query *q); /* returns number of outer
relations */
extern int query_outer_used_exp(sql_query *q, int i, sql_exp *e, int f);
extern void query_outer_pop_last_used(sql_query *q, int i);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list