[Commits] 549bcceefd9: Applying Alexander Barkov patch:
revision-id: 549bcceefd94e8700c9e629bdd2c2f5a73d2459b (mariadb-10.3.6-6-g549bcceefd9) parent(s): a64a078e76c3372f075c7eaed9729a03e524cd47 author: Oleksandr Byelkin committer: Oleksandr Byelkin timestamp: 2018-05-22 19:38:27 +0200 message: Applying Alexander Barkov patch: This patch removes a lot of main_select_push() / pop_select() that you had to add into *.yy files in the 10.3-MDEV-11953 branch. The patch does the following: - Disallows creation of Item_field in the select stack is empty. An error is returned instead (ER_BAD_FIELD_ERROR). The point is that Item_field requires a Name_resolution_context, which is not available with the empty select stack. This additionally fixed the problem reported in: MDEV-14347 CREATE PROCEDURE returns no error when using an unknown variable - Disallows creation of Item_sum and Item_windowfunc the same way, as they also need a Name_resolution_context. It fixed the second part of MDEV-14347, about aggregate and window functions. It also fixed: MDEV-15870 Using aggregate and window function in unexpected places can crash the server (repeatable since 10.2) - Adds FOR_LOOP_BOUND into enum_parsing_place, to force creation of a temporary Item_field when inside a FOR loop: FOR x IN ident If the "ident" is later resolves to a cursor name, then the loop is treated as "explicit cursor FOR loop", otherwise it's a normal field name and therefore the same error (ER_BAD_FIELD_ERROR) is returned. - Adds a new method LEX::create_item_query_expression() to reuse the same code in sql_yacc.yy and sql_yacc_ora.yy. Adds a test for curr_sel, in case of NULL resets curr_sel to &lex->builtin_select. - Adds tests to cover IN and EXISTS subselects in various query parts. This was very weakly covered. While working on this patch I had problems with IN and EXISTS subselects, so I had to cover them. - Adds a function relink_hack() to properly bind st_select_lex containing an IN/EXISTS subselect to thd->lex->builtin_select. This is needed for the cases when the statement does not do main_select_push(). I does not know this code well, so you can fine a better solution. Please suggest. --- mysql-test/main/get_diagnostics.result | 11 +- mysql-test/main/get_diagnostics.test | 7 +- mysql-test/main/mysqldump.result | 4 +- mysql-test/main/mysqldump.test | 2 +- mysql-test/main/signal.result | 6 - mysql-test/main/signal.test | 13 +- mysql-test/main/sp-error.result | 14 +- mysql-test/main/sp-error.test | 19 +-- mysql-test/main/sp.result | 57 +------ mysql-test/main/sp.test | 33 ++-- mysql-test/suite/compat/oracle/r/sp.result | 8 - mysql-test/suite/compat/oracle/t/sp.test | 16 +- mysql-test/suite/funcs_1/r/storedproc.result | 3 +- mysql-test/suite/funcs_1/t/storedproc.test | 1 + sql/item_create.cc | 7 +- sql/item_subselect.cc | 43 ++++- sql/item_sum.cc | 1 + sql/opt_subselect.cc | 1 + sql/sql_lex.cc | 122 +++++++++++--- sql/sql_lex.h | 46 +++++- sql/sql_priv.h | 1 + sql/sql_yacc.yy | 212 +++++-------------------- sql/sql_yacc_ora.yy | 229 +++++---------------------- 23 files changed, 327 insertions(+), 529 deletions(-) diff --git a/mysql-test/main/get_diagnostics.result b/mysql-test/main/get_diagnostics.result index 732be7c0283..6944103c805 100644 --- a/mysql-test/main/get_diagnostics.result +++ b/mysql-test/main/get_diagnostics.result @@ -133,7 +133,7 @@ DROP PROCEDURE p1; GET DIAGNOSTICS CONDITION; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 GET DIAGNOSTICS CONDITION a; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 +ERROR 42S22: Unknown column 'a' in 'field list' GET DIAGNOSTICS CONDITION 1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 GET DIAGNOSTICS CONDITION 1 @var; @@ -212,9 +212,9 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp GET DIAGNOSTICS CONDITION (1) @var = CLASS_ORIGIN; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(1) @var = CLASS_ORIGIN' at line 1 GET DIAGNOSTICS CONDITION p1() @var = CLASS_ORIGIN; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '() @var = CLASS_ORIGIN' at line 1 +ERROR 42S22: Unknown column 'p1' in 'field list' GET DIAGNOSTICS CONDITION ABS(2) @var = CLASS_ORIGIN; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(2) @var = CLASS_ORIGIN' at line 1 +ERROR 42S22: Unknown column 'ABS' in 'field list' GET DIAGNOSTICS CONDITION 1.1 @var = CLASS_ORIGIN; GET DIAGNOSTICS CONDITION "1" @var = CLASS_ORIGIN; SELECT COUNT(max_questions) INTO @var FROM mysql.user; @@ -226,10 +226,7 @@ Warnings: Error 1758 Invalid condition number Error 1758 Invalid condition number GET DIAGNOSTICS CONDITION a @var = CLASS_ORIGIN; -Warnings: -Error 1758 Invalid condition number -Error 1758 Invalid condition number -Error 1054 Unknown column 'a' in 'field list' +ERROR 42S22: Unknown column 'a' in 'field list' SELECT COUNT(max_questions) INTO @var FROM mysql.user; SET @cond = 1; GET DIAGNOSTICS CONDITION @cond @var1 = CLASS_ORIGIN; diff --git a/mysql-test/main/get_diagnostics.test b/mysql-test/main/get_diagnostics.test index a30bad72136..1553eb500b7 100644 --- a/mysql-test/main/get_diagnostics.test +++ b/mysql-test/main/get_diagnostics.test @@ -169,7 +169,7 @@ DROP PROCEDURE p1; --error ER_PARSE_ERROR GET DIAGNOSTICS CONDITION; ---error ER_PARSE_ERROR +--error ER_BAD_FIELD_ERROR GET DIAGNOSTICS CONDITION a; --error ER_PARSE_ERROR GET DIAGNOSTICS CONDITION 1; @@ -271,9 +271,9 @@ GET DIAGNOSTICS CONDITION 1+1 @var = CLASS_ORIGIN; GET DIAGNOSTICS CONDITION ? @var = CLASS_ORIGIN; --error ER_PARSE_ERROR GET DIAGNOSTICS CONDITION (1) @var = CLASS_ORIGIN; ---error ER_PARSE_ERROR +--error ER_BAD_FIELD_ERROR GET DIAGNOSTICS CONDITION p1() @var = CLASS_ORIGIN; ---error ER_PARSE_ERROR +--error ER_BAD_FIELD_ERROR GET DIAGNOSTICS CONDITION ABS(2) @var = CLASS_ORIGIN; # Unfortunate side effects... @@ -285,6 +285,7 @@ SELECT COUNT(max_questions) INTO @var FROM mysql.user; GET DIAGNOSTICS CONDITION 9999 @var = CLASS_ORIGIN; GET DIAGNOSTICS CONDITION NULL @var = CLASS_ORIGIN; +--error ER_BAD_FIELD_ERROR GET DIAGNOSTICS CONDITION a @var = CLASS_ORIGIN; # Reset warnings diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result index a1e206dffd7..7034a7ba2e1 100644 --- a/mysql-test/main/mysqldump.result +++ b/mysql-test/main/mysqldump.result @@ -5153,7 +5153,7 @@ USE BUG52792; SET NAMES utf8; CREATE FUNCTION `straße` ( c1 CHAR(20)) RETURNS CHAR(50) DETERMINISTIC -RETURN CONCAT(']]>, ', s, '!'); +RETURN CONCAT(']]>, ', c1, '!'); <?xml version="1.0"?> <mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <database name="BUG52792"> @@ -5162,7 +5162,7 @@ RETURN CONCAT(']]>, ', s, '!'); <![CDATA[ CREATE DEFINER=`root`@`localhost` FUNCTION `straße`( c1 CHAR(20)) RETURNS char(50) CHARSET latin1 DETERMINISTIC -RETURN CONCAT(']]]]><![CDATA[>, ', s, '!') +RETURN CONCAT(']]]]><![CDATA[>, ', c1, '!') ]]> </routine> </routines> diff --git a/mysql-test/main/mysqldump.test b/mysql-test/main/mysqldump.test index 6dde5aa7bc6..05aabcce6ba 100644 --- a/mysql-test/main/mysqldump.test +++ b/mysql-test/main/mysqldump.test @@ -2351,7 +2351,7 @@ USE BUG52792; SET NAMES utf8; CREATE FUNCTION `straße` ( c1 CHAR(20)) RETURNS CHAR(50) DETERMINISTIC -RETURN CONCAT(']]>, ', s, '!'); +RETURN CONCAT(']]>, ', c1, '!'); --exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=utf8 --compatible=mysql323 -R -X BUG52792 diff --git a/mysql-test/main/signal.result b/mysql-test/main/signal.result index 215f7db8b0d..e329c58a47e 100644 --- a/mysql-test/main/signal.result +++ b/mysql-test/main/signal.result @@ -2285,17 +2285,13 @@ begin DECLARE foo CONDITION FOR SQLSTATE '12345'; SIGNAL foo SET MYSQL_ERRNO = `65`; /* illegal */ end $$ -call test_signal $$ ERROR 42S22: Unknown column '65' in 'field list' -drop procedure test_signal $$ create procedure test_signal() begin DECLARE foo CONDITION FOR SQLSTATE '12345'; SIGNAL foo SET MYSQL_ERRNO = `A`; /* illegal */ end $$ -call test_signal $$ ERROR 42S22: Unknown column 'A' in 'field list' -drop procedure test_signal $$ create procedure test_signal() begin DECLARE foo CONDITION FOR SQLSTATE '12345'; @@ -2346,9 +2342,7 @@ DECLARE foo CONDITION FOR SQLSTATE '12345'; SIGNAL foo SET MYSQL_ERRNO = 1000, MESSAGE_TEXT = `Hello`; end $$ -call test_signal $$ ERROR 42S22: Unknown column 'Hello' in 'field list' -drop procedure test_signal $$ create procedure test_signal() begin DECLARE foo CONDITION FOR SQLSTATE '12345'; diff --git a/mysql-test/main/signal.test b/mysql-test/main/signal.test index e4dcb5a71cf..5b40863b0e6 100644 --- a/mysql-test/main/signal.test +++ b/mysql-test/main/signal.test @@ -2546,25 +2546,21 @@ end $$ call test_signal $$ drop procedure test_signal $$ +-- error ER_BAD_FIELD_ERROR create procedure test_signal() begin DECLARE foo CONDITION FOR SQLSTATE '12345'; SIGNAL foo SET MYSQL_ERRNO = `65`; /* illegal */ end $$ --- error ER_BAD_FIELD_ERROR -call test_signal $$ -drop procedure test_signal $$ +-- error ER_BAD_FIELD_ERROR create procedure test_signal() begin DECLARE foo CONDITION FOR SQLSTATE '12345'; SIGNAL foo SET MYSQL_ERRNO = `A`; /* illegal */ end $$ --- error ER_BAD_FIELD_ERROR -call test_signal $$ -drop procedure test_signal $$ create procedure test_signal() begin @@ -2620,6 +2616,7 @@ end $$ call test_signal $$ drop procedure test_signal $$ +-- error ER_BAD_FIELD_ERROR create procedure test_signal() begin DECLARE foo CONDITION FOR SQLSTATE '12345'; @@ -2627,10 +2624,6 @@ begin MESSAGE_TEXT = `Hello`; end $$ --- error ER_BAD_FIELD_ERROR -call test_signal $$ -drop procedure test_signal $$ - create procedure test_signal() begin DECLARE foo CONDITION FOR SQLSTATE '12345'; diff --git a/mysql-test/main/sp-error.result b/mysql-test/main/sp-error.result index de4c4cf3103..cf74e6c33cd 100644 --- a/mysql-test/main/sp-error.result +++ b/mysql-test/main/sp-error.result @@ -439,6 +439,9 @@ create procedure nodb.bug3339() begin end| ERROR 42000: Unknown database 'nodb' create procedure bug2653_1(a int, out b int) set b = aa| +call bug2653_1(1, @b)| +ERROR 42S22: Unknown column 'aa' in 'field list' +drop procedure bug2653_1| create procedure bug2653_2(a int, out b int) begin if aa < 0 then @@ -447,12 +450,7 @@ else set b = a; end if; end| -call bug2653_1(1, @b)| -ERROR 42S22: Unknown column 'aa' in 'field list' -call bug2653_2(2, @b)| ERROR 42S22: Unknown column 'aa' in 'field list' -drop procedure bug2653_1| -drop procedure bug2653_2| create procedure bug4344() drop procedure bug4344| ERROR HY000: Can't drop or alter a PROCEDURE from within another stored routine create procedure bug4344() drop function bug4344| @@ -1067,6 +1065,7 @@ IF bug13037_foo THEN SELECT 1; END IF; END| +ERROR 42S22: Unknown column 'bug13037_foo' in 'field list' CREATE PROCEDURE bug13037_p2() BEGIN SET @bug13037_foo = bug13037_bar; @@ -1076,19 +1075,14 @@ BEGIN SELECT bug13037_foo; END| -CALL bug13037_p1(); -ERROR 42S22: Unknown column 'bug13037_foo' in 'field list' CALL bug13037_p2(); ERROR 42S22: Unknown column 'bug13037_bar' in 'field list' CALL bug13037_p3(); ERROR 42S22: Unknown column 'bug13037_foo' in 'field list' -CALL bug13037_p1(); -ERROR 42S22: Unknown column 'bug13037_foo' in 'field list' CALL bug13037_p2(); ERROR 42S22: Unknown column 'bug13037_bar' in 'field list' CALL bug13037_p3(); ERROR 42S22: Unknown column 'bug13037_foo' in 'field list' -DROP PROCEDURE bug13037_p1; DROP PROCEDURE bug13037_p2; DROP PROCEDURE bug13037_p3; create database mysqltest1; diff --git a/mysql-test/main/sp-error.test b/mysql-test/main/sp-error.test index 88d9809265a..e2adea88b5b 100644 --- a/mysql-test/main/sp-error.test +++ b/mysql-test/main/sp-error.test @@ -608,6 +608,12 @@ create procedure nodb.bug3339() begin end| create procedure bug2653_1(a int, out b int) set b = aa| +--error ER_BAD_FIELD_ERROR +call bug2653_1(1, @b)| + +drop procedure bug2653_1| + +--error ER_BAD_FIELD_ERROR create procedure bug2653_2(a int, out b int) begin if aa < 0 then @@ -617,13 +623,6 @@ begin end if; end| ---error 1054 -call bug2653_1(1, @b)| ---error 1054 -call bug2653_2(2, @b)| - -drop procedure bug2653_1| -drop procedure bug2653_2| # # BUG#4344 @@ -1507,6 +1506,7 @@ DROP PROCEDURE IF EXISTS bug13037_p3; delimiter |; +--error ER_BAD_FIELD_ERROR CREATE PROCEDURE bug13037_p1() BEGIN IF bug13037_foo THEN @@ -1528,21 +1528,16 @@ delimiter ;| --echo ---error 1054 -CALL bug13037_p1(); --error 1054 CALL bug13037_p2(); --error 1054 CALL bug13037_p3(); ---error 1054 -CALL bug13037_p1(); --error 1054 CALL bug13037_p2(); --error 1054 CALL bug13037_p3(); -DROP PROCEDURE bug13037_p1; DROP PROCEDURE bug13037_p2; DROP PROCEDURE bug13037_p3; diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result index 3e8e2243725..4745e1a1603 100644 --- a/mysql-test/main/sp.result +++ b/mysql-test/main/sp.result @@ -4179,6 +4179,7 @@ select v, isnull(v); end if; end; end| +ERROR 42S22: Unknown column 'undefined_var' in 'field list' create procedure bug14643_2() begin declare continue handler for sqlexception select 'boo' as 'Handler'; @@ -4190,18 +4191,7 @@ select 2; end case; select undefined_var; end| -call bug14643_1()| -Handler -boo -v isnull(v) -NULL 1 -call bug14643_2()| -Handler -boo -Handler -boo -drop procedure bug14643_1| -drop procedure bug14643_2| +ERROR 42S22: Unknown column 'undefined_var' in 'field list' drop procedure if exists bug14304| drop table if exists t3, t4| create table t3(a int primary key auto_increment)| @@ -4231,9 +4221,7 @@ create procedure bug14376() begin declare x int default x; end| -call bug14376()| ERROR 42S22: Unknown column 'x' in 'field list' -drop procedure bug14376| create procedure bug14376() begin declare x int default 42; @@ -4476,6 +4464,7 @@ select 'no' as 'v'; end if; select 'done' as 'End'; end| +ERROR 42S22: Unknown column 'v' in 'field list' create procedure bug14498_2() begin declare continue handler for sqlexception select 'error' as 'Handler'; @@ -4484,6 +4473,7 @@ select 'yes' as 'v'; end while; select 'done' as 'End'; end| +ERROR 42S22: Unknown column 'v' in 'field list' create procedure bug14498_3() begin declare continue handler for sqlexception select 'error' as 'Handler'; @@ -4492,6 +4482,7 @@ select 'maybe' as 'v'; until v end repeat; select 'done' as 'End'; end| +ERROR 42S22: Unknown column 'v' in 'field list' create procedure bug14498_4() begin declare continue handler for sqlexception select 'error' as 'Handler'; @@ -4505,6 +4496,7 @@ select '?' as 'v'; end case; select 'done' as 'End'; end| +ERROR 42S22: Unknown column 'v' in 'field list' create procedure bug14498_5() begin declare continue handler for sqlexception select 'error' as 'Handler'; @@ -4518,38 +4510,7 @@ select '?' as 'v'; end case; select 'done' as 'End'; end| -call bug14498_1()| -Handler -error -End -done -call bug14498_2()| -Handler -error -End -done -call bug14498_3()| -v -maybe -Handler -error -End -done -call bug14498_4()| -Handler -error -End -done -call bug14498_5()| -Handler -error -End -done -drop procedure bug14498_1| -drop procedure bug14498_2| -drop procedure bug14498_3| -drop procedure bug14498_4| -drop procedure bug14498_5| +ERROR 42S22: Unknown column 'v' in 'field list' drop table if exists t3| drop procedure if exists bug15231_1| drop procedure if exists bug15231_2| @@ -8328,14 +8289,12 @@ DECLARE name VARCHAR(10); SET name="hello"; call p1(name2); END| +ERROR 42S22: Unknown column 'name2' in 'field list' call p2(); a hello -call p3(); -ERROR 42S22: Unknown column 'name2' in 'field list' drop procedure p1; drop procedure p2; -drop procedure p3; # # MDEV-15328: MariaDB 10.2.13 Crashes upon CALL PROCEDURE PARAM # LAST_INSERT_ID () diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test index 6308a0906c7..b0f54ac9787 100644 --- a/mysql-test/main/sp.test +++ b/mysql-test/main/sp.test @@ -5040,6 +5040,7 @@ drop procedure if exists bug14643_1| drop procedure if exists bug14643_2| --enable_warnings +--error ER_BAD_FIELD_ERROR create procedure bug14643_1() begin declare continue handler for sqlexception select 'boo' as 'Handler'; @@ -5055,6 +5056,7 @@ begin end; end| +--error ER_BAD_FIELD_ERROR create procedure bug14643_2() begin declare continue handler for sqlexception select 'boo' as 'Handler'; @@ -5069,11 +5071,6 @@ begin select undefined_var; end| -call bug14643_1()| -call bug14643_2()| - -drop procedure bug14643_1| -drop procedure bug14643_2| # # BUG#14304: auto_increment field incorrect set in SP @@ -5114,15 +5111,12 @@ drop table t3, t4| drop procedure if exists bug14376| --enable_warnings +--error ER_BAD_FIELD_ERROR create procedure bug14376() begin declare x int default x; end| -# Not the error we want, but that's what we got for now... ---error ER_BAD_FIELD_ERROR -call bug14376()| -drop procedure bug14376| create procedure bug14376() begin @@ -5344,6 +5338,7 @@ drop procedure if exists bug14498_4| drop procedure if exists bug14498_5| --enable_warnings +--error ER_BAD_FIELD_ERROR create procedure bug14498_1() begin declare continue handler for sqlexception select 'error' as 'Handler'; @@ -5356,6 +5351,7 @@ begin select 'done' as 'End'; end| +--error ER_BAD_FIELD_ERROR create procedure bug14498_2() begin declare continue handler for sqlexception select 'error' as 'Handler'; @@ -5366,6 +5362,7 @@ begin select 'done' as 'End'; end| +--error ER_BAD_FIELD_ERROR create procedure bug14498_3() begin declare continue handler for sqlexception select 'error' as 'Handler'; @@ -5376,6 +5373,7 @@ begin select 'done' as 'End'; end| +--error ER_BAD_FIELD_ERROR create procedure bug14498_4() begin declare continue handler for sqlexception select 'error' as 'Handler'; @@ -5391,6 +5389,7 @@ begin select 'done' as 'End'; end| +--error ER_BAD_FIELD_ERROR create procedure bug14498_5() begin declare continue handler for sqlexception select 'error' as 'Handler'; @@ -5406,17 +5405,6 @@ begin select 'done' as 'End'; end| -call bug14498_1()| -call bug14498_2()| -call bug14498_3()| -call bug14498_4()| -call bug14498_5()| - -drop procedure bug14498_1| -drop procedure bug14498_2| -drop procedure bug14498_3| -drop procedure bug14498_4| -drop procedure bug14498_5| # # BUG#15231: Stored procedure bug with not found condition handler @@ -9827,6 +9815,8 @@ BEGIN SET name="hello"; call p1(name); END| + +--error ER_BAD_FIELD_ERROR CREATE OR REPLACE PROCEDURE p3 () BEGIN DECLARE name VARCHAR(10); @@ -9837,11 +9827,8 @@ END| DELIMITER ;| call p2(); ---error ER_BAD_FIELD_ERROR -call p3(); drop procedure p1; drop procedure p2; -drop procedure p3; --echo # --echo # MDEV-15328: MariaDB 10.2.13 Crashes upon CALL PROCEDURE PARAM diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result index 7f042825385..2049f234df3 100644 --- a/mysql-test/suite/compat/oracle/r/sp.result +++ b/mysql-test/suite/compat/oracle/r/sp.result @@ -1019,9 +1019,7 @@ LOOP EXIT WHEN unknown_ident IS NULL; END LOOP; END$$ -CALL p1; ERROR 42S22: Unknown column 'unknown_ident' in 'field list' -DROP PROCEDURE p1; CREATE PROCEDURE p1 AS BEGIN @@ -1030,9 +1028,7 @@ LOOP EXIT label WHEN unknown_ident IS NULL; END LOOP; END$$ -CALL p1; ERROR 42S22: Unknown column 'unknown_ident' in 'field list' -DROP PROCEDURE p1; CREATE PROCEDURE p1 AS BEGIN @@ -1040,9 +1036,7 @@ LOOP CONTINUE WHEN unknown_ident IS NULL; END LOOP; END$$ -CALL p1; ERROR 42S22: Unknown column 'unknown_ident' in 'field list' -DROP PROCEDURE p1; CREATE PROCEDURE p1 AS BEGIN @@ -1051,9 +1045,7 @@ LOOP CONTINUE label WHEN unknown_ident IS NULL; END LOOP; END$$ -CALL p1; ERROR 42S22: Unknown column 'unknown_ident' in 'field list' -DROP PROCEDURE p1; # # MDEV-10583 sql_mode=ORACLE: SQL%ROWCOUNT # diff --git a/mysql-test/suite/compat/oracle/t/sp.test b/mysql-test/suite/compat/oracle/t/sp.test index b88271ad3e2..de2a4a5e4e7 100644 --- a/mysql-test/suite/compat/oracle/t/sp.test +++ b/mysql-test/suite/compat/oracle/t/sp.test @@ -1092,6 +1092,7 @@ DROP FUNCTION f1; --echo # DELIMITER $$; +--error ER_BAD_FIELD_ERROR CREATE PROCEDURE p1 AS BEGIN @@ -1100,12 +1101,10 @@ BEGIN END LOOP; END$$ DELIMITER ;$$ ---error ER_BAD_FIELD_ERROR -CALL p1; -DROP PROCEDURE p1; DELIMITER $$; +--error ER_BAD_FIELD_ERROR CREATE PROCEDURE p1 AS BEGIN @@ -1115,12 +1114,10 @@ BEGIN END LOOP; END$$ DELIMITER ;$$ ---error ER_BAD_FIELD_ERROR -CALL p1; -DROP PROCEDURE p1; DELIMITER $$; +--error ER_BAD_FIELD_ERROR CREATE PROCEDURE p1 AS BEGIN @@ -1129,12 +1126,10 @@ BEGIN END LOOP; END$$ DELIMITER ;$$ ---error ER_BAD_FIELD_ERROR -CALL p1; -DROP PROCEDURE p1; DELIMITER $$; +--error ER_BAD_FIELD_ERROR CREATE PROCEDURE p1 AS BEGIN @@ -1144,9 +1139,6 @@ BEGIN END LOOP; END$$ DELIMITER ;$$ ---error ER_BAD_FIELD_ERROR -CALL p1; -DROP PROCEDURE p1; --echo # --echo # MDEV-10583 sql_mode=ORACLE: SQL%ROWCOUNT diff --git a/mysql-test/suite/funcs_1/r/storedproc.result b/mysql-test/suite/funcs_1/r/storedproc.result index e5e009a86de..0fe7082bea1 100644 --- a/mysql-test/suite/funcs_1/r/storedproc.result +++ b/mysql-test/suite/funcs_1/r/storedproc.result @@ -15723,6 +15723,7 @@ Testcase 4.3.7: DROP PROCEDURE IF EXISTS sp7; CREATE PROCEDURE sp7() BEGIN +DECLARE count INT DEFAULT 100; label1: loop set @dummystring = 'temp value'; if count > 10 then leave label1; @@ -15732,7 +15733,7 @@ END label1 loop; END// ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'iterate; END label1 loop; -END' at line 7 +END' at line 8 DROP PROCEDURE IF EXISTS sp7; CREATE PROCEDURE sp7() BEGIN diff --git a/mysql-test/suite/funcs_1/t/storedproc.test b/mysql-test/suite/funcs_1/t/storedproc.test index 98385d42b22..31786410a7b 100644 --- a/mysql-test/suite/funcs_1/t/storedproc.test +++ b/mysql-test/suite/funcs_1/t/storedproc.test @@ -18861,6 +18861,7 @@ delimiter //; --error ER_PARSE_ERROR CREATE PROCEDURE sp7() BEGIN + DECLARE count INT DEFAULT 100; label1: loop set @dummystring = 'temp value'; if count > 10 then leave label1; diff --git a/sql/item_create.cc b/sql/item_create.cc index 901dfa06f40..b3fbdfd97cf 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -3487,12 +3487,11 @@ Create_sp_func::create_with_db(THD *thd, LEX_CSTRING *db, LEX_CSTRING *name, sph->add_used_routine(lex, thd, qname); if (pkgname.m_name.length) sp_handler_package_body.add_used_routine(lex, thd, &pkgname); + Name_resolution_context *ctx= lex->current_context_or_default(); if (arg_count > 0) - func= new (thd->mem_root) Item_func_sp(thd, lex->current_context(), - qname, sph, *item_list); + func= new (thd->mem_root) Item_func_sp(thd, ctx, qname, sph, *item_list); else - func= new (thd->mem_root) Item_func_sp(thd, lex->current_context(), - qname, sph); + func= new (thd->mem_root) Item_func_sp(thd, ctx, qname, sph); lex->safe_to_cache_query= 0; return func; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 5a447cef23a..9ca44c616a5 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -115,7 +115,8 @@ void Item_subselect::init(st_select_lex *select_lex, do not take into account expression inside aggregate functions because they can access original table fields */ - parsing_place= (outer_select->in_sum_expr ? + // QQ: shouldn't we use relink_hack() instead ? + parsing_place= (!outer_select || outer_select->in_sum_expr ? NO_MATTER : outer_select->parsing_place); if (unit->is_unit_op() && unit->first_select()->next_select()) @@ -239,6 +240,9 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) { SELECT_LEX *upper= unit->outer_select(); + // QQ: shouldn't we use relink_hack() instead? + if (!upper) + upper= &thd_param->lex->builtin_select; if (upper->parsing_place == IN_HAVING) upper->subquery_in_having= 1; /* The subquery is an expression cache candidate */ @@ -1395,12 +1399,46 @@ bool Item_singlerow_subselect::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) } +/* + "IN" and "EXISTS" subselect can appear in two statement types: + + 1. Statements that can have table columns, such as SELECT, DELETE, UPDATE + 2. Statements that cannot have table columns, e.g: + RETURN ((1) IN (SELECT * FROM t1)) + IF ((1) IN (SELECT * FROM t1)) + + Statements of the first type call master_select_push() in the beginning. + In such case everything is properly linked. + + Statements of the second type do not call mastr_select_push(). + Here we catch the second case and relink thd->lex->builtin_select and + select_lex to properly point to each other. + + QQ: Shouldn't subselects of other type also call relink_hack()? + QQ: Can we do it at constructor time instead? +*/ +static void relink_hack(THD *thd, st_select_lex *select_lex) +{ + if (!thd->lex->select_stack_top) // Statements of the second type + { + if (!select_lex->get_master()->get_master()) + ((st_select_lex *) select_lex->get_master())-> + set_master(&thd->lex->builtin_select); + if (!thd->lex->builtin_select.get_slave()) + thd->lex->builtin_select.set_slave(select_lex->get_master()); + } +} + + Item_exists_subselect::Item_exists_subselect(THD *thd, st_select_lex *select_lex): Item_subselect(thd), upper_not(NULL), abort_on_null(0), emb_on_expr_nest(NULL), optimizer(0), exists_transformed(0) { DBUG_ENTER("Item_exists_subselect::Item_exists_subselect"); + + relink_hack(thd, select_lex); + init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this)); max_columns= UINT_MAX; null_value= FALSE; //can't be NULL @@ -1443,6 +1481,9 @@ Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp, { DBUG_ENTER("Item_in_subselect::Item_in_subselect"); DBUG_PRINT("info", ("in_strategy: %u", (uint)in_strategy)); + + relink_hack(thd, select_lex); + left_expr_orig= left_expr= left_exp; /* prepare to possible disassembling the item in convert_subq_to_sj() */ if (left_exp->type() == Item::ROW_ITEM) diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 2ec7e3c338f..a8800502daf 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -72,6 +72,7 @@ size_t Item_sum::ram_limitation(THD *thd) bool Item_sum::init_sum_func_check(THD *thd) { SELECT_LEX *curr_sel= thd->lex->current_select; + DBUG_ASSERT(curr_sel); if (!curr_sel->name_visibility_map) { for (SELECT_LEX *sl= curr_sel; sl; sl= sl->context.outer_select()) diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index a55ce2d163c..70f82d53eba 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -518,6 +518,7 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs, if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) && // 0 !child_select->is_part_of_union() && // 1 parent_unit->first_select()->leaf_tables.elements && // 2 + child_select->outer_select() && child_select->outer_select()->leaf_tables.elements && // 2A subquery_types_allow_materialization(in_subs) && (in_subs->is_top_level_item() || //3 diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index db055eb012e..55e76c7effd 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -6006,9 +6006,17 @@ bool LEX::sp_for_loop_implicit_cursor_statement(THD *thd, bounds->m_index->sp_lex_in_use= true; sphead->reset_lex(thd, bounds->m_index); DBUG_ASSERT(thd->lex != this); - if (!(item= new (thd->mem_root) Item_field(thd, - thd->lex->current_context(), - NullS, NullS, &name))) + /* + We pass NULL as Name_resolution_context here. + It's OK, fix_fields() will not be called for this Item_field created. + Item_field is only needed for LEX::sp_for_loop_cursor_declarations() + and is used to transfer the loop index variable name, "rec" in this example: + FOR rec IN (SELECT * FROM t1) + DO + SELECT rec.a, rec.b; + END FOR; + */ + if (!(item= new (thd->mem_root) Item_field(thd, NULL, NullS, NullS, &name))) return true; bounds->m_index->set_item_and_free_list(item, NULL); if (thd->lex->sphead->restore_lex(thd)) @@ -6112,6 +6120,19 @@ bool LEX::sp_for_loop_intrange_declarations(THD *thd, Lex_for_loop_st *loop, const LEX_CSTRING *index, const Lex_for_loop_bounds_st &bounds) { + Item *item; + if ((item= bounds.m_index->get_item())->type() == Item::FIELD_ITEM) + { + // We're here is the lower bound is unknown identifier + my_error(ER_SP_UNDECLARED_VAR, MYF(0), item->full_name()); + return true; + } + if ((item= bounds.m_upper_bound->get_item())->type() == Item::FIELD_ITEM) + { + // We're here is the upper bound is unknown identifier + my_error(ER_SP_UNDECLARED_VAR, MYF(0), item->full_name()); + return true; + } if (!(loop->m_index= bounds.m_index->sp_add_for_loop_variable(thd, index, bounds.m_index->get_item()))) @@ -6989,6 +7010,38 @@ bool LEX::add_resignal_statement(THD *thd, const sp_condition_value *v) } +/* + Make an Item when an identifier is found in the FOR loop bounds: + FOR rec IN cursor + FOR var IN var1 .. xxx + FOR var IN row1.field1 .. xxx + When we parse the first expression after the "IN" keyword, + we don't know yet if it's a cursor name, or a scalar SP variable name, + or a field of a ROW SP variable. Here we create Item_field to remember + the fully qualified name. Later sp_for_loop_cursor_declarations() + detects how to treat this name properly. +*/ +Item *LEX::create_item_for_loop_bound(THD *thd, + const LEX_CSTRING *a, + const LEX_CSTRING *b, + const LEX_CSTRING *c) +{ + /* + Pass NULL as the name resolution context. + This is OK, fix_fields() won't be called for this Item_field. + */ + return new (thd->mem_root) Item_field(thd, NULL, a->str, b->str, c); +} + + +bool LEX::check_expr_allows_fields_or_error(THD *thd, const char *name) const +{ + if (select_stack_top > 0) + return false; // OK, fields are allowed + my_error(ER_BAD_FIELD_ERROR, MYF(0), name, thd->where); + return true; // Error, fields are not allowed +} + Item *LEX::create_item_ident_nospvar(THD *thd, const LEX_CSTRING *a, const LEX_CSTRING *b) @@ -7011,12 +7064,11 @@ Item *LEX::create_item_ident_nospvar(THD *thd, my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), a->str, thd->where); return NULL; } - if ((current_select->parsing_place != IN_HAVING) || - (current_select->get_in_sum_expr() > 0)) - return new (thd->mem_root) Item_field(thd, current_context(), - NullS, a->str, b); - return new (thd->mem_root) Item_ref(thd, current_context(), - NullS, a->str, b); + + if (current_select->parsing_place == FOR_LOOP_BOUND) + return create_item_for_loop_bound(thd, &null_clex_str, a, b); + + return create_item_ident_field(thd, NullS, a->str, b); } @@ -7217,12 +7269,11 @@ Item *LEX::create_item_ident(THD *thd, my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), b->str, thd->where); return NULL; } - if (current_select->parsing_place != IN_HAVING || - current_select->get_in_sum_expr() > 0) - return new (thd->mem_root) Item_field(thd, current_context(), - schema, b->str, c); - return new (thd->mem_root) Item_ref(thd, current_context(), - schema, b->str, c); + + if (current_select->parsing_place == FOR_LOOP_BOUND) + return create_item_for_loop_bound(thd, &null_clex_str, b, c); + + return create_item_ident_field(thd, schema, b->str, c); } @@ -7298,15 +7349,19 @@ bool LEX::set_user_variable(THD *thd, const LEX_CSTRING *name, Item *val) } -Item *LEX::create_item_ident_nosp(THD *thd, LEX_CSTRING *name) +Item *LEX::create_item_ident_field(THD *thd, const char *db, + const char *table, const LEX_CSTRING *name) { + if (check_expr_allows_fields_or_error(thd, name->str)) + return NULL; + if (current_select->parsing_place != IN_HAVING || current_select->get_in_sum_expr() > 0) return new (thd->mem_root) Item_field(thd, current_context(), - NullS, NullS, name); + db, table, name); return new (thd->mem_root) Item_ref(thd, current_context(), - NullS, NullS, name); + db, table, name); } @@ -7352,6 +7407,11 @@ Item *LEX::create_item_ident_sp(THD *thd, LEX_CSTRING *name, if (!my_strcasecmp(system_charset_info, name->str, "SQLERRM")) return new (thd->mem_root) Item_func_sqlerrm(thd); } + + if (current_select->parsing_place == FOR_LOOP_BOUND) + return create_item_for_loop_bound(thd, &null_clex_str, &null_clex_str, + name); + return create_item_ident_nosp(thd, name); } @@ -8648,3 +8708,29 @@ bool LEX::insert_select_hack(SELECT_LEX *sel) DBUG_RETURN(FALSE); } + + +/* + Create an Item_singlerow_subselect for a query expression. +*/ +Item *LEX::create_item_query_expression(THD *thd, + const char *tok_start, + st_select_lex_unit *unit) +{ + if (!expr_allows_subselect || sql_command == SQLCOM_PURGE) + { + thd->parse_error(ER_SYNTAX_ERROR, tok_start); + return NULL; + } + + // Add the subtree of subquery to the current SELECT_LEX + SELECT_LEX *curr_sel= select_stack_head(); + DBUG_ASSERT(current_select == curr_sel); + if (!curr_sel) + curr_sel= &builtin_select; + curr_sel->register_unit(unit, &curr_sel->context); + curr_sel->add_statistics(unit); + + return new (thd->mem_root) + Item_singlerow_subselect(thd, unit->first_select()); +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 4fc74474d56..f715fddc5f0 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -606,6 +606,7 @@ class st_select_lex_node { } inline st_select_lex_node* get_master() { return master; } + inline st_select_lex_node* get_slave() { return slave; } void include_down(st_select_lex_node *upper); void add_slave(st_select_lex_node *slave_arg); void include_neighbour(st_select_lex_node *before); @@ -1116,6 +1117,10 @@ class st_select_lex: public st_select_lex_node { master= (st_select_lex_node *)master_unit; } + void set_master(st_select_lex *master_arg) + { + master= master_arg; + } st_select_lex_unit* first_inner_unit() { return (st_select_lex_unit*) slave; @@ -2843,6 +2848,12 @@ struct LEX: public Query_tables_list bool sp_for_loop_condition(THD *thd, const Lex_for_loop_st &loop); bool sp_for_loop_increment(THD *thd, const Lex_for_loop_st &loop); + /* + Check if Item_field and Item_ref are allowed in the current statement. + @retval false OK (fields are allowed) + @retval true ERROR (fields are not allowed). Error is raised. + */ + bool check_expr_allows_fields_or_error(THD *thd, const char *name) const; public: void parse_error(uint err_number= ER_SYNTAX_ERROR); inline bool is_arena_for_set_stmt() {return arena_for_set_stmt != 0;} @@ -3312,12 +3323,25 @@ struct LEX: public Query_tables_list DBUG_RETURN(select_lex); } + SELECT_LEX *current_select_or_default() + { + return current_select ? current_select : &builtin_select; + } + bool copy_db_to(LEX_CSTRING *to); Name_resolution_context *current_context() { return context_stack.head(); } + Name_resolution_context *current_context_or_default() + { + Name_resolution_context *ctx= current_context(); + if (!ctx) + return &builtin_select.context; + return ctx; + } + /* Restore the LEX and THD in case of a parse error. */ @@ -3484,7 +3508,12 @@ struct LEX: public Query_tables_list Item_splocal *create_item_for_sp_var(LEX_CSTRING *name, sp_variable *spvar, const char *start, const char *end); - Item *create_item_ident_nosp(THD *thd, LEX_CSTRING *name); + Item *create_item_ident_field(THD *thd, const char *db, const char *table, + const LEX_CSTRING *name); + Item *create_item_ident_nosp(THD *thd, LEX_CSTRING *name) + { + return create_item_ident_field(thd, NullS, NullS, name); + } Item *create_item_ident_sp(THD *thd, LEX_CSTRING *name, const char *start, const char *end); Item *create_item_ident(THD *thd, LEX_CSTRING *name, @@ -3614,6 +3643,10 @@ struct LEX: public Query_tables_list const char *start, const char *end); + Item *create_item_query_expression(THD *thd, + const char *tok_start, + st_select_lex_unit *unit); + Item *make_item_func_replace(THD *thd, Item *org, Item *find, Item *replace); Item *make_item_func_substr(THD *thd, Item *a, Item *b, Item *c); Item *make_item_func_substr(THD *thd, Item *a, Item *b); @@ -3791,6 +3824,17 @@ struct LEX: public Query_tables_list sp_for_loop_cursor_finalize(thd, loop) : sp_for_loop_intrange_finalize(thd, loop); } + + /* + Make an Item when an identifier is found in the FOR loop bounds: + FOR rec IN cursor + FOR rec IN var1 .. var2 + FOR rec IN row1.field1 .. xxx + */ + Item *create_item_for_loop_bound(THD *thd, + const LEX_CSTRING *a, + const LEX_CSTRING *b, + const LEX_CSTRING *c); /* End of FOR LOOP methods */ bool add_signal_statement(THD *thd, const class sp_condition_value *value); diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 7fda6198dcf..5ad21167b94 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -363,6 +363,7 @@ enum enum_parsing_place IN_PART_FUNC, BEFORE_OPT_LIST, AFTER_LIST, + FOR_LOOP_BOUND, PARSING_PLACE_SIZE /* always should be the last */ }; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b5e3bb4f73d..491874b3b45 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2222,12 +2222,7 @@ deallocate_or_drop: ; prepare: - PREPARE_SYM - { - if (Lex->main_select_push()) - MYSQL_YYABORT; - } - ident FROM prepare_src + PREPARE_SYM ident FROM prepare_src { LEX *lex= thd->lex; if (lex->table_or_sp_used()) @@ -2236,8 +2231,7 @@ prepare: if (Lex->check_main_unit_semantics()) MYSQL_YYABORT; lex->sql_command= SQLCOM_PREPARE; - lex->prepared_stmt_name= $3; - Lex->pop_select(); //main select + lex->prepared_stmt_name= $2; } ; @@ -2256,21 +2250,13 @@ execute: LEX *lex= thd->lex; lex->sql_command= SQLCOM_EXECUTE; lex->prepared_stmt_name= $2; - if (Lex->main_select_push()) - MYSQL_YYABORT; } execute_using { - Lex->pop_select(); //main select if (Lex->check_main_unit_semantics()) MYSQL_YYABORT; } - | EXECUTE_SYM IMMEDIATE_SYM - { - if (Lex->main_select_push()) - MYSQL_YYABORT; - } - prepare_src + | EXECUTE_SYM IMMEDIATE_SYM prepare_src { if (Lex->table_or_sp_used()) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), @@ -2279,7 +2265,6 @@ execute: } execute_using { - Lex->pop_select(); //main select if (Lex->check_main_unit_semantics()) MYSQL_YYABORT; } @@ -2812,7 +2797,6 @@ create: if (Lex->main_select_push()) MYSQL_YYABORT; Lex->create_info.set($1); - } sf_tail_aggregate { @@ -3306,13 +3290,8 @@ call: { if (Lex->call_statement_start(thd, $2)) MYSQL_YYABORT; - if (Lex->main_select_push()) - MYSQL_YYABORT; - } - opt_sp_cparam_list - { - Lex->pop_select(); //main select } + opt_sp_cparam_list {} ; /* CALL parameters */ @@ -3729,16 +3708,10 @@ sp_hcond: ; signal_stmt: - SIGNAL_SYM - { - if (Lex->main_select_push()) - YYABORT; - } - signal_value opt_set_signal_information + SIGNAL_SYM signal_value opt_set_signal_information { - if (Lex->add_signal_statement(thd, $3)) + if (Lex->add_signal_statement(thd, $2)) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -3864,14 +3837,9 @@ resignal_stmt: ; get_diagnostics: - GET_SYM which_area DIAGNOSTICS_SYM + GET_SYM which_area DIAGNOSTICS_SYM diagnostics_information { - if (Lex->main_select_push()) - YYABORT; - } - diagnostics_information - { - Diagnostics_information *info= $5; + Diagnostics_information *info= $4; info->set_which_da($2); @@ -3880,7 +3848,6 @@ get_diagnostics: if (Lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -4048,16 +4015,7 @@ sp_decl_idents: sp_opt_default: /* Empty */ { $$ = NULL; } - | DEFAULT - { - if (Lex->main_select_push()) - MYSQL_YYABORT; - } - expr - { - Lex->pop_select(); //main select - $$ = $3; - } + | DEFAULT expr { $$ = $2; } ; /* @@ -4159,15 +4117,10 @@ sp_proc_stmt_statement: sp_proc_stmt_return: RETURN_SYM - { - Lex->sphead->reset_lex(thd); - if (Lex->main_select_push()) - MYSQL_YYABORT; - } + { Lex->sphead->reset_lex(thd); } expr { LEX *lex= Lex; - lex->pop_select(); //main select sp_head *sp= lex->sphead; if (sp->m_handler->add_instr_freturn(thd, sp, lex->spcont, $3, lex) || @@ -4205,8 +4158,6 @@ assignment_source_expr: { DBUG_ASSERT(thd->free_list == NULL); Lex->sphead->reset_lex(thd, $1); - if (Lex->main_select_push()) - MYSQL_YYABORT; } expr { @@ -4215,7 +4166,6 @@ assignment_source_expr: $$->sp_lex_in_use= true; $$->set_item_and_free_list($3, thd->free_list); thd->free_list= NULL; - Lex->pop_select(); //main select if ($$->sphead->restore_lex(thd)) MYSQL_YYABORT; } @@ -4225,6 +4175,7 @@ for_loop_bound_expr: assignment_source_lex { Lex->sphead->reset_lex(thd, $1); + Lex->current_select->parsing_place= FOR_LOOP_BOUND; } expr { @@ -4234,6 +4185,7 @@ for_loop_bound_expr: $$->set_item_and_free_list($3, NULL); if ($$->sphead->restore_lex(thd)) MYSQL_YYABORT; + Lex->current_select->parsing_place= NO_MATTER; } ; @@ -4348,14 +4300,9 @@ sp_fetch_list: ; sp_if: - { - Lex->sphead->reset_lex(thd); - if (Lex->main_select_push()) - MYSQL_YYABORT; - } + { Lex->sphead->reset_lex(thd); } expr THEN_SYM { - Lex->pop_select(); //main select LEX *lex= Lex; sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont; @@ -4467,18 +4414,12 @@ case_stmt_specification: ; case_stmt_body: - { - Lex->sphead->reset_lex(thd); /* For expr $2 */ - - if (Lex->main_select_push()) - MYSQL_YYABORT; - } + { Lex->sphead->reset_lex(thd); /* For expr $2 */ } expr { if (Lex->case_stmt_action_expr($2)) MYSQL_YYABORT; - Lex->pop_select(); //main select if (Lex->sphead->restore_lex(thd)) MYSQL_YYABORT; } @@ -4502,9 +4443,6 @@ simple_when_clause: WHEN_SYM { Lex->sphead->reset_lex(thd); /* For expr $3 */ - - if (Lex->main_select_push()) - MYSQL_YYABORT; } expr { @@ -4513,8 +4451,6 @@ simple_when_clause: LEX *lex= Lex; if (lex->case_stmt_action_when($3, true)) MYSQL_YYABORT; - - lex->pop_select(); //main select /* For expr $3 */ if (lex->sphead->restore_lex(thd)) MYSQL_YYABORT; @@ -4531,17 +4467,12 @@ searched_when_clause: WHEN_SYM { Lex->sphead->reset_lex(thd); /* For expr $3 */ - - if (Lex->main_select_push()) - MYSQL_YYABORT; } expr { LEX *lex= Lex; if (lex->case_stmt_action_when($3, false)) MYSQL_YYABORT; - - lex->pop_select(); //main select /* For expr $3 */ if (lex->sphead->restore_lex(thd)) MYSQL_YYABORT; @@ -4690,7 +4621,6 @@ while_body: LEX *lex= Lex; if (lex->sp_while_loop_expression(thd, $1)) MYSQL_YYABORT; - Lex->pop_select(); //main select pushed before while_body use if (lex->sphead->restore_lex(thd)) MYSQL_YYABORT; } @@ -4703,12 +4633,7 @@ while_body: repeat_body: sp_proc_stmts1 UNTIL_SYM - { - Lex->sphead->reset_lex(thd); - - if (Lex->main_select_push()) - MYSQL_YYABORT; - } + { Lex->sphead->reset_lex(thd); } expr END REPEAT_SYM { LEX *lex= Lex; @@ -4719,8 +4644,6 @@ repeat_body: if (i == NULL || lex->sphead->add_instr(i)) MYSQL_YYABORT; - - lex->pop_select(); //main select if (lex->sphead->restore_lex(thd)) MYSQL_YYABORT; /* We can shortcut the cont_backpatch here */ @@ -4749,12 +4672,8 @@ sp_labeled_control: if (Lex->sp_push_loop_label(thd, &$1)) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); - - if (Lex->main_select_push()) - MYSQL_YYABORT; } while_body pop_sp_loop_label - { } | sp_label FOR_SYM { @@ -4806,13 +4725,9 @@ sp_unlabeled_control: if (Lex->sp_push_loop_empty_label(thd)) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); - - if (Lex->main_select_push()) - MYSQL_YYABORT; } while_body { - // while body pop main select Lex->sp_pop_loop_empty_label(thd); } | FOR_SYM @@ -6907,22 +6822,7 @@ parenthesized_expr: remember_tok_start query_expression { - if (!Lex->expr_allows_subselect || - Lex->sql_command == (int)SQLCOM_PURGE) - { - thd->parse_error(ER_SYNTAX_ERROR, $1); - MYSQL_YYABORT; - } - - // Add the subtree of subquery to the current SELECT_LEX - SELECT_LEX *curr_sel= Lex->select_stack_head(); - DBUG_ASSERT(Lex->current_select == curr_sel); - curr_sel->register_unit($2, &curr_sel->context); - curr_sel->add_statistics($2); - - $$= new (thd->mem_root) - Item_singlerow_subselect(thd, $2->first_select()); - if ($$ == NULL) + if (!($$= Lex->create_item_query_expression(thd, $1, $2))) MYSQL_YYABORT; } | expr @@ -8765,13 +8665,9 @@ checksum: lex->sql_command = SQLCOM_CHECKSUM; /* Will be overridden during execution. */ YYPS->m_lock_type= TL_UNLOCK; - if (Lex->main_select_push()) - MYSQL_YYABORT; } table_list opt_checksum_type - { - Lex->pop_select(); //main select - } + {} ; opt_checksum_type: @@ -8797,8 +8693,6 @@ repair: lex->alter_info.reset(); /* Will be overridden during execution. */ YYPS->m_lock_type= TL_UNLOCK; - if (Lex->main_select_push()) - MYSQL_YYABORT; } repair_table_or_view { @@ -8807,7 +8701,6 @@ repair: lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_repair_table(); if (lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -8836,8 +8729,6 @@ analyze: ANALYZE_SYM opt_no_write_to_binlog table_or_tables { LEX *lex=Lex; - if (lex->main_select_push()) - YYABORT; lex->sql_command = SQLCOM_ANALYZE; lex->no_write_to_binlog= $2; lex->check_opt.init(); @@ -8852,7 +8743,6 @@ analyze: lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_analyze_table(); if (lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -8969,8 +8859,6 @@ check: CHECK_SYM lex->alter_info.reset(); /* Will be overridden during execution. */ YYPS->m_lock_type= TL_UNLOCK; - if (Lex->main_select_push()) - MYSQL_YYABORT; } check_view_or_table { @@ -8981,7 +8869,6 @@ check: CHECK_SYM lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_check_table(); if (lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -9019,8 +8906,6 @@ optimize: lex->alter_info.reset(); /* Will be overridden during execution. */ YYPS->m_lock_type= TL_UNLOCK; - if (Lex->main_select_push()) - MYSQL_YYABORT; } table_list opt_lock_wait_timeout { @@ -9029,7 +8914,6 @@ optimize: lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_optimize_table(); if (lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -9043,13 +8927,9 @@ rename: RENAME table_or_tables { Lex->sql_command= SQLCOM_RENAME_TABLE; - if (Lex->main_select_push()) - MYSQL_YYABORT; } table_to_table_list - { - Lex->pop_select(); //main select - } + {} | RENAME USER_SYM clear_privileges rename_list { Lex->sql_command = SQLCOM_RENAME_USER; @@ -9143,13 +9023,9 @@ preload: LEX *lex=Lex; lex->sql_command=SQLCOM_PRELOAD_KEYS; lex->alter_info.reset(); - if (Lex->main_select_push()) - MYSQL_YYABORT; } preload_list_or_parts - { - Lex->pop_select(); //main select - } + {} ; preload_list_or_parts: @@ -9534,6 +9410,7 @@ query_expression: } ; + subselect: remember_tok_start query_expression @@ -10338,7 +10215,21 @@ column_default_non_parenthesized_expr: | param_marker { $$= $1; } | variable | sum_expr + { + if (!Lex->select_stack_top) + { + my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0)); + MYSQL_YYABORT; + } + } | window_func_expr + { + if (!Lex->select_stack_top) + { + my_error(ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION, MYF(0)); + MYSQL_YYABORT; + } + } | inverse_distribution_function | ROW_SYM '(' expr ',' expr_list ')' { @@ -11462,7 +11353,7 @@ sum_expr: SELECT_LEX *sel= Select; sel->in_sum_expr--; $$= new (thd->mem_root) - Item_func_group_concat(thd, Lex->current_context(), + Item_func_group_concat(thd, Lex->current_context_or_default(), $3, $5, sel->gorder_list, $7, $8, sel->select_limit, @@ -13166,15 +13057,10 @@ do: LEX *lex=Lex; lex->sql_command = SQLCOM_DO; mysql_init_select(lex); - if (Lex->main_select_push()) - MYSQL_YYABORT; } expr_list { Lex->insert_list= $3; - Lex->pop_select(); //main select - if (Lex->check_main_unit_semantics()) - MYSQL_YYABORT; } ; @@ -13316,7 +13202,8 @@ table_list: table_name: table_ident { - if (!Select->add_table_to_list(thd, $1, NULL, + if (!thd->lex->current_select_or_default()-> + add_table_to_list(thd, $1, NULL, TL_OPTION_UPDATING, YYPS->m_lock_type, YYPS->m_mdl_type)) @@ -13732,7 +13619,6 @@ delete_part2: | HISTORY_SYM delete_single_table opt_delete_system_time { Lex->last_table()->vers_conditions= Lex->vers_conditions; - Lex->pop_select(); //main select } ; @@ -13859,8 +13745,6 @@ truncate: { LEX* lex= Lex; lex->sql_command= SQLCOM_TRUNCATE; - if (lex->main_select_push()) - MYSQL_YYABORT; lex->alter_info.reset(); lex->builtin_select.options= 0; lex->builtin_select.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED; @@ -13875,7 +13759,6 @@ truncate: lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table(); if (lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -14679,13 +14562,9 @@ purge: LEX *lex=Lex; lex->type=0; lex->sql_command = SQLCOM_PURGE; - if (lex->main_select_push()) - MYSQL_YYABORT; } purge_options - { - Lex->pop_select(); //main select - } + {} ; purge_options: @@ -14714,8 +14593,6 @@ kill: KILL_SYM { LEX *lex=Lex; - if (lex->main_select_push()) - YYABORT; lex->value_list.empty(); lex->users_list.empty(); lex->sql_command= SQLCOM_KILL; @@ -14724,7 +14601,6 @@ kill: kill_type kill_option kill_expr { Lex->kill_signal= (killed_state) ($3 | $4); - Lex->pop_select(); //main select } ; @@ -16544,13 +16420,9 @@ lock: if (lex->sphead) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "LOCK")); lex->sql_command= SQLCOM_LOCK_TABLES; - if (Lex->main_select_push()) - MYSQL_YYABORT; } table_lock_list opt_lock_wait_timeout - { - Lex->pop_select(); //main select - } + {} ; opt_lock_wait_timeout: @@ -16615,13 +16487,9 @@ unlock: if (lex->sphead) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "UNLOCK")); lex->sql_command= SQLCOM_UNLOCK_TABLES; - if (Lex->main_select_push()) - MYSQL_YYABORT; } table_or_tables - { - Lex->pop_select(); //main select - } + {} ; /* diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 7dd065d59ab..069fa0ae615 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -1640,22 +1640,14 @@ deallocate_or_drop: ; prepare: - PREPARE_SYM - { - if (Lex->main_select_push()) - MYSQL_YYABORT; - } - ident FROM prepare_src + PREPARE_SYM ident FROM prepare_src { LEX *lex= thd->lex; if (lex->table_or_sp_used()) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "PREPARE..FROM")); - if (Lex->check_main_unit_semantics()) - MYSQL_YYABORT; lex->sql_command= SQLCOM_PREPARE; - lex->prepared_stmt_name= $3; - Lex->pop_select(); //main select + lex->prepared_stmt_name= $2; } ; @@ -1674,21 +1666,10 @@ execute: LEX *lex= thd->lex; lex->sql_command= SQLCOM_EXECUTE; lex->prepared_stmt_name= $2; - if (Lex->main_select_push()) - MYSQL_YYABORT; } execute_using - { - Lex->pop_select(); //main select - if (Lex->check_main_unit_semantics()) - MYSQL_YYABORT; - } - | EXECUTE_SYM IMMEDIATE_SYM - { - if (Lex->main_select_push()) - MYSQL_YYABORT; - } - prepare_src + {} + | EXECUTE_SYM IMMEDIATE_SYM prepare_src { if (Lex->table_or_sp_used()) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), @@ -1696,11 +1677,7 @@ execute: Lex->sql_command= SQLCOM_EXECUTE_IMMEDIATE; } execute_using - { - Lex->pop_select(); //main select - if (Lex->check_main_unit_semantics()) - MYSQL_YYABORT; - } + {} ; execute_using: @@ -2952,13 +2929,8 @@ call: { if (Lex->call_statement_start(thd, $2)) MYSQL_YYABORT; - if (Lex->main_select_push()) - MYSQL_YYABORT; - } - opt_sp_cparam_list - { - Lex->pop_select(); //main select } + opt_sp_cparam_list {} ; /* CALL parameters */ @@ -3488,16 +3460,10 @@ raise_stmt: ; signal_stmt: - SIGNAL_SYM + SIGNAL_SYM signal_value opt_set_signal_information { - if (Lex->main_select_push()) - YYABORT; - } - signal_value opt_set_signal_information - { - if (Lex->add_signal_statement(thd, $3)) + if (Lex->add_signal_statement(thd, $2)) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -3623,14 +3589,9 @@ resignal_stmt: ; get_diagnostics: - GET_SYM which_area DIAGNOSTICS_SYM + GET_SYM which_area DIAGNOSTICS_SYM diagnostics_information { - if (Lex->main_select_push()) - YYABORT; - } - diagnostics_information - { - Diagnostics_information *info= $5; + Diagnostics_information *info= $4; info->set_which_da($2); @@ -3639,7 +3600,6 @@ get_diagnostics: if (Lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -3820,26 +3780,8 @@ sp_decl_idents: sp_opt_default: /* Empty */ { $$ = NULL; } - | DEFAULT - { - if (Lex->main_select_push()) - MYSQL_YYABORT; - } - expr - { - Lex->pop_select(); //main select - $$ = $3; - } - | SET_VAR - { - if (Lex->main_select_push()) - MYSQL_YYABORT; - } - expr - { - Lex->pop_select(); //main select - $$ = $3; - } + | DEFAULT expr { $$ = $2; } + | SET_VAR expr { $$ = $2; } ; sp_proc_stmt: @@ -3956,15 +3898,10 @@ sp_proc_stmt_statement: sp_proc_stmt_return: RETURN_SYM - { - Lex->sphead->reset_lex(thd); - if (Lex->main_select_push()) - MYSQL_YYABORT; - } + { Lex->sphead->reset_lex(thd); } expr { LEX *lex= Lex; - lex->pop_select(); //main select sp_head *sp= lex->sphead; if (sp->m_handler->add_instr_freturn(thd, sp, lex->spcont, $3, lex) || @@ -4090,8 +4027,6 @@ assignment_source_expr: { DBUG_ASSERT(thd->free_list == NULL); Lex->sphead->reset_lex(thd, $1); - if (Lex->main_select_push()) - MYSQL_YYABORT; } expr { @@ -4100,7 +4035,6 @@ assignment_source_expr: $$->sp_lex_in_use= true; $$->set_item_and_free_list($3, thd->free_list); thd->free_list= NULL; - Lex->pop_select(); //main select if ($$->sphead->restore_lex(thd)) MYSQL_YYABORT; } @@ -4110,6 +4044,7 @@ for_loop_bound_expr: assignment_source_lex { Lex->sphead->reset_lex(thd, $1); + Lex->current_select->parsing_place= FOR_LOOP_BOUND; } expr { @@ -4119,6 +4054,7 @@ for_loop_bound_expr: $$->set_item_and_free_list($3, NULL); if ($$->sphead->restore_lex(thd)) MYSQL_YYABORT; + Lex->current_select->parsing_place= NO_MATTER; } ; @@ -4221,14 +4157,9 @@ sp_fetch_list: ; sp_if: - { - Lex->sphead->reset_lex(thd); - if (Lex->main_select_push()) - MYSQL_YYABORT; - } + { Lex->sphead->reset_lex(thd); } expr THEN_SYM { - Lex->pop_select(); //main select LEX *lex= Lex; sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont; @@ -4340,18 +4271,12 @@ case_stmt_specification: ; case_stmt_body: - { - Lex->sphead->reset_lex(thd); /* For expr $2 */ - - if (Lex->main_select_push()) - MYSQL_YYABORT; - } + { Lex->sphead->reset_lex(thd); /* For expr $2 */ } expr { if (Lex->case_stmt_action_expr($2)) MYSQL_YYABORT; - Lex->pop_select(); //main select if (Lex->sphead->restore_lex(thd)) MYSQL_YYABORT; } @@ -4375,9 +4300,6 @@ simple_when_clause: WHEN_SYM { Lex->sphead->reset_lex(thd); /* For expr $3 */ - - if (Lex->main_select_push()) - MYSQL_YYABORT; } expr { @@ -4386,8 +4308,6 @@ simple_when_clause: LEX *lex= Lex; if (lex->case_stmt_action_when($3, true)) MYSQL_YYABORT; - - lex->pop_select(); //main select /* For expr $3 */ if (lex->sphead->restore_lex(thd)) MYSQL_YYABORT; @@ -4404,17 +4324,12 @@ searched_when_clause: WHEN_SYM { Lex->sphead->reset_lex(thd); /* For expr $3 */ - - if (Lex->main_select_push()) - MYSQL_YYABORT; } expr { LEX *lex= Lex; if (lex->case_stmt_action_when($3, false)) MYSQL_YYABORT; - - lex->pop_select(); //main select /* For expr $3 */ if (lex->sphead->restore_lex(thd)) MYSQL_YYABORT; @@ -4654,7 +4569,6 @@ while_body: LEX *lex= Lex; if (lex->sp_while_loop_expression(thd, $1)) MYSQL_YYABORT; - Lex->pop_select(); //main select pushed before while_body use if (lex->sphead->restore_lex(thd)) MYSQL_YYABORT; } @@ -4667,12 +4581,7 @@ while_body: repeat_body: sp_proc_stmts1 UNTIL_SYM - { - Lex->sphead->reset_lex(thd); - - if (Lex->main_select_push()) - MYSQL_YYABORT; - } + { Lex->sphead->reset_lex(thd); } expr END REPEAT_SYM { LEX *lex= Lex; @@ -4683,8 +4592,6 @@ repeat_body: if (i == NULL || lex->sphead->add_instr(i)) MYSQL_YYABORT; - - lex->pop_select(); //main select if (lex->sphead->restore_lex(thd)) MYSQL_YYABORT; /* We can shortcut the cont_backpatch here */ @@ -4713,12 +4620,8 @@ sp_labeled_control: if (Lex->sp_push_loop_label(thd, &$1)) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); - - if (Lex->main_select_push()) - MYSQL_YYABORT; } while_body pop_sp_loop_label - { } | labels_declaration_oracle FOR_SYM { @@ -4770,13 +4673,9 @@ sp_unlabeled_control: if (Lex->sp_push_loop_empty_label(thd)) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); - - if (Lex->main_select_push()) - MYSQL_YYABORT; } while_body { - // while body pop main select Lex->sp_pop_loop_empty_label(thd); } | FOR_SYM @@ -6687,22 +6586,7 @@ parenthesized_expr: remember_tok_start query_expression { - if (!Lex->expr_allows_subselect || - Lex->sql_command == (int)SQLCOM_PURGE) - { - thd->parse_error(ER_SYNTAX_ERROR, $1); - MYSQL_YYABORT; - } - - // Add the subtree of subquery to the current SELECT_LEX - SELECT_LEX *curr_sel= Lex->select_stack_head(); - DBUG_ASSERT(Lex->current_select == curr_sel); - curr_sel->register_unit($2, &curr_sel->context); - curr_sel->add_statistics($2); - - $$= new (thd->mem_root) - Item_singlerow_subselect(thd, $2->first_select()); - if ($$ == NULL) + if (!($$= Lex->create_item_query_expression(thd, $1, $2))) MYSQL_YYABORT; } | expr @@ -8599,13 +8483,9 @@ checksum: lex->sql_command = SQLCOM_CHECKSUM; /* Will be overridden during execution. */ YYPS->m_lock_type= TL_UNLOCK; - if (Lex->main_select_push()) - MYSQL_YYABORT; } table_list opt_checksum_type - { - Lex->pop_select(); //main select - } + {} ; opt_checksum_type: @@ -8631,8 +8511,6 @@ repair: lex->alter_info.reset(); /* Will be overridden during execution. */ YYPS->m_lock_type= TL_UNLOCK; - if (Lex->main_select_push()) - MYSQL_YYABORT; } repair_table_or_view { @@ -8641,7 +8519,6 @@ repair: lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_repair_table(); if (lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -8670,8 +8547,6 @@ analyze: ANALYZE_SYM opt_no_write_to_binlog table_or_tables { LEX *lex=Lex; - if (lex->main_select_push()) - YYABORT; lex->sql_command = SQLCOM_ANALYZE; lex->no_write_to_binlog= $2; lex->check_opt.init(); @@ -8686,7 +8561,6 @@ analyze: lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_analyze_table(); if (lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -8803,8 +8677,6 @@ check: CHECK_SYM lex->alter_info.reset(); /* Will be overridden during execution. */ YYPS->m_lock_type= TL_UNLOCK; - if (Lex->main_select_push()) - MYSQL_YYABORT; } check_view_or_table { @@ -8815,7 +8687,6 @@ check: CHECK_SYM lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_check_table(); if (lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -8853,8 +8724,6 @@ optimize: lex->alter_info.reset(); /* Will be overridden during execution. */ YYPS->m_lock_type= TL_UNLOCK; - if (Lex->main_select_push()) - MYSQL_YYABORT; } table_list opt_lock_wait_timeout { @@ -8863,7 +8732,6 @@ optimize: lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_optimize_table(); if (lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } ; @@ -8877,13 +8745,9 @@ rename: RENAME table_or_tables { Lex->sql_command= SQLCOM_RENAME_TABLE; - if (Lex->main_select_push()) - MYSQL_YYABORT; } table_to_table_list - { - Lex->pop_select(); //main select - } + {} | RENAME USER_SYM clear_privileges rename_list { Lex->sql_command = SQLCOM_RENAME_USER; @@ -8977,13 +8841,9 @@ preload: LEX *lex=Lex; lex->sql_command=SQLCOM_PRELOAD_KEYS; lex->alter_info.reset(); - if (Lex->main_select_push()) - MYSQL_YYABORT; } preload_list_or_parts - { - Lex->pop_select(); //main select - } + {} ; preload_list_or_parts: @@ -10160,7 +10020,21 @@ column_default_non_parenthesized_expr: | param_marker { $$= $1; } | variable | sum_expr + { + if (!Lex->select_stack_top) + { + my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0)); + MYSQL_YYABORT; + } + } | window_func_expr + { + if (!Lex->select_stack_top) + { + my_error(ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION, MYF(0)); + MYSQL_YYABORT; + } + } | inverse_distribution_function | ROW_SYM '(' expr ',' expr_list ')' { @@ -11283,7 +11157,7 @@ sum_expr: SELECT_LEX *sel= Select; sel->in_sum_expr--; $$= new (thd->mem_root) - Item_func_group_concat(thd, Lex->current_context(), + Item_func_group_concat(thd, Lex->current_context_or_default(), $3, $5, sel->gorder_list, $7, $8, sel->select_limit, @@ -12996,15 +12870,10 @@ do: LEX *lex=Lex; lex->sql_command = SQLCOM_DO; mysql_init_select(lex); - if (Lex->main_select_push()) - MYSQL_YYABORT; } expr_list { Lex->insert_list= $3; - Lex->pop_select(); //main select - if (Lex->check_main_unit_semantics()) - MYSQL_YYABORT; } ; @@ -13688,7 +13557,6 @@ truncate: lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table(); if (lex->m_sql_cmd == NULL) MYSQL_YYABORT; - Lex->pop_select(); //main select } opt_truncate_table_storage_clause { } ; @@ -14481,13 +14349,9 @@ purge: LEX *lex=Lex; lex->type=0; lex->sql_command = SQLCOM_PURGE; - if (lex->main_select_push()) - MYSQL_YYABORT; } purge_options - { - Lex->pop_select(); //main select - } + {} ; purge_options: @@ -14505,8 +14369,6 @@ purge_option: lex->value_list.empty(); lex->value_list.push_front($2, thd->mem_root); lex->sql_command= SQLCOM_PURGE_BEFORE; - if (Lex->check_main_unit_semantics()) - MYSQL_YYABORT; } ; @@ -14516,8 +14378,6 @@ kill: KILL_SYM { LEX *lex=Lex; - if (lex->main_select_push()) - YYABORT; lex->value_list.empty(); lex->users_list.empty(); lex->sql_command= SQLCOM_KILL; @@ -14526,7 +14386,6 @@ kill: kill_type kill_option kill_expr { Lex->kill_signal= (killed_state) ($3 | $4); - Lex->pop_select(); //main select } ; @@ -16479,13 +16338,9 @@ lock: if (lex->sphead) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "LOCK")); lex->sql_command= SQLCOM_LOCK_TABLES; - if (Lex->main_select_push()) - MYSQL_YYABORT; } table_lock_list opt_lock_wait_timeout - { - Lex->pop_select(); //main select - } + {} ; opt_lock_wait_timeout: @@ -16550,13 +16405,9 @@ unlock: if (lex->sphead) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "UNLOCK")); lex->sql_command= SQLCOM_UNLOCK_TABLES; - if (Lex->main_select_push()) - MYSQL_YYABORT; } table_or_tables - { - Lex->pop_select(); //main select - } + {} ; /*
participants (1)
-
Oleksandr Byelkin