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

Reply via email to