summaryrefslogtreecommitdiff
path: root/sql/item_subselect.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2020-06-09 23:03:08 +0400
committerAlexander Barkov <bar@mariadb.com>2020-06-10 18:09:35 +0400
commit6e2d967b1b040f2221a20b0f63befafe35ce56b6 (patch)
tree75d961cbb84e1b62c61a9906e4783244c786ce0e /sql/item_subselect.cc
parent264a98eaa0a783e1ce76d18b9105ae00dc11098b (diff)
downloadmariadb-git-6e2d967b1b040f2221a20b0f63befafe35ce56b6.tar.gz
MDEV-14347 CREATE PROCEDURE returns no error when using an unknown variable
CREATE PROCEDURE did not detect unknown SP variables in assignments like this: SET var=a_long_var_name_with_a_typo; The error happened only during the SP execution time, and only of the control flow reaches the erroneous statement. Fixing most expressions to detect unknown identifiers. This includes simple subqueries without tables: - Query specification: SELECT list, WHERE, HAVING (inside aggregate functions) clauses, e.g. SET var= (SELECT unknown_ident+1); SET var= (SELECT 1 WHERE unknown_identifier); SET var= (SELECT 1 HAVING SUM(unknown_identifier); - Table value constructor: VALUES clause, e.g.: SET var= (VALUES(unknown_ident)); Note, in some more complex subquery cases unknown variables are still not detected (this will be fixed separately): - Derived tables: SET a=(SELECT unknown_ident FROM (SELECT 1 AS alias) t1); SET res=(SELECT * FROM t1 LEFT OUTER JOIN (SELECT unknown_ident) t2 USING (c1)); - CTE: SET a=(WITH cte1 (a) AS (SELECT unknown_ident) SELECT * FROM cte1); SET a=(WITH cte1 (a,b) AS (VALUES (unknown,2),(3,4)) SELECT * FROM cte1); SET a=(WITH cte1 (a,b) AS (VALUES (1,2),(3,4)) SELECT unknown_ident FROM cte1); - SELECT .. GROUP BY unknown_identifier - SELECT .. ORDER BY unknown_identifier - HAVING with an unknown identifier outside of any aggregate functions: SELECT .. HAVING unknown_identifier;
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r--sql/item_subselect.cc34
1 files changed, 34 insertions, 0 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 10218f392c7..23ff906e3cf 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -661,6 +661,40 @@ bool Item_subselect::is_expensive()
}
+bool Item_subselect::unknown_splocal_processor(void *argument)
+{
+ SELECT_LEX *sl= unit->first_select();
+ if (sl->top_join_list.elements)
+ return 0;
+ if (sl->tvc && sl->tvc->walk_values(&Item::unknown_splocal_processor,
+ false, argument))
+ return true;
+ for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select())
+ {
+ /*
+ TODO: walk through GROUP BY and ORDER yet eventually.
+ This will require checking aliases in SELECT list:
+ SELECT 1 AS a GROUP BY a;
+ SELECT 1 AS a ORDER BY a;
+ */
+ List_iterator<Item> li(lex->item_list);
+ Item *item;
+ if (lex->where && (lex->where)->walk(&Item::unknown_splocal_processor,
+ false, argument))
+ return true;
+ if (lex->having && (lex->having)->walk(&Item::unknown_splocal_processor,
+ false, argument))
+ return true;
+ while ((item=li++))
+ {
+ if (item->walk(&Item::unknown_splocal_processor, false, argument))
+ return true;
+ }
+ }
+ return false;
+}
+
+
bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
void *argument)
{