[Commits] 9e3d3b772b9: # Das ist eine Kombination aus 91 Commits.
revision-id: 9e3d3b772b94f5591b963f4a837feeab3c9378a3 (mariadb-10.3.1-46-g9e3d3b772b9) parent(s): 4a32e2395e1ff6cf7274d0567282b1747031108b author: Oleksandr Byelkin committer: Oleksandr Byelkin timestamp: 2018-04-03 09:58:06 +0200 message: # Das ist eine Kombination aus 91 Commits. # Das ist die erste Commit-Beschreibung: Start point for attempts to solve subselect/dirived problem # Die Commit-Beschreibung #2 wird ausgelassen: # ccc # Die Commit-Beschreibung #3 wird ausgelassen: # cccc # Die Commit-Beschreibung #4 wird ausgelassen: # ccc 2018-02-09 s # Die Commit-Beschreibung #5 wird ausgelassen: # Intermediate commit with added query_expression. # Die Commit-Beschreibung #6 wird ausgelassen: # ccc 2018-02-12 sanja # Die Commit-Beschreibung #7 wird ausgelassen: # 2018-02-12 sanja more # Die Commit-Beschreibung #8 wird ausgelassen: # 2018-02-12 sanja even more # Die Commit-Beschreibung #9 wird ausgelassen: # mmmm # Die Commit-Beschreibung #10 wird ausgelassen: # Alias pass 2012-02-13 sanja (to be continue) # Die Commit-Beschreibung #11 wird ausgelassen: # 2018-02-13 fix cindition # Die Commit-Beschreibung #12 wird ausgelassen: # 2018-02-13 sanja # Die Commit-Beschreibung #13 wird ausgelassen: # fixed options 2018-02-14 sanja # Die Commit-Beschreibung #14 wird ausgelassen: # fixed EXPLAIN # select.test passed # 2012-02-14 Sanja # Die Commit-Beschreibung #15 wird ausgelassen: # fixed unit operation check # 2018-02-14 sanja # Die Commit-Beschreibung #16 wird ausgelassen: # Added opt_order_clause, opt_limit_clause, opt_select_lock_type # to query_specification # Die Commit-Beschreibung #17 wird ausgelassen: # Fixed a problem with parsing ORDER BY. # Die Commit-Beschreibung #18 wird ausgelassen: # 2012-02-15 sanja (order & co) # Die Commit-Beschreibung #19 wird ausgelassen: # MDEV-11953: New variant of the grammar. # Die Commit-Beschreibung #20 wird ausgelassen: # new gramatic fixed # # aliases + # select - # subselect - # # 2018-02-16 sanja # Die Commit-Beschreibung #21 wird ausgelassen: # select passes # 2018-02-16 sanja # Die Commit-Beschreibung #22 wird ausgelassen: # Fix of GLOBAL ORDER BY table name check; # Fix of linking third and more SELECTs to union. # # 2012-02-16 sanja # Die Commit-Beschreibung #23 wird ausgelassen: # Another grammar for query_expression # Die Commit-Beschreibung #24 wird ausgelassen: # Changed the rule for table_primary_derived # Die Commit-Beschreibung #25 wird ausgelassen: # some fixes # 2018-02-19 sanja # Die Commit-Beschreibung #26 wird ausgelassen: # fixed check. # added union. # 2018-02-19 sanja # Die Commit-Beschreibung #27 wird ausgelassen: # more changes # Die Commit-Beschreibung #28 wird ausgelassen: # Fixed a conflict for create table statements. # Die Commit-Beschreibung #29 wird ausgelassen: # Fixed a bug in the previous fix. # Die Commit-Beschreibung #30 wird ausgelassen: # Removed %prec # Die Commit-Beschreibung #31 wird ausgelassen: # 2018-02-22 INTO # Die Commit-Beschreibung #32 wird ausgelassen: # more into fix # Die Commit-Beschreibung #33 wird ausgelassen: # Fixed a conflict in insert/replace statement in the same way as # for ctreate table statement. # Corrected semantics for derived tables when they are specified by unions. # Die Commit-Beschreibung #34 wird ausgelassen: # more check of into # Die Commit-Beschreibung #35 wird ausgelassen: # fix of SP/functions/triggers # Die Commit-Beschreibung #36 wird ausgelassen: # Fixed a problem with UNIONs. # Die Commit-Beschreibung #37 wird ausgelassen: # better solution with INTO # Die Commit-Beschreibung #38 wird ausgelassen: # return tests # Die Commit-Beschreibung #39 wird ausgelassen: # fix of test # Die Commit-Beschreibung #40 wird ausgelassen: # fix place # Die Commit-Beschreibung #41 wird ausgelassen: # Fixed some grammar problems for insert. # Die Commit-Beschreibung #42 wird ausgelassen: # Fixed a problem with DELETE ... ORDER BY. # Die Commit-Beschreibung #43 wird ausgelassen: # Fixed a problem with privileges. # Die Commit-Beschreibung #44 wird ausgelassen: # fix create # Die Commit-Beschreibung #45 wird ausgelassen: # Fixed some problems for CTE. # Die Commit-Beschreibung #46 wird ausgelassen: # fix for second CTE parsing # Die Commit-Beschreibung #47 wird ausgelassen: # fixed SP # Die Commit-Beschreibung #48 wird ausgelassen: # More tests fix # Die Commit-Beschreibung #49 wird ausgelassen: # fix purge # Die Commit-Beschreibung #50 wird ausgelassen: # Fixed a problem for CTE. # Die Commit-Beschreibung #51 wird ausgelassen: # vix problem view with CTE # Die Commit-Beschreibung #52 wird ausgelassen: # Fixed another problem with CTE. # Die Commit-Beschreibung #53 wird ausgelassen: # Fixed the previous incomplete commit. # Die Commit-Beschreibung #54 wird ausgelassen: # Fixed a problem with INSERT INTO SET. # Die Commit-Beschreibung #55 wird ausgelassen: # fix numbering with "WITH" # Die Commit-Beschreibung #56 wird ausgelassen: # fix of execute immidiate # Die Commit-Beschreibung #57 wird ausgelassen: # ps fixed # Die Commit-Beschreibung #58 wird ausgelassen: # fix SP # Die Commit-Beschreibung #59 wird ausgelassen: # fix double brackets in devived # Die Commit-Beschreibung #60 wird ausgelassen: # Fixed all problems with CTEs. # Die Commit-Beschreibung #61 wird ausgelassen: # Fixed a problem with CREATE TABLE. # Die Commit-Beschreibung #62 wird ausgelassen: # Fixed a problem with WF tests. # Die Commit-Beschreibung #63 wird ausgelassen: # fixed sp-cursor # Die Commit-Beschreibung #64 wird ausgelassen: # sp fixed # Die Commit-Beschreibung #65 wird ausgelassen: # CREATE INDEX fixed # Die Commit-Beschreibung #66 wird ausgelassen: # Fixed problems with query_expression_tail and with unions. # Die Commit-Beschreibung #67 wird ausgelassen: # Fixed a problem with INSERT SELECT. # Die Commit-Beschreibung #68 wird ausgelassen: # Fixed a problem with two query expression tails. # Die Commit-Beschreibung #69 wird ausgelassen: # Fixed a problem with fulltext_order_by.test # Die Commit-Beschreibung #70 wird ausgelassen: # port from 10.3 correct select numbering # fixed sp-lock # Die Commit-Beschreibung #71 wird ausgelassen: # erro message fix # Die Commit-Beschreibung #72 wird ausgelassen: # Fixed problems with LOAD DATA, CREATE merge table and explicit # partition pruning. # Die Commit-Beschreibung #73 wird ausgelassen: # qury cache fixed # # oracle parser commented out # Die Commit-Beschreibung #74 wird ausgelassen: # Fixed problems with locks and with SIGNAL. # Die Commit-Beschreibung #75 wird ausgelassen: # Fixed problems with SHOW WARNING. # Temporarily changed settings with sql_mode='oracle'. # Die Commit-Beschreibung #76 wird ausgelassen: # fixed all query cache bug # Die Commit-Beschreibung #77 wird ausgelassen: # fixed test # Die Commit-Beschreibung #78 wird ausgelassen: # partial fix # Die Commit-Beschreibung #79 wird ausgelassen: # Fixed the remaining problems with INTERSECT. # Die Commit-Beschreibung #80 wird ausgelassen: # Fixed problems with KILL. # Die Commit-Beschreibung #81 wird ausgelassen: # Fix problems with GET DIAGNOSTICS. # Die Commit-Beschreibung #82 wird ausgelassen: # Fixed problems with FLUSH TABLE LOCK. # Die Commit-Beschreibung #83 wird ausgelassen: # Fixed func_analyse.test # Die Commit-Beschreibung #84 wird ausgelassen: # Temporarily changed a test case in events_bugs.test to be able # to run it without the grammar rules for oracle. # Die Commit-Beschreibung #85 wird ausgelassen: # Fixed problems with HANDLER and opt_limit_clause. # Die Commit-Beschreibung #86 wird ausgelassen: # Fixed a problem with compound.test. # Die Commit-Beschreibung #87 wird ausgelassen: # Fixed a problem with create_drop_binlog.test # Die Commit-Beschreibung #88 wird ausgelassen: # Fixed problems with ANALYZE. # Die Commit-Beschreibung #89 wird ausgelassen: # Adjusted a test case for new syntax. # Die Commit-Beschreibung #90 wird ausgelassen: # fix select numbering # Die Commit-Beschreibung #91 wird ausgelassen: # Fixed numbering for selects. --- mysql-test/include/deadlock.inc | 2 +- mysql-test/r/cte_nonrecursive.result | 28 +- mysql-test/r/deadlock_innodb.result | 2 +- mysql-test/r/derived.result | 2 +- mysql-test/r/events_bugs.result | 1 - mysql-test/r/except.result | 8 +- mysql-test/r/fulltext_order_by.result | 4 +- mysql-test/r/func_analyse.result | 22 +- mysql-test/r/intersect.result | 22 +- mysql-test/r/join.result | 2 +- mysql-test/r/join_nested.result | 2 +- mysql-test/r/join_nested_jcl6.result | 2 +- mysql-test/r/parser.result | 55 +- mysql-test/r/query_cache.result | 37 +- mysql-test/r/show_check.result | 4 +- mysql-test/r/sp-error.result | 10 +- mysql-test/r/sp.result | 137 +- mysql-test/r/sql_mode.result | 5 +- mysql-test/r/subselect.result | 141 +- mysql-test/r/subselect_mat.result | 4 +- mysql-test/r/subselect_no_exists_to_in.result | 141 +- mysql-test/r/subselect_no_mat.result | 141 +- mysql-test/r/subselect_no_opts.result | 141 +- mysql-test/r/subselect_no_scache.result | 141 +- mysql-test/r/subselect_no_semijoin.result | 141 +- mysql-test/r/subselect_sj.result | 2 +- mysql-test/r/subselect_sj_jcl6.result | 2 +- mysql-test/r/subselect_sj_mat.result | 4 +- mysql-test/r/test.result | 114 ++ mysql-test/r/union.result | 21 +- mysql-test/r/view.result | 104 +- mysql-test/t/events_bugs.test | 2 +- mysql-test/t/except.test | 4 +- mysql-test/t/func_analyse.test | 17 +- mysql-test/t/intersect.test | 4 +- mysql-test/t/join_nested.test | 2 +- mysql-test/t/parser.test | 55 +- mysql-test/t/query_cache.test | 31 +- mysql-test/t/show_check.test | 2 +- mysql-test/t/sp-error.test | 10 +- mysql-test/t/sp.test | 176 +- mysql-test/t/sql_mode.test | 5 +- mysql-test/t/subselect.test | 94 +- mysql-test/t/subselect_sj.test | 2 +- mysql-test/t/subselect_sj_mat.test | 4 +- mysql-test/t/test.test | 26 + mysql-test/t/union.test | 18 +- mysql-test/t/view.test | 104 +- sql/events.cc | 9 +- sql/item.cc | 18 +- sql/item_subselect.cc | 18 +- sql/log_event.cc | 6 +- sql/opt_range.cc | 2 +- sql/opt_table_elimination.cc | 4 +- sql/set_var.cc | 2 +- sql/sp.cc | 1 - sql/sp_head.cc | 37 +- sql/sp_head.h | 8 +- sql/sp_rcontext.cc | 14 +- sql/sql_admin.cc | 18 +- sql/sql_alter.cc | 4 +- sql/sql_base.cc | 8 +- sql/sql_base.h | 6 +- sql/sql_cache.cc | 8 +- sql/sql_class.cc | 6 +- sql/sql_class.h | 25 +- sql/sql_cte.cc | 12 +- sql/sql_cte.h | 30 +- sql/sql_delete.cc | 32 +- sql/sql_derived.cc | 3 +- sql/sql_do.cc | 2 +- sql/sql_error.cc | 2 +- sql/sql_explain.h | 6 + sql/sql_help.cc | 11 +- sql/sql_insert.cc | 40 +- sql/sql_lex.cc | 940 ++++++++++- sql/sql_lex.h | 266 ++- sql/sql_load.cc | 9 +- sql/sql_parse.cc | 105 +- sql/sql_partition.cc | 3 +- sql/sql_partition_admin.cc | 4 +- sql/sql_prepare.cc | 70 +- sql/sql_priv.h | 4 + sql/sql_profile.cc | 4 +- sql/sql_select.cc | 57 +- sql/sql_sequence.cc | 4 +- sql/sql_show.cc | 27 +- sql/sql_table.cc | 6 +- sql/sql_trigger.cc | 7 +- sql/sql_truncate.cc | 2 +- sql/sql_union.cc | 2 +- sql/sql_update.cc | 30 +- sql/sql_view.cc | 53 +- sql/sql_yacc.yy | 2206 ++++++++++++++----------- sql/sql_yacc_ora.yy | 150 +- sql/structs.h | 53 + sql/table.cc | 30 +- sql/wsrep_mysqld.cc | 4 +- storage/mroonga/ha_mroonga.cpp | 2 +- storage/spider/spd_db_mysql.cc | 2 +- storage/tokudb/tokudb_dir_cmd.cc | 4 +- 101 files changed, 4091 insertions(+), 2283 deletions(-) diff --git a/mysql-test/include/deadlock.inc b/mysql-test/include/deadlock.inc index 2fa61f48624..7ac2a16fc44 100644 --- a/mysql-test/include/deadlock.inc +++ b/mysql-test/include/deadlock.inc @@ -94,7 +94,7 @@ insert into t2 values(0, 0), (1, 20), (2, 30); commit; connection con1; -select a,b from t2 UNION SELECT id, x from t1 FOR UPDATE; +select a,b from t2 UNION (SELECT id, x from t1 FOR UPDATE); select * from t2; select * from t1; diff --git a/mysql-test/r/cte_nonrecursive.result b/mysql-test/r/cte_nonrecursive.result index 2fceebd1971..66051ceb3e2 100644 --- a/mysql-test/r/cte_nonrecursive.result +++ b/mysql-test/r/cte_nonrecursive.result @@ -151,8 +151,8 @@ with t as (select a from t1 where a<5) select * from t2 where c in (select a from t); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 -1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 -3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where explain select * from t2 where c in (select a from (select a from t1 where a<5) as t); @@ -332,8 +332,8 @@ union select * from t where a >= 4; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where -3 UNION t1 ALL NULL NULL NULL NULL 8 Using where -NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL +2 UNION t1 ALL NULL NULL NULL NULL 8 Using where +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL explain select * from (select a from t1 where b >= 'c') as t where t.a < 2 @@ -418,10 +418,10 @@ t2.c in (with t as (select * from t1 where t1.a<5) select t2.c from t2,t where t2.c=t.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 -1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) -2 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where -2 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) explain select t1.a,t1.b from t1,t2 where t1.a>t2.c and @@ -507,9 +507,9 @@ select t.a, count(*) from t1,t where t1.a=t.a group by t.a; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort 1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) -1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 35 func 1 -3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where -3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +1 PRIMARY <subquery4> eq_ref distinct_key distinct_key 35 func 1 +4 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +4 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) explain select t.a, count(*) from t1, @@ -597,8 +597,8 @@ explain select * from v2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where -1 PRIMARY <derived3> ref key0 key0 5 test.t2.c 2 -3 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort +1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2 +2 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort # with clause in the specification of a view that whose definition # table alias for a with table create view v3 as @@ -863,8 +863,8 @@ SELECT * FROM (WITH a AS (SELECT * FROM t1) SELECT 1) AS t1; 1 EXPLAIN SELECT * FROM (WITH a AS (SELECT * FROM t1) SELECT 1) AS t1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY <derived2> system NULL NULL NULL NULL 1 -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +1 PRIMARY <derived3> system NULL NULL NULL NULL 1 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used DROP TABLE t1; # # MDEV-10058: Suspicious EXPLAIN output for a derived table + WITH + joined table diff --git a/mysql-test/r/deadlock_innodb.result b/mysql-test/r/deadlock_innodb.result index af78a6aa9d5..fca0ff6be0c 100644 --- a/mysql-test/r/deadlock_innodb.result +++ b/mysql-test/r/deadlock_innodb.result @@ -72,7 +72,7 @@ insert into t1 values(0, 0), (300, 300); insert into t2 values(0, 0), (1, 20), (2, 30); commit; connection con1; -select a,b from t2 UNION SELECT id, x from t1 FOR UPDATE; +select a,b from t2 UNION (SELECT id, x from t1 FOR UPDATE); a b 0 0 20 1 diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 220fd5a8c74..36b62cf18e9 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -225,7 +225,7 @@ ERROR HY000: The target table t1 of the UPDATE is not updatable delete from (select * from t1); 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 '(select * from t1)' at line 1 insert into (select * from t1) values (5); -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 '(select * from t1) values (5)' at line 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 'select * from t1) values (5)' at line 1 drop table t1; create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1) ); diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index b56912dea7e..5f0217aa5cd 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -729,7 +729,6 @@ DROP USER mysqltest_u1@localhost; drop procedure if exists p; set @old_mode= @@sql_mode; -set @@sql_mode= cast(pow(2,32)-1 as unsigned integer); create event e1 on schedule every 1 day do select 1; select @@sql_mode into @full_mode; set @@sql_mode= @old_mode; diff --git a/mysql-test/r/except.result b/mysql-test/r/except.result index fdaa625ea65..5d118ede7d2 100644 --- a/mysql-test/r/except.result +++ b/mysql-test/r/except.result @@ -24,7 +24,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 3 EXCEPT t2 ALL NULL NULL NULL NULL 2 100.00 NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b` from ((/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) except (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`)) `a` +Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b` from (/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` except (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`)) `a` EXPLAIN format=json (select a,b from t1) except (select c,d from t2); EXPLAIN { @@ -229,7 +229,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 3 EXCEPT t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join) NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b`,`a`.`e` AS `e`,`a`.`f` AS `f` from ((/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t1` join `test`.`t3`) except (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t4`.`g` AS `g`,`test`.`t4`.`h` AS `h` from `test`.`t2` join `test`.`t4`)) `a` +Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b`,`a`.`e` AS `e`,`a`.`f` AS `f` from (/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t1` join `test`.`t3` except (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t4`.`g` AS `g`,`test`.`t4`.`h` AS `h` from `test`.`t2` join `test`.`t4`)) `a` EXPLAIN format=json (select a,b,e,f from t1,t3) except (select c,d,g,h from t2,t4); EXPLAIN { @@ -500,7 +500,7 @@ a (select 1 from dual) except (select 1 from dual); 1 (select 1 from dual into @v) except (select 1 from dual); -ERROR HY000: Incorrect usage of EXCEPT and INTO +ERROR 42000: Incorrect usage/placement of 'INTO' select 1 from dual ORDER BY 1 except select 1 from dual; 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 'except select 1 from dual' at line 1 select 1 as a from dual union all select 1 from dual; @@ -508,7 +508,7 @@ a 1 1 select 1 from dual except all select 1 from dual; -ERROR HY000: Incorrect usage of EXCEPT and ALL +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 'all select 1 from dual' at line 1 create table t1 (a int, b blob, a1 int, b1 blob) engine=MyISAM; create table t2 (c int, d blob, c1 int, d1 blob) engine=MyISAM; insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt"); diff --git a/mysql-test/r/fulltext_order_by.result b/mysql-test/r/fulltext_order_by.result index c2f57c6f9c2..a350a55c75d 100644 --- a/mysql-test/r/fulltext_order_by.result +++ b/mysql-test/r/fulltext_order_by.result @@ -126,7 +126,7 @@ group by a.text, b.id, b.betreff order by match(b.betreff) against ('+abc' in boolean mode) desc; -ERROR 42000: Table 'b' from one of the SELECTs cannot be used in field list +ERROR 42000: Table 'b' from one of the SELECTs cannot be used in ORDER clause select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join @@ -142,7 +142,7 @@ where match(c.beitrag) against ('+abc' in boolean mode) order by match(b.betreff) against ('+abc' in boolean mode) desc; -ERROR 42000: Table 'b' from one of the SELECTs cannot be used in field list +ERROR 42000: Table 'b' from one of the SELECTs cannot be used in ORDER clause select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join diff --git a/mysql-test/r/func_analyse.result b/mysql-test/r/func_analyse.result index 1e78e603bca..68ceb8aed02 100644 --- a/mysql-test/r/func_analyse.result +++ b/mysql-test/r/func_analyse.result @@ -19,7 +19,7 @@ test.t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL create table t2 select * from t1 procedure analyse(); -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 'procedure analyse()' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' drop table t1; EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(); ERROR HY000: Incorrect usage of PROCEDURE and subquery @@ -120,7 +120,7 @@ CREATE TABLE t1(a INT); INSERT INTO t1 VALUES (1),(2); # should not crash CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE(); -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 'PROCEDURE ANALYSE()' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' DROP TABLE t1; End of 5.0 tests # @@ -158,16 +158,24 @@ Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_ ((SELECT 1 FROM DUAL PROCEDURE ANALYSE())); Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype 1 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL +(SELECT 1 FROM DUAL) PROCEDURE ANALYSE(); +Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype +1 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL +((SELECT 1 FROM DUAL)) PROCEDURE ANALYSE(); +Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype +1 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL +create table t1 (a int); SELECT * FROM t1 UNION SELECT * FROM t1 PROCEDURE analyse(); -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 'PROCEDURE analyse()' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' +drop table t1; # # MDEV-10030 sql_yacc.yy: Split table_expression and remove PROCEDURE from create_select, select_paren_derived, select_derived2, query_specification # SELECT * FROM (SELECT * FROM t1 PROCEDURE ANALYSE()); -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 'PROCEDURE ANALYSE())' at line 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 SELECT * FROM t1 NATURAL JOIN (SELECT * FROM t2 PROCEDURE ANALYSE()); -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 'PROCEDURE ANALYSE())' at line 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 SELECT (SELECT 1 FROM t1 PROCEDURE ANALYSE()) FROM t2; -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 'PROCEDURE ANALYSE()) FROM t2' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' SELECT ((SELECT 1 FROM t1 PROCEDURE ANALYSE())) FROM t2; -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 'PROCEDURE ANALYSE())) FROM t2' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' diff --git a/mysql-test/r/intersect.result b/mysql-test/r/intersect.result index 5dfb7fb6875..c32233ec9ec 100644 --- a/mysql-test/r/intersect.result +++ b/mysql-test/r/intersect.result @@ -37,7 +37,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 4 INTERSECT t3 ALL NULL NULL NULL NULL 3 100.00 NULL INTERSECT RESULT <intersect2,3,4> ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b` from ((/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) intersect (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (/* select#4 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `a` +Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b` from (/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` intersect (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (/* select#4 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `a` EXPLAIN format=json (select a,b from t1) intersect (select c,d from t2) intersect (select e,f from t3); EXPLAIN { @@ -278,7 +278,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 3 INTERSECT t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b` from ((/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) intersect (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t3`.`e` AS `e` from `test`.`t2` join `test`.`t3`)) `a` +Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b` from (/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` intersect (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t3`.`e` AS `e` from `test`.`t2` join `test`.`t3`)) `a` EXPLAIN format=json (select a,b from t1) intersect (select c,e from t2,t3); EXPLAIN { @@ -497,7 +497,7 @@ a 1 1 (select 1 from dual into @v) intersect (select 1 from dual); -ERROR HY000: Incorrect usage of INTERSECT and INTO +ERROR 42000: Incorrect usage/placement of 'INTO' select 1 from dual ORDER BY 1 intersect select 1 from dual; 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 'intersect select 1 from dual' at line 1 select 1 as a from dual union all select 1 from dual; @@ -505,7 +505,7 @@ a 1 1 select 1 from dual intersect all select 1 from dual; -ERROR HY000: Incorrect usage of INTERSECT and ALL +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 'all select 1 from dual' at line 1 create table t1 (a int, b blob, a1 int, b1 blob); create table t2 (c int, d blob, c1 int, d1 blob); insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt"); @@ -599,14 +599,14 @@ explain extended (select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -3 UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 +5 UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 -4 INTERSECT t3 ALL NULL NULL NULL NULL 2 100.00 -NULL INTERSECT RESULT <intersect2,4> ALL NULL NULL NULL NULL NULL NULL -5 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used -NULL UNION RESULT <union1,3,5> ALL NULL NULL NULL NULL NULL NULL +3 INTERSECT t3 ALL NULL NULL NULL NULL 2 100.00 +NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL NULL +4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,5,4> ALL NULL NULL NULL NULL NULL NULL Warnings: -Note 1003 (/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union /* select#3 */ select `__3`.`c` AS `c`,`__3`.`d` AS `d` from ((/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (/* select#4 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__3` union (/* select#5 */ select 4 AS `4`,4 AS `4`) +Note 1003 (/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union /* select#5 */ select `__5`.`c` AS `c`,`__5`.`d` AS `d` from ((/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (/* select#3 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__5` union (/* select#4 */ select 4 AS `4`,4 AS `4`) (select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4); e f 3 3 @@ -686,6 +686,6 @@ a b drop procedure p1; show create view v1; View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS (select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union select `__3`.`c` AS `c`,`__3`.`d` AS `d` from ((select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__3` union (select 4 AS `4`,4 AS `4`) latin1 latin1_swedish_ci +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS (select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union select `__6`.`c` AS `c`,`__6`.`d` AS `d` from (select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` intersect (select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__6` union (select 4 AS `4`,4 AS `4`) latin1 latin1_swedish_ci drop view v1; drop tables t1,t2,t3; diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index df48dbba605..a5d207d0364 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -1483,7 +1483,7 @@ DROP TABLE t1,t2,t3,t4,t5; # MDEV-4752: Segfault during parsing of illegal query # SELECT * FROM t5 JOIN (t1 JOIN t2 UNION SELECT * FROM t3 JOIN t4); -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 'SELECT * FROM t3 JOIN t4)' at line 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 'UNION SELECT * FROM t3 JOIN t4)' at line 1 # # MDEV-4959: join of const table with NULL fields # diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result index 917a31e2a79..869443709b5 100644 --- a/mysql-test/r/join_nested.result +++ b/mysql-test/r/join_nested.result @@ -1150,7 +1150,7 @@ a b a b 4 2 2 2 5 3 NULL NULL SELECT t2.a,t2.b,t3.a,t3.b -FROM t2 LEFT JOIN (t3) ON t2.b=t3.b +FROM t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL); a b a b 4 2 1 2 diff --git a/mysql-test/r/join_nested_jcl6.result b/mysql-test/r/join_nested_jcl6.result index 1ffd94547cc..8e949357977 100644 --- a/mysql-test/r/join_nested_jcl6.result +++ b/mysql-test/r/join_nested_jcl6.result @@ -1161,7 +1161,7 @@ a b a b 4 2 2 2 5 3 NULL NULL SELECT t2.a,t2.b,t3.a,t3.b -FROM t2 LEFT JOIN (t3) ON t2.b=t3.b +FROM t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL); a b a b 4 2 1 2 diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index f197fbe6a19..621115751e3 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -705,6 +705,9 @@ FOR UPDATE; 1 1 SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 +PROCEDURE ANALYSE(); +ERROR HY000: Can't use ORDER clause with this procedure +SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 PROCEDURE ANALYSE() FOR UPDATE; ERROR HY000: Can't use ORDER clause with this procedure SELECT 1 FROM @@ -715,7 +718,7 @@ FOR UPDATE) a; SELECT 1 FROM (SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 PROCEDURE ANALYSE() FOR UPDATE) 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 'PROCEDURE ANALYSE() FOR UPDATE) a' at line 3 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' SELECT 1 FROM t1 WHERE EXISTS(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 FOR UPDATE); @@ -723,7 +726,7 @@ FOR UPDATE); SELECT 1 FROM t1 WHERE EXISTS(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 PROCEDURE ANALYSE() FOR UPDATE); -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 'PROCEDURE ANALYSE() FOR UPDATE)' at line 3 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' SELECT 1 FROM t1 UNION SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 @@ -734,7 +737,7 @@ SELECT 1 FROM t1 UNION SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 PROCEDURE ANALYSE() FOR UPDATE; -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 'PROCEDURE ANALYSE() FOR UPDATE' at line 4 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' SELECT 1 FROM DUAL PROCEDURE ANALYSE() UNION SELECT 1 FROM t1; @@ -750,11 +753,11 @@ FOR UPDATE); UNION (SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 PROCEDURE ANALYSE() FOR UPDATE); -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 'PROCEDURE ANALYSE() FOR UPDATE)' at line 4 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' # "FOR UPDATE" tests SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1; 1 -SELECT 1 FROM t1 FOR UPDATE UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1; +(SELECT 1 FROM t1 FOR UPDATE) UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1; 1 SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 FOR UPDATE; 1 @@ -769,10 +772,10 @@ Warnings: Warning 1329 No data - zero rows fetched, selected, or processed SELECT 1 INTO @var17727401 FROM DUAL; SELECT 1 INTO @var17727401_1 FROM t1 INTO @var17727401_2; -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 'INTO @var17727401_2' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT 1 INTO @var17727401_1 FROM DUAL INTO @var17727401_2; -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 'INTO @var17727401_2' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT 1 INTO @var17727401 FROM t1 WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1; Warnings: Warning 1329 No data - zero rows fetched, selected, or processed @@ -784,41 +787,29 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp SELECT 1 INTO @var17727401_1 FROM t1 WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1 INTO @var17727401_2; -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 'INTO @var17727401_2' at line 3 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT (SELECT 1 FROM t1 INTO @var17727401); -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 'INTO @var17727401)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT 1 FROM (SELECT 1 FROM t1 INTO @var17727401) 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 'INTO @var17727401) a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT EXISTS(SELECT 1 FROM t1 INTO @var17727401); -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 'INTO @var17727401)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT 1 FROM t1 INTO @var17727401 UNION SELECT 1 FROM t1 INTO t1; 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 'UNION SELECT 1 FROM t1 INTO t1' at line 1 (SELECT 1 FROM t1 INTO @var17727401) UNION (SELECT 1 FROM t1 INTO t1); -ERROR HY000: Incorrect usage of UNION and INTO +ERROR 42000: Undeclared variable: t1 SELECT 1 FROM t1 UNION SELECT 1 FROM t1 INTO @var17727401; Warnings: Warning 1329 No data - zero rows fetched, selected, or processed SELECT 1 INTO @var17727401 FROM t1 PROCEDURE ANALYSE(); -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 'PROCEDURE ANALYSE()' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT 1 FROM t1 PROCEDURE ANALYSE() INTO @var17727401; -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 'INTO @var17727401' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' # ORDER and LIMIT clause combinations -(SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1; -1 -(SELECT 1 FROM t1 LIMIT 1) LIMIT 1; -1 -((SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1) ORDER BY 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 'ORDER BY 1) ORDER BY 1' at line 1 -((SELECT 1 FROM t1 LIMIT 1) LIMIT 1) LIMIT 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 'LIMIT 1) LIMIT 1' at line 1 -(SELECT 1 FROM t1 ORDER BY 1) LIMIT 1; -1 -(SELECT 1 FROM t1 LIMIT 1) ORDER BY 1; -1 ((SELECT 1 FROM t1 ORDER BY 1) LIMIT 1) ORDER BY 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 'LIMIT 1) ORDER BY 1)' at line 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 ((SELECT 1 FROM t1 LIMIT 1) ORDER BY 1) LIMIT 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 'ORDER BY 1) LIMIT 1)' at line 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 SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1; 1 SELECT (SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1); @@ -1265,19 +1256,19 @@ CREATE TABLE t1 (i INT); (SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)) UNION (SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)); -ERROR HY000: Incorrect usage of UNION and SELECT ... PROCEDURE ANALYSE() +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' (SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)) UNION SELECT * FROM t1 PROCEDURE ANALYSE(10, 10); -ERROR HY000: Incorrect usage of UNION and SELECT ... PROCEDURE ANALYSE() +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' (SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)) UNION (SELECT 1); -ERROR HY000: Incorrect usage of UNION and SELECT ... PROCEDURE ANALYSE() +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' (SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)) UNION SELECT 1; -ERROR HY000: Incorrect usage of UNION and SELECT ... PROCEDURE ANALYSE() +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' SELECT * FROM t1 PROCEDURE ANALYSE(10, 10) UNION (SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)); diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index eb9b1d16011..d6e46b124b4 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -847,13 +847,6 @@ select '1' || '3' from t1; 1 1 1 -set SQL_MODE=oracle; -select '1' || '3' from t1; -'1' || '3' -13 -13 -13 -13 set SQL_MODE=default; drop table t1; create table t1 (a varchar(20), b int); @@ -876,7 +869,7 @@ Variable_name Value Qcache_queries_in_cache 0 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 19 +Qcache_inserts 18 show status like "Qcache_hits"; Variable_name Value Qcache_hits 6 @@ -889,7 +882,7 @@ Variable_name Value Qcache_queries_in_cache 1 show status like "Qcache_inserts"; Variable_name Value -Qcache_inserts 20 +Qcache_inserts 19 show status like "Qcache_hits"; Variable_name Value Qcache_hits 7 @@ -1858,17 +1851,17 @@ DROP TABLE t1; SET GLOBAL query_cache_size= default; CREATE TABLE t1( a INT ); SET @v = ( SELECT SQL_CACHE 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 '1 )' at line 1 +ERROR 42000: Incorrect usage/placement of 'SQL_CACHE' SET @v = ( SELECT SQL_NO_CACHE 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 '1 )' at line 1 +ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE' SELECT a FROM t1 WHERE a IN ( SELECT SQL_CACHE a FROM t1 ); -ERROR 42S22: Unknown column 'SQL_CACHE' in 'field list' +ERROR 42000: Incorrect usage/placement of 'SQL_CACHE' SELECT a FROM t1 WHERE a IN ( SELECT SQL_NO_CACHE a FROM t1 ); -ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list' +ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE' SELECT ( SELECT SQL_CACHE a FROM t1 ); -ERROR 42S22: Unknown column 'SQL_CACHE' in 'field list' +ERROR 42000: Incorrect usage/placement of 'SQL_CACHE' SELECT ( SELECT SQL_NO_CACHE a FROM t1 ); -ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list' +ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE' SELECT SQL_CACHE * FROM t1; a SELECT SQL_NO_CACHE * FROM t1; @@ -1878,18 +1871,18 @@ ERROR 42000: Incorrect usage/placement of 'SQL_CACHE' SELECT * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1; ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE' SELECT * FROM t1 WHERE a IN (SELECT SQL_CACHE a FROM t1); -ERROR 42S22: Unknown column 'SQL_CACHE' in 'field list' +ERROR 42000: Incorrect usage/placement of 'SQL_CACHE' SELECT * FROM t1 WHERE a IN (SELECT a FROM t1 UNION SELECT SQL_CACHE a FROM t1); -ERROR 42S22: Unknown column 'SQL_CACHE' in 'field list' +ERROR 42000: Incorrect usage/placement of 'SQL_CACHE' SELECT * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1; ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE' SELECT * FROM t1 WHERE a IN (SELECT SQL_NO_CACHE a FROM t1); -ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list' +ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE' SELECT * FROM t1 WHERE a IN (SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1); -ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list' +ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE' SELECT SQL_CACHE SQL_NO_CACHE * FROM t1; -ERROR HY000: Incorrect usage of SQL_CACHE and SQL_NO_CACHE +ERROR HY000: Incorrect usage of SQL_NO_CACHE and SQL_CACHE SELECT SQL_NO_CACHE SQL_CACHE * FROM t1; ERROR HY000: Incorrect usage of SQL_NO_CACHE and SQL_CACHE SELECT SQL_CACHE * FROM t1 UNION SELECT SQL_CACHE * FROM t1; @@ -1902,10 +1895,10 @@ SELECT SQL_NO_CACHE * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1; ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE' SELECT SQL_CACHE * FROM t1 WHERE a IN (SELECT SQL_NO_CACHE a FROM t1); -ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list' +ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE' SELECT SQL_CACHE * FROM t1 WHERE a IN (SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1); -ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list' +ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE' DROP TABLE t1; End of 5.1 tests # diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 38a7bd8e1c2..44197daab3c 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -755,11 +755,11 @@ View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache current_timestamp() AS `NOW()` binary binary DROP VIEW v1; CREATE VIEW v1 AS SELECT SQL_CACHE SQL_NO_CACHE NOW(); -ERROR HY000: Incorrect usage of SQL_CACHE and SQL_NO_CACHE +ERROR HY000: Incorrect usage of SQL_NO_CACHE and SQL_CACHE CREATE VIEW v1 AS SELECT SQL_NO_CACHE SQL_CACHE NOW(); ERROR HY000: Incorrect usage of SQL_NO_CACHE and SQL_CACHE CREATE VIEW v1 AS SELECT SQL_CACHE SQL_NO_CACHE SQL_CACHE NOW(); -ERROR HY000: Incorrect usage of SQL_CACHE and SQL_NO_CACHE +ERROR HY000: Option 'SQL_CACHE' used twice in statement CREATE PROCEDURE p1() BEGIN SET @s= 'CREATE VIEW v1 AS SELECT SQL_CACHE 1'; diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index f0bc1874850..874e930fb5b 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1227,16 +1227,16 @@ DROP PROCEDURE IF EXISTS bug14702; DROP TABLE IF EXISTS t1; CREATE TABLE t1 (i INT); CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO @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 'INTO @a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file"; -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 'INTO DUMPFILE "file"' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file"; -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 'INTO OUTFILE "file"' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE(); -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 'PROCEDURE ANALYSE()' at line 2 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 FROM (SELECT 1) AS d1 into @w; -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 'into @w' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' CREATE PROCEDURE bug20953(i INT) CREATE VIEW v AS SELECT i; ERROR HY000: View's SELECT contains a variable or parameter CREATE PROCEDURE bug20953() diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index cb2237699fb..f952470e48c 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -314,7 +314,7 @@ delete from t1| drop procedure b| drop procedure if exists b2| create procedure b2(x int) -repeat(select 1 into outfile 'b2'); +repeat(select 1) into outfile 'b2'; insert into test.t1 values (repeat("b2",3), x); set x = x-1; until x = 0 end repeat| @@ -6904,18 +6904,6 @@ END latin1 latin1_swedish_ci latin1_swedish_ci DROP FUNCTION f1; -drop procedure if exists p; -set @old_mode= @@sql_mode; -set @@sql_mode= cast(pow(2,32)-1 as unsigned integer); -select @@sql_mode into @full_mode; -create procedure p() as begin end; -call p(); -set @@sql_mode= @old_mode; -select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; -select name from mysql.proc where name = 'p' and sql_mode = @full_mode; -name -p -drop procedure p; CREATE DEFINER = 'root'@'localhost' PROCEDURE p1() NOT DETERMINISTIC CONTAINS SQL @@ -8116,6 +8104,129 @@ CALL p(); drop procedure p; drop view v; drop table t, tmp_t; +# +# MDEV-14857: problem with 10.2.11 server crashing when +# executing stored procedure +# +SET max_sp_recursion_depth=10; +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT); +CREATE PROCEDURE proc_0() +BEGIN +CALL empty_1(); +CALL proc_1(); +END || +CREATE PROCEDURE proc_1() +BEGIN +CALL proc_2(); +CALL proc_3(); +CALL proc_4(); +CALL proc_5(); +END || +CREATE PROCEDURE proc_2() +CALL proc_6(); +|| +CREATE PROCEDURE proc_3() +BEGIN +CALL empty_2(); +CALL empty_3(); +END || +CREATE PROCEDURE proc_4() +CALL proc_7(); +|| +CREATE PROCEDURE proc_5() +CALL proc_select(); +|| +CREATE PROCEDURE proc_6() +BEGIN +CALL empty_4(); +CALL empty_5(); +CALL empty_6(); +CALL empty_7(); +CALL proc_8(); +END || +CREATE PROCEDURE proc_7() +CALL proc_9('foo'); +|| +CREATE PROCEDURE proc_8() +CALL proc_10(); +|| +CREATE PROCEDURE proc_9(IN opt VARCHAR(40)) +IF LEFT(opt,1) <> '_' THEN +CALL proc_11(); +END IF; +|| +CREATE PROCEDURE proc_10() +CALL proc_12(); +|| +CREATE PROCEDURE proc_11() +BEGIN +CALL empty_8(); +CALL empty_9(); +CALL empty_10(); +CALL proc_13(); +END || +CREATE PROCEDURE proc_12() +BEGIN +CALL empty_11(); +CALL empty_12(); +CALL empty_13(); +END || +CREATE PROCEDURE proc_13() +BEGIN +CALL proc_9('_bar'); +CALL empty_14(); +END || +CREATE PROCEDURE empty_1() BEGIN END ; +CREATE PROCEDURE empty_2() BEGIN END ; +CREATE PROCEDURE empty_3() BEGIN END ; +CREATE PROCEDURE empty_4() BEGIN END ; +CREATE PROCEDURE empty_5() BEGIN END ; +CREATE PROCEDURE empty_6() BEGIN END ; +CREATE PROCEDURE empty_7() BEGIN END ; +CREATE PROCEDURE empty_8() BEGIN END ; +CREATE PROCEDURE empty_9() BEGIN END ; +CREATE PROCEDURE empty_10() BEGIN END ; +CREATE PROCEDURE empty_11() BEGIN END ; +CREATE PROCEDURE empty_12() BEGIN END ; +CREATE PROCEDURE empty_13() BEGIN END ; +CREATE PROCEDURE empty_14() BEGIN END ; +CREATE PROCEDURE proc_select() +SELECT * FROM t1 WHERE NOT EXISTS ( SELECT * FROM t2) +; +CALL proc_0(); +a +DROP PROCEDURE empty_1; +DROP PROCEDURE empty_2; +DROP PROCEDURE empty_3; +DROP PROCEDURE empty_4; +DROP PROCEDURE empty_5; +DROP PROCEDURE empty_6; +DROP PROCEDURE empty_7; +DROP PROCEDURE empty_8; +DROP PROCEDURE empty_9; +DROP PROCEDURE empty_10; +DROP PROCEDURE empty_11; +DROP PROCEDURE empty_12; +DROP PROCEDURE empty_13; +DROP PROCEDURE empty_14; +DROP PROCEDURE proc_0; +DROP PROCEDURE proc_1; +DROP PROCEDURE proc_2; +DROP PROCEDURE proc_3; +DROP PROCEDURE proc_4; +DROP PROCEDURE proc_5; +DROP PROCEDURE proc_6; +DROP PROCEDURE proc_7; +DROP PROCEDURE proc_8; +DROP PROCEDURE proc_9; +DROP PROCEDURE proc_10; +DROP PROCEDURE proc_11; +DROP PROCEDURE proc_12; +DROP PROCEDURE proc_13; +DROP PROCEDURE proc_select; +DROP TABLE t1, t2; +SET max_sp_recursion_depth=default; #End of 10.1 tests # # MDEV-11081: CURSOR for query with GROUP BY diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index 7c881fd5ad5..b674376e173 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -72,10 +72,10 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`a`), UNIQUE KEY `email` (`email`) ) TYPE=MEMORY ROW_FORMAT=DYNAMIC -set sql_mode="postgresql,oracle,mssql,db2,maxdb"; +set sql_mode="postgresql,mssql,db2,maxdb"; select @@sql_mode; @@sql_mode -PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER +PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,POSTGRESQL,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER show create table t1; Table Create Table t1 CREATE TABLE "t1" ( @@ -749,7 +749,6 @@ SET sql_mode=DEFAULT; CREATE OR REPLACE TABLE t1 (a TEXT); PREPARE stmt FROM 'INSERT INTO t1 (a) VALUES (2||3)'; EXECUTE stmt; -SET sql_mode=ORACLE; EXECUTE stmt; ALTER TABLE t1 ADD b INT; EXECUTE stmt; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 919693efffb..b50e159ca32 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -80,7 +80,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); 1 1 select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 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 'SELECT 1))' at line 1 SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; @@ -179,7 +179,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1); a b 1 7 2 7 -(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3; +(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) +union (select * from t4 order by a limit 2) order by a limit 3; a b 1 7 2 7 @@ -3728,7 +3729,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS i SELECT * FROM t1 WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); -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 'UNION (SELECT i FROM t1)))' at line 2 +i explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) from t1; 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 'union (select t12.i from t1 t12)) @@ -5096,34 +5097,31 @@ INSERT INTO t1 VALUES (1),(2); CREATE TABLE t2( a INT, b INT ); SELECT * FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a; -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 'INTO @var FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO @var FROM t1 WHERE a = 2 ) t1a; -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 'INTO @var FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a; a 2 @@ -5154,23 +5152,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a; 1 1 SELECT * FROM ((SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a; -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 'INTO @a))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a; -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 'INTO DUMPFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a; -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 'INTO OUTFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a ORDER BY a) t1a; a 1 @@ -5188,35 +5186,23 @@ a 1 1 1 2 1 SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1; -ERROR 42000: Every derived table must have its own alias +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 'ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 1' at line 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 'UNION SELECT 1) ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 1' at line 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 'UNION SELECT 1)) ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 1' at line 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 ') t1a ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 1' at line 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 ')) t1a ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ') ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ')) ON 1' at line 1 SELECT * FROM (t1 t1a); -a -1 -2 +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 SELECT * FROM ((t1 t1a)); -a -1 -2 +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 SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1; a t1a 1 1 @@ -5245,11 +5231,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 ); a 1 @@ -5257,29 +5243,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1; ( SELECT a FROM t1 WHERE a = 1 ) a 1 1 @@ -5291,11 +5277,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1; SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2); a b SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 )' at line 1 +1 +1 ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1' at line 1 +1 +1 SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ) +1 SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1' at line 1 SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5305,9 +5294,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1)); ((SELECT 1 UNION SELECT 1 UNION SELECT 1)) 1 SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ); -ERROR 42000: Every derived table must have its own alias +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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a; 1 1 @@ -5315,19 +5304,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a; 1 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5343,18 +5338,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT EXISTS(SELECT 1+1); EXISTS(SELECT 1+1) 1 SELECT EXISTS(SELECT 1+1 INTO @test); -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 'INTO @test)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' DROP TABLE t1, t2; CREATE TABLE t1 (a ENUM('rainbow')); INSERT INTO t1 VALUES (),(),(),(),(); diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index 350275d2463..658b5e2cf07 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -2179,11 +2179,11 @@ drop database mysqltest4; # (both 1st and further executions) CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM; INSERT INTO t1 VALUES (0),(8); -SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2)); +SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2); a 0 PREPARE stmt FROM " -SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2)) +SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2) "; execute stmt; a diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result index 806475b3380..16b605b7b2d 100644 --- a/mysql-test/r/subselect_no_exists_to_in.result +++ b/mysql-test/r/subselect_no_exists_to_in.result @@ -84,7 +84,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); 1 1 select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 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 'SELECT 1))' at line 1 SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; @@ -183,7 +183,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1); a b 1 7 2 7 -(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3; +(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) +union (select * from t4 order by a limit 2) order by a limit 3; a b 1 7 2 7 @@ -3731,7 +3732,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS i SELECT * FROM t1 WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); -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 'UNION (SELECT i FROM t1)))' at line 2 +i explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) from t1; 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 'union (select t12.i from t1 t12)) @@ -5098,34 +5099,31 @@ INSERT INTO t1 VALUES (1),(2); CREATE TABLE t2( a INT, b INT ); SELECT * FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a; -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 'INTO @var FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO @var FROM t1 WHERE a = 2 ) t1a; -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 'INTO @var FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a; a 2 @@ -5156,23 +5154,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a; 1 1 SELECT * FROM ((SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a; -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 'INTO @a))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a; -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 'INTO DUMPFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a; -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 'INTO OUTFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a ORDER BY a) t1a; a 1 @@ -5190,35 +5188,23 @@ a 1 1 1 2 1 SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1; -ERROR 42000: Every derived table must have its own alias +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 'ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 1' at line 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 'UNION SELECT 1) ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 1' at line 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 'UNION SELECT 1)) ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 1' at line 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 ') t1a ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 1' at line 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 ')) t1a ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ') ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ')) ON 1' at line 1 SELECT * FROM (t1 t1a); -a -1 -2 +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 SELECT * FROM ((t1 t1a)); -a -1 -2 +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 SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1; a t1a 1 1 @@ -5247,11 +5233,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 ); a 1 @@ -5259,29 +5245,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1; ( SELECT a FROM t1 WHERE a = 1 ) a 1 1 @@ -5293,11 +5279,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1; SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2); a b SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 )' at line 1 +1 +1 ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1' at line 1 +1 +1 SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ) +1 SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1' at line 1 SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5307,9 +5296,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1)); ((SELECT 1 UNION SELECT 1 UNION SELECT 1)) 1 SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ); -ERROR 42000: Every derived table must have its own alias +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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a; 1 1 @@ -5317,19 +5306,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a; 1 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5345,18 +5340,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT EXISTS(SELECT 1+1); EXISTS(SELECT 1+1) 1 SELECT EXISTS(SELECT 1+1 INTO @test); -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 'INTO @test)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' DROP TABLE t1, t2; CREATE TABLE t1 (a ENUM('rainbow')); INSERT INTO t1 VALUES (),(),(),(),(); diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index 237a6dbf9bb..1e7027bb83f 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -87,7 +87,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); 1 1 select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 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 'SELECT 1))' at line 1 SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; @@ -186,7 +186,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1); a b 1 7 2 7 -(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3; +(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) +union (select * from t4 order by a limit 2) order by a limit 3; a b 1 7 2 7 @@ -3731,7 +3732,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS i SELECT * FROM t1 WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); -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 'UNION (SELECT i FROM t1)))' at line 2 +i explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) from t1; 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 'union (select t12.i from t1 t12)) @@ -5096,34 +5097,31 @@ INSERT INTO t1 VALUES (1),(2); CREATE TABLE t2( a INT, b INT ); SELECT * FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a; -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 'INTO @var FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO @var FROM t1 WHERE a = 2 ) t1a; -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 'INTO @var FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a; a 2 @@ -5154,23 +5152,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a; 1 1 SELECT * FROM ((SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a; -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 'INTO @a))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a; -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 'INTO DUMPFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a; -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 'INTO OUTFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a ORDER BY a) t1a; a 1 @@ -5188,35 +5186,23 @@ a 1 1 1 2 1 SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1; -ERROR 42000: Every derived table must have its own alias +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 'ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 1' at line 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 'UNION SELECT 1) ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 1' at line 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 'UNION SELECT 1)) ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 1' at line 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 ') t1a ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 1' at line 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 ')) t1a ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ') ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ')) ON 1' at line 1 SELECT * FROM (t1 t1a); -a -1 -2 +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 SELECT * FROM ((t1 t1a)); -a -1 -2 +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 SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1; a t1a 1 1 @@ -5245,11 +5231,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 ); a 1 @@ -5257,29 +5243,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1; ( SELECT a FROM t1 WHERE a = 1 ) a 1 1 @@ -5291,11 +5277,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1; SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2); a b SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 )' at line 1 +1 +1 ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1' at line 1 +1 +1 SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ) +1 SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1' at line 1 SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5305,9 +5294,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1)); ((SELECT 1 UNION SELECT 1 UNION SELECT 1)) 1 SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ); -ERROR 42000: Every derived table must have its own alias +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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a; 1 1 @@ -5315,19 +5304,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a; 1 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5343,18 +5338,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT EXISTS(SELECT 1+1); EXISTS(SELECT 1+1) 1 SELECT EXISTS(SELECT 1+1 INTO @test); -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 'INTO @test)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' DROP TABLE t1, t2; CREATE TABLE t1 (a ENUM('rainbow')); INSERT INTO t1 VALUES (),(),(),(),(); diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index af1afe47f32..1a271a2d418 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -83,7 +83,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); 1 1 select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 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 'SELECT 1))' at line 1 SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; @@ -182,7 +182,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1); a b 1 7 2 7 -(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3; +(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) +union (select * from t4 order by a limit 2) order by a limit 3; a b 1 7 2 7 @@ -3727,7 +3728,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS i SELECT * FROM t1 WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); -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 'UNION (SELECT i FROM t1)))' at line 2 +i explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) from t1; 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 'union (select t12.i from t1 t12)) @@ -5092,34 +5093,31 @@ INSERT INTO t1 VALUES (1),(2); CREATE TABLE t2( a INT, b INT ); SELECT * FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a; -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 'INTO @var FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO @var FROM t1 WHERE a = 2 ) t1a; -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 'INTO @var FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a; a 2 @@ -5150,23 +5148,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a; 1 1 SELECT * FROM ((SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a; -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 'INTO @a))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a; -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 'INTO DUMPFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a; -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 'INTO OUTFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a ORDER BY a) t1a; a 1 @@ -5184,35 +5182,23 @@ a 1 1 1 2 1 SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1; -ERROR 42000: Every derived table must have its own alias +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 'ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 1' at line 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 'UNION SELECT 1) ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 1' at line 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 'UNION SELECT 1)) ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 1' at line 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 ') t1a ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 1' at line 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 ')) t1a ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ') ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ')) ON 1' at line 1 SELECT * FROM (t1 t1a); -a -1 -2 +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 SELECT * FROM ((t1 t1a)); -a -1 -2 +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 SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1; a t1a 1 1 @@ -5241,11 +5227,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 ); a 1 @@ -5253,29 +5239,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1; ( SELECT a FROM t1 WHERE a = 1 ) a 1 1 @@ -5287,11 +5273,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1; SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2); a b SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 )' at line 1 +1 +1 ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1' at line 1 +1 +1 SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ) +1 SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1' at line 1 SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5301,9 +5290,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1)); ((SELECT 1 UNION SELECT 1 UNION SELECT 1)) 1 SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ); -ERROR 42000: Every derived table must have its own alias +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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a; 1 1 @@ -5311,19 +5300,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a; 1 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5339,18 +5334,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT EXISTS(SELECT 1+1); EXISTS(SELECT 1+1) 1 SELECT EXISTS(SELECT 1+1 INTO @test); -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 'INTO @test)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' DROP TABLE t1, t2; CREATE TABLE t1 (a ENUM('rainbow')); INSERT INTO t1 VALUES (),(),(),(),(); diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index 75be8642069..2372e2f2ce7 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -86,7 +86,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); 1 1 select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 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 'SELECT 1))' at line 1 SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; @@ -185,7 +185,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1); a b 1 7 2 7 -(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3; +(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) +union (select * from t4 order by a limit 2) order by a limit 3; a b 1 7 2 7 @@ -3734,7 +3735,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS i SELECT * FROM t1 WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); -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 'UNION (SELECT i FROM t1)))' at line 2 +i explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) from t1; 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 'union (select t12.i from t1 t12)) @@ -5102,34 +5103,31 @@ INSERT INTO t1 VALUES (1),(2); CREATE TABLE t2( a INT, b INT ); SELECT * FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a; -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 'INTO @var FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO @var FROM t1 WHERE a = 2 ) t1a; -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 'INTO @var FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a; a 2 @@ -5160,23 +5158,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a; 1 1 SELECT * FROM ((SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a; -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 'INTO @a))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a; -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 'INTO DUMPFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a; -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 'INTO OUTFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a ORDER BY a) t1a; a 1 @@ -5194,35 +5192,23 @@ a 1 1 1 2 1 SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1; -ERROR 42000: Every derived table must have its own alias +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 'ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 1' at line 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 'UNION SELECT 1) ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 1' at line 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 'UNION SELECT 1)) ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 1' at line 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 ') t1a ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 1' at line 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 ')) t1a ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ') ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ')) ON 1' at line 1 SELECT * FROM (t1 t1a); -a -1 -2 +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 SELECT * FROM ((t1 t1a)); -a -1 -2 +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 SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1; a t1a 1 1 @@ -5251,11 +5237,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 ); a 1 @@ -5263,29 +5249,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1; ( SELECT a FROM t1 WHERE a = 1 ) a 1 1 @@ -5297,11 +5283,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1; SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2); a b SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 )' at line 1 +1 +1 ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1' at line 1 +1 +1 SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ) +1 SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1' at line 1 SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5311,9 +5300,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1)); ((SELECT 1 UNION SELECT 1 UNION SELECT 1)) 1 SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ); -ERROR 42000: Every derived table must have its own alias +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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a; 1 1 @@ -5321,19 +5310,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a; 1 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5349,18 +5344,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT EXISTS(SELECT 1+1); EXISTS(SELECT 1+1) 1 SELECT EXISTS(SELECT 1+1 INTO @test); -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 'INTO @test)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' DROP TABLE t1, t2; CREATE TABLE t1 (a ENUM('rainbow')); INSERT INTO t1 VALUES (),(),(),(),(); diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index a6a6397375b..f00cb186fb8 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -83,7 +83,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); 1 1 select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 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 'SELECT 1))' at line 1 SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; @@ -182,7 +182,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1); a b 1 7 2 7 -(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3; +(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) +union (select * from t4 order by a limit 2) order by a limit 3; a b 1 7 2 7 @@ -3727,7 +3728,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS i SELECT * FROM t1 WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); -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 'UNION (SELECT i FROM t1)))' at line 2 +i explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) from t1; 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 'union (select t12.i from t1 t12)) @@ -5092,34 +5093,31 @@ INSERT INTO t1 VALUES (1),(2); CREATE TABLE t2( a INT, b INT ); SELECT * FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a; -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 'INTO @var FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO @var FROM t1 WHERE a = 2 ) t1a; -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 'INTO @var FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO OUTFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ( SELECT 1 a UNION SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2 ) t1a; -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 'INTO DUMPFILE 'file' FROM t1 WHERE a = 2 -) t1a' at line 4 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a; a 2 @@ -5150,23 +5148,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a; 1 1 SELECT * FROM ((SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a; -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 'INTO @a)) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a; -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 'INTO DUMPFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a; -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 'INTO OUTFILE 'file' )) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a; -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 'INTO @a))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a; -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 'INTO DUMPFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a; -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 'INTO OUTFILE 'file' ))) t1a' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM (SELECT 1 a ORDER BY a) t1a; a 1 @@ -5184,35 +5182,23 @@ a 1 1 1 2 1 SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1; -ERROR 42000: Every derived table must have its own alias +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 'ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 1' at line 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 'UNION SELECT 1) ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 1' at line 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 'UNION SELECT 1)) ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 1' at line 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 ') t1a ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 1' at line 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 ')) t1a ON 1' at line 1 SELECT * FROM t1 JOIN (t1 t1a) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ') ON 1' at line 1 SELECT * FROM t1 JOIN ((t1 t1a)) ON 1; -a a -1 1 -2 1 -1 2 -2 2 +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 ')) ON 1' at line 1 SELECT * FROM (t1 t1a); -a -1 -2 +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 SELECT * FROM ((t1 t1a)); -a -1 -2 +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 SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1; a t1a 1 1 @@ -5241,11 +5227,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 ); a 1 @@ -5253,29 +5239,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @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 'INTO @a)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); -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 'INTO OUTFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); -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 'INTO DUMPFILE 'file' )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1; ( SELECT a FROM t1 WHERE a = 1 ) a 1 1 @@ -5287,11 +5273,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1; SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2); a b SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 )' at line 1 +1 +1 ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1' at line 1 +1 +1 SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ) +1 SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1' at line 1 SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5301,9 +5290,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1)); ((SELECT 1 UNION SELECT 1 UNION SELECT 1)) 1 SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ); -ERROR 42000: Every derived table must have its own alias +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 SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a; 1 1 @@ -5311,19 +5300,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a; 1 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 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 'UNION SELECT 1 ) )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 ) UNION SELECT 1 )' at line 1 +a +1 SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 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 'UNION SELECT 1 )' at line 1 SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); @@ -5339,18 +5334,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); a 1 SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT EXISTS(SELECT 1+1); EXISTS(SELECT 1+1) 1 SELECT EXISTS(SELECT 1+1 INTO @test); -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 'INTO @test)' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v ); -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 'INTO @v )' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' DROP TABLE t1, t2; CREATE TABLE t1 (a ENUM('rainbow')); INSERT INTO t1 VALUES (),(),(),(),(); diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index a601dac5337..0de9f2f57da 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -1675,7 +1675,7 @@ CREATE TABLE t3 ( f11 int) ; INSERT IGNORE INTO t3 VALUES (0); SELECT alias1.f11 AS field2 FROM ( t3 AS alias2 JOIN t1 AS alias3 ON alias3.f10 = 1) -LEFT JOIN ( t2 AS alias1 ) ON alias3.f11 = 1 +LEFT JOIN t2 AS alias1 ON alias3.f11 = 1 WHERE alias2.f11 IN ( SELECT f11 FROM t2 ) GROUP BY field2 ; field2 diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index 77a073ea2d3..4810d06f1c3 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -1688,7 +1688,7 @@ CREATE TABLE t3 ( f11 int) ; INSERT IGNORE INTO t3 VALUES (0); SELECT alias1.f11 AS field2 FROM ( t3 AS alias2 JOIN t1 AS alias3 ON alias3.f10 = 1) -LEFT JOIN ( t2 AS alias1 ) ON alias3.f11 = 1 +LEFT JOIN t2 AS alias1 ON alias3.f11 = 1 WHERE alias2.f11 IN ( SELECT f11 FROM t2 ) GROUP BY field2 ; field2 diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index 9e1870875ce..579a9db0218 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -2219,11 +2219,11 @@ drop database mysqltest4; # (both 1st and further executions) CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM; INSERT INTO t1 VALUES (0),(8); -SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2)); +SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2); a 0 PREPARE stmt FROM " -SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2)) +SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2) "; execute stmt; a diff --git a/mysql-test/r/test.result b/mysql-test/r/test.result new file mode 100644 index 00000000000..05fba4cfad0 --- /dev/null +++ b/mysql-test/r/test.result @@ -0,0 +1,114 @@ +select 1 union ( select 2 union select 3); +1 +1 +2 +3 +explain extended +select 1 union ( select 2 union select 3); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL +NULL UNION RESULT <union1,4> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select 1 AS `1` union /* select#4 */ select `__4`.`2` AS `2` from (/* select#2 */ select 2 AS `2` union /* select#3 */ select 3 AS `3`) `__4` +select 1 union ( select 1 union select 1); +1 +1 +explain extended +select 1 union ( select 1 union select 1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL +NULL UNION RESULT <union1,4> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select 1 AS `1` union /* select#4 */ select `__4`.`1` AS `1` from (/* select#2 */ select 1 AS `1` union /* select#3 */ select 1 AS `1`) `__4` +select 1 union all ( select 1 union select 1); +1 +1 +1 +explain extended +select 1 union all ( select 1 union select 1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select 1 AS `1` union all /* select#4 */ select `__4`.`1` AS `1` from (/* select#2 */ select 1 AS `1` union /* select#3 */ select 1 AS `1`) `__4` +select 1 union ( select 1 union all select 1); +1 +1 +explain extended +select 1 union ( select 1 union all select 1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +4 UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,4> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select 1 AS `1` union /* select#4 */ select `__4`.`1` AS `1` from (/* select#2 */ select 1 AS `1` union all /* select#3 */ select 1 AS `1`) `__4` +select 1 union select 1 union all select 1; +1 +1 +1 +explain extended +select 1 union select 1 union all select 1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2,3> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1 */ select 1 AS `1` union /* select#2 */ select 1 AS `1` union all /* select#3 */ select 1 AS `1` +(select 1 as a) union (select 2) order by a; +a +1 +2 +explain extended +(select 1 as a) union (select 2) order by a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 (/* select#1 */ select 1 AS `a`) union (/* select#2 */ select 2 AS `2`) order by `a` +/* select#1 */ select 1 AS `a` union /* select#2 */ select 2 AS `2` order by `a`; +a +1 +2 +explain extended +/* select#1 */ select 1 AS `a` union /* select#2 */ select 2 AS `2` order by `a`; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 /* select#1 */ select 1 AS `a` union /* select#2 */ select 2 AS `2` order by `a` +select 1 union ( select 1 union (select 1 union (select 1 union select 1))); +1 +1 +explain extended all +select 1 union ( select 1 union (select 1 union (select 1 union select 1))); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used +8 UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +7 UNION <derived3> ALL NULL NULL NULL NULL 2 100.00 +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +6 UNION <derived4> ALL NULL NULL NULL NULL 2 100.00 +4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used +5 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL NULL +NULL UNION RESULT <union3,6> ALL NULL NULL NULL NULL NULL NULL +NULL UNION RESULT <union2,7> ALL NULL NULL NULL NULL NULL NULL +NULL UNION RESULT <union1,8> ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 /* select#1/1 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#8/1 */ select `__8`.`1` AS `1` from (/* select#2/2 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#7/2 */ select `__7`.`1` AS `1` from (/* select#3/3 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#6/3 */ select `__6`.`1` AS `1` from (/* select#4/4 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#5/4 */ select 1 AS `1`) `__6`) `__7`) `__8` diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index b193f032146..e00144ad300 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -81,7 +81,7 @@ a b 2 b 1 a (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b; -ERROR 42000: Table 't1' from one of the SELECTs cannot be used in global ORDER clause +ERROR 42000: Table 't1' from one of the SELECTs cannot be used in ORDER clause explain extended (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 @@ -494,7 +494,7 @@ drop temporary table t1; create table t1 select a from t1 union select a from t2; ERROR 42S01: Table 't1' already exists select a from t1 union select a from t2 order by t2.a; -ERROR 42000: Table 't2' from one of the SELECTs cannot be used in field list +ERROR 42000: Table 't2' from one of the SELECTs cannot be used in ORDER clause drop table t1,t2; select length(version()) > 1 as `*` UNION select 2; * @@ -1532,11 +1532,8 @@ SELECT a FROM (SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY c) AS test; ERROR 42S22: Unknown column 'c' in 'order clause' DROP TABLE t1; (select 1 into @var) union (select 1); -ERROR HY000: Incorrect usage of UNION and INTO +ERROR 42000: Incorrect usage/placement of 'INTO' (select 1) union (select 1 into @var); -select @var; -@var -1 (select 2) union (select 1 into @var); ERROR 42000: Result consisted of more than one row CREATE TABLE t1 (a int); @@ -1666,11 +1663,11 @@ SELECT a FROM t1 UNION SELECT a INTO @v FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1; SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; -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 'UNION SELECT a FROM t1' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; -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 'UNION SELECT a FROM t1' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; -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 'UNION SELECT a FROM t1' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' # Tests fix in parser rule query_expression_body. SELECT ( SELECT a UNION SELECT a ) INTO @v FROM t1; SELECT ( SELECT a UNION SELECT a ) INTO OUTFILE 'union.out.file3' FROM t1; @@ -2019,14 +2016,14 @@ SET @@global.slow_query_log= @old_slow_query_log; CREATE TABLE t1 (a int); CREATE TABLE t2 (b int); CREATE TABLE t3 (c int); -SELECT a FROM t1 UNION SELECT b FROM t2 JOIN (t3) ON ( t2.b = t3.c ); +SELECT a FROM t1 UNION SELECT b FROM t2 JOIN t3 ON ( t2.b = t3.c ); a DROP TABLE t1, t2, t3; CREATE TABLE t1 (pk int NOT NULL); CREATE TABLE t2 (pk int NOT NULL, fk int NOT NULL); -SELECT t1.pk FROM t1 LEFT JOIN (t2) ON (t1.pk = t2.fk) +SELECT t1.pk FROM t1 LEFT JOIN t2 ON (t1.pk = t2.fk) UNION -SELECT t1.pk FROM t1 LEFT JOIN (t2) ON (t1.pk = t2.fk); +SELECT t1.pk FROM t1 LEFT JOIN t2 ON (t1.pk = t2.fk); pk DROP TABLE t1,t2; create table t1 (a int); diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 24c669308cd..a58da83278e 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -919,12 +919,12 @@ select * from v4; ERROR 21000: Subquery returns more than 1 row drop view v4, v3, v2, v1; create view v1 as select 5 into @w; -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 'into @w' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' create view v1 as select 5 into outfile 'ttt'; -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 'into outfile 'ttt'' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' create table t1 (a int); create view v1 as select a from t1 procedure analyse(); -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 'procedure analyse()' at line 1 +ERROR 42000: Incorrect usage/placement of 'PROCEDURE' create view v1 as select 1 from (select 1) as d1; drop view v1; drop table t1; @@ -3223,7 +3223,7 @@ DROP TABLE t1; DROP VIEW IF EXISTS v1; SELECT * FROM (SELECT 1) AS t into @w; CREATE VIEW v1 AS SELECT * FROM (SELECT 1) AS t into @w; -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 'into @w' at line 1 +ERROR 42000: Incorrect usage/placement of 'INTO' # Previously the following would fail. SELECT * FROM (SELECT 1) AS t into @w; drop view if exists view_24532_a; @@ -4163,7 +4163,7 @@ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 ; SELECT 1 -FROM (( SELECT 1 +FROM ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4171,8 +4171,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t1) -LEFT OUTER JOIN (( SELECT 1 +) t1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4180,8 +4180,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t2) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t2 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4189,8 +4189,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t3) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t3 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4198,8 +4198,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t4) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t4 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4207,8 +4207,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t5) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t5 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4216,8 +4216,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t6) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t6 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4225,8 +4225,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t7) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t7 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4234,18 +4234,18 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t8) ON 1=1 +) t8 ON 1=1 ; 1 SELECT 1 -FROM (v1 t1) -LEFT OUTER JOIN (v1 t2) ON 1=1 -LEFT OUTER JOIN (v1 t3) ON 1=1 -LEFT OUTER JOIN (v1 t4) ON 1=1 -LEFT OUTER JOIN (v1 t5) ON 1=1 -LEFT OUTER JOIN (v1 t6) ON 1=1 -LEFT OUTER JOIN (v1 t7) ON 1=1 -LEFT OUTER JOIN (v1 t8) ON 1=1 +FROM v1 t1 +LEFT OUTER JOIN v1 t2 ON 1=1 +LEFT OUTER JOIN v1 t3 ON 1=1 +LEFT OUTER JOIN v1 t4 ON 1=1 +LEFT OUTER JOIN v1 t5 ON 1=1 +LEFT OUTER JOIN v1 t6 ON 1=1 +LEFT OUTER JOIN v1 t7 ON 1=1 +LEFT OUTER JOIN v1 t8 ON 1=1 ; 1 drop view v1; @@ -5318,7 +5318,7 @@ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 ; SELECT 1 -FROM (( SELECT 1 +FROM ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5326,8 +5326,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t1) -LEFT OUTER JOIN (( SELECT 1 +) t1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5335,8 +5335,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t2) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t2 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5344,8 +5344,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t3) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t3 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5353,8 +5353,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t4) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t4 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5362,8 +5362,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t5) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t5 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5371,8 +5371,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t6) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t6 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5380,8 +5380,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t7) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t7 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5389,18 +5389,18 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t8) ON 1=1 +) t8 ON 1=1 ; 1 SELECT 1 -FROM (v1 t1) -LEFT OUTER JOIN (v1 t2) ON 1=1 -LEFT OUTER JOIN (v1 t3) ON 1=1 -LEFT OUTER JOIN (v1 t4) ON 1=1 -LEFT OUTER JOIN (v1 t5) ON 1=1 -LEFT OUTER JOIN (v1 t6) ON 1=1 -LEFT OUTER JOIN (v1 t7) ON 1=1 -LEFT OUTER JOIN (v1 t8) ON 1=1 +FROM v1 t1 +LEFT OUTER JOIN v1 t2 ON 1=1 +LEFT OUTER JOIN v1 t3 ON 1=1 +LEFT OUTER JOIN v1 t4 ON 1=1 +LEFT OUTER JOIN v1 t5 ON 1=1 +LEFT OUTER JOIN v1 t6 ON 1=1 +LEFT OUTER JOIN v1 t7 ON 1=1 +LEFT OUTER JOIN v1 t8 ON 1=1 ; 1 drop view v1; diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index 76288c8fbae..4a156307ff0 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -1179,7 +1179,7 @@ DROP USER mysqltest_u1@localhost; drop procedure if exists p; --enable_warnings set @old_mode= @@sql_mode; -set @@sql_mode= cast(pow(2,32)-1 as unsigned integer); +# set @@sql_mode= cast(pow(2,32)-1 as unsigned integer); create event e1 on schedule every 1 day do select 1; select @@sql_mode into @full_mode; set @@sql_mode= @old_mode; diff --git a/mysql-test/t/except.test b/mysql-test/t/except.test index e13137701a9..671482adf19 100644 --- a/mysql-test/t/except.test +++ b/mysql-test/t/except.test @@ -60,13 +60,13 @@ drop tables t1,t2,t3,t4; select 1 as a from dual except select 1 from dual; (select 1 from dual) except (select 1 from dual); ---error ER_WRONG_USAGE +--error ER_CANT_USE_OPTION_HERE (select 1 from dual into @v) except (select 1 from dual); --error ER_PARSE_ERROR select 1 from dual ORDER BY 1 except select 1 from dual; select 1 as a from dual union all select 1 from dual; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR select 1 from dual except all select 1 from dual; diff --git a/mysql-test/t/func_analyse.test b/mysql-test/t/func_analyse.test index d99f5c0fa9a..24fdd9a10e2 100644 --- a/mysql-test/t/func_analyse.test +++ b/mysql-test/t/func_analyse.test @@ -11,7 +11,7 @@ insert into t1 values (1,2,"","Y","2002-03-03"), (3,4,"","N","2002-03-04"), (5,6 select count(*) from t1 procedure analyse(); select * from t1 procedure analyse(); select * from t1 procedure analyse(2); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE create table t2 select * from t1 procedure analyse(); drop table t1; @@ -127,7 +127,7 @@ CREATE TABLE t1(a INT); INSERT INTO t1 VALUES (1),(2); --echo # should not crash ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE(); DROP TABLE t1; @@ -161,12 +161,17 @@ DROP TABLE t1, t2; --echo # --echo # Start of 10.2 tests --echo # +# --error ER_PARSE_ERROR (SELECT 1 FROM DUAL PROCEDURE ANALYSE()); +# --error ER_PARSE_ERROR ((SELECT 1 FROM DUAL PROCEDURE ANALYSE())); +(SELECT 1 FROM DUAL) PROCEDURE ANALYSE(); +((SELECT 1 FROM DUAL)) PROCEDURE ANALYSE(); -# TODO: ---error ER_PARSE_ERROR +create table t1 (a int); +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 UNION SELECT * FROM t1 PROCEDURE analyse(); +drop table t1; --echo # --echo # MDEV-10030 sql_yacc.yy: Split table_expression and remove PROCEDURE from create_select, select_paren_derived, select_derived2, query_specification @@ -177,7 +182,7 @@ SELECT * FROM (SELECT * FROM t1 PROCEDURE ANALYSE()); --ERROR ER_PARSE_ERROR SELECT * FROM t1 NATURAL JOIN (SELECT * FROM t2 PROCEDURE ANALYSE()); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT (SELECT 1 FROM t1 PROCEDURE ANALYSE()) FROM t2; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT ((SELECT 1 FROM t1 PROCEDURE ANALYSE())) FROM t2; diff --git a/mysql-test/t/intersect.test b/mysql-test/t/intersect.test index 6028b2fa498..8ad4da55e46 100644 --- a/mysql-test/t/intersect.test +++ b/mysql-test/t/intersect.test @@ -59,13 +59,13 @@ drop tables t1,t2,t3; select 1 as a from dual intersect select 1 from dual; (select 1 from dual) intersect (select 1 from dual); ---error ER_WRONG_USAGE +--error ER_CANT_USE_OPTION_HERE (select 1 from dual into @v) intersect (select 1 from dual); --error ER_PARSE_ERROR select 1 from dual ORDER BY 1 intersect select 1 from dual; select 1 as a from dual union all select 1 from dual; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR select 1 from dual intersect all select 1 from dual; diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test index e60b7827f75..77d0e4154c1 100644 --- a/mysql-test/t/join_nested.test +++ b/mysql-test/t/join_nested.test @@ -683,7 +683,7 @@ SELECT t2.a,t2.b,t3.a,t3.b WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL); SELECT t2.a,t2.b,t3.a,t3.b - FROM t2 LEFT JOIN (t3) ON t2.b=t3.b + FROM t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL); ALTER TABLE t3 diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index 98eaa7a7774..2631a43386f 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -825,6 +825,9 @@ SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 FOR UPDATE; --error ER_ORDER_WITH_PROC +SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 + PROCEDURE ANALYSE(); +--error ER_ORDER_WITH_PROC SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 PROCEDURE ANALYSE() FOR UPDATE; @@ -832,7 +835,7 @@ SELECT 1 FROM (SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 FOR UPDATE) a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT 1 FROM (SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 PROCEDURE ANALYSE() FOR UPDATE) a; @@ -841,7 +844,7 @@ SELECT 1 FROM t1 WHERE EXISTS(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 FOR UPDATE); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT 1 FROM t1 WHERE EXISTS(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 PROCEDURE ANALYSE() FOR UPDATE); @@ -851,7 +854,7 @@ UNION SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 FOR UPDATE; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT 1 FROM t1 UNION SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 @@ -867,7 +870,7 @@ UNION (SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 FOR UPDATE); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE (SELECT 1 FROM t1) UNION (SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 @@ -876,7 +879,7 @@ UNION --echo # "FOR UPDATE" tests SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1; -SELECT 1 FROM t1 FOR UPDATE UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1; +(SELECT 1 FROM t1 FOR UPDATE) UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1; SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 FOR UPDATE; @@ -889,10 +892,10 @@ SELECT 1 INTO @var17727401; SELECT 1 INTO @var17727401 FROM t1; SELECT 1 INTO @var17727401 FROM DUAL; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT 1 INTO @var17727401_1 FROM t1 INTO @var17727401_2; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT 1 INTO @var17727401_1 FROM DUAL INTO @var17727401_2; @@ -902,45 +905,45 @@ SELECT 1 FROM t1 WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1 INTO @var1772740 --error ER_PARSE_ERROR SELECT 1 FROM t1 WHERE 1 INTO @var17727401 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT 1 INTO @var17727401_1 FROM t1 WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1 INTO @var17727401_2; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT (SELECT 1 FROM t1 INTO @var17727401); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT 1 FROM (SELECT 1 FROM t1 INTO @var17727401) a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT EXISTS(SELECT 1 FROM t1 INTO @var17727401); --error ER_PARSE_ERROR SELECT 1 FROM t1 INTO @var17727401 UNION SELECT 1 FROM t1 INTO t1; ---error ER_WRONG_USAGE +--error ER_SP_UNDECLARED_VAR (SELECT 1 FROM t1 INTO @var17727401) UNION (SELECT 1 FROM t1 INTO t1); SELECT 1 FROM t1 UNION SELECT 1 FROM t1 INTO @var17727401; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT 1 INTO @var17727401 FROM t1 PROCEDURE ANALYSE(); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT 1 FROM t1 PROCEDURE ANALYSE() INTO @var17727401; --echo # ORDER and LIMIT clause combinations # Limited support for (SELECT ...) ORDER/LIMIT: -(SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1; -(SELECT 1 FROM t1 LIMIT 1) LIMIT 1; +# (SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1; +# (SELECT 1 FROM t1 LIMIT 1) LIMIT 1; ---error ER_PARSE_ERROR -((SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1) ORDER BY 1; ---error ER_PARSE_ERROR -((SELECT 1 FROM t1 LIMIT 1) LIMIT 1) LIMIT 1; +#--error ER_PARSE_ERROR +# ((SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1) ORDER BY 1; +#--error ER_PARSE_ERROR +# ((SELECT 1 FROM t1 LIMIT 1) LIMIT 1) LIMIT 1; -(SELECT 1 FROM t1 ORDER BY 1) LIMIT 1; -(SELECT 1 FROM t1 LIMIT 1) ORDER BY 1; +# (SELECT 1 FROM t1 ORDER BY 1) LIMIT 1; +# (SELECT 1 FROM t1 LIMIT 1) ORDER BY 1; --error ER_PARSE_ERROR ((SELECT 1 FROM t1 ORDER BY 1) LIMIT 1) ORDER BY 1); @@ -1276,22 +1279,22 @@ DROP TABLE t1; --echo # CREATE TABLE t1 (i INT); ---error ER_WRONG_USAGE +--error ER_CANT_USE_OPTION_HERE (SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)) UNION (SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)); ---error ER_WRONG_USAGE +--error ER_CANT_USE_OPTION_HERE (SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)) UNION SELECT * FROM t1 PROCEDURE ANALYSE(10, 10); ---error ER_WRONG_USAGE +--error ER_CANT_USE_OPTION_HERE (SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)) UNION (SELECT 1); ---error ER_WRONG_USAGE +--error ER_CANT_USE_OPTION_HERE (SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)) UNION SELECT 1; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index c354032bc36..9e9eaa49a37 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -620,8 +620,8 @@ select c from t1 order by c, id; set max_sort_length=default; # sql_mode select '1' || '3' from t1; -set SQL_MODE=oracle; -select '1' || '3' from t1; +#set SQL_MODE=oracle; +#select '1' || '3' from t1; set SQL_MODE=default; drop table t1; # group_concat_max_len @@ -1534,22 +1534,21 @@ SET GLOBAL query_cache_size= default; # CREATE TABLE t1( a INT ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SET @v = ( SELECT SQL_CACHE 1 ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SET @v = ( SELECT SQL_NO_CACHE 1 ); # -# Keywords 'SQL_CACHE' and 'SQL_NO_CACHE' are allowed as column names. -# Hence the error messages are not intuitive. +# Keywords 'SQL_CACHE' and 'SQL_NO_CACHE'. # ---error ER_BAD_FIELD_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT a FROM t1 WHERE a IN ( SELECT SQL_CACHE a FROM t1 ); ---error ER_BAD_FIELD_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT a FROM t1 WHERE a IN ( SELECT SQL_NO_CACHE a FROM t1 ); ---error ER_BAD_FIELD_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT ( SELECT SQL_CACHE a FROM t1 ); ---error ER_BAD_FIELD_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT ( SELECT SQL_NO_CACHE a FROM t1 ); SELECT SQL_CACHE * FROM t1; @@ -1560,16 +1559,16 @@ SELECT SQL_NO_CACHE * FROM t1; SELECT * FROM t1 UNION SELECT SQL_CACHE * FROM t1; --error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1; ---error ER_BAD_FIELD_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a IN (SELECT SQL_CACHE a FROM t1); ---error ER_BAD_FIELD_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a IN (SELECT a FROM t1 UNION SELECT SQL_CACHE a FROM t1); --error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1; ---error ER_BAD_FIELD_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a IN (SELECT SQL_NO_CACHE a FROM t1); ---error ER_BAD_FIELD_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a IN (SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1); --error ER_WRONG_USAGE @@ -1584,10 +1583,10 @@ SELECT SQL_CACHE * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1; SELECT SQL_NO_CACHE * FROM t1 UNION SELECT SQL_CACHE * FROM t1; --error ER_CANT_USE_OPTION_HERE SELECT SQL_NO_CACHE * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1; ---error ER_BAD_FIELD_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT SQL_CACHE * FROM t1 WHERE a IN (SELECT SQL_NO_CACHE a FROM t1); ---error ER_BAD_FIELD_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT SQL_CACHE * FROM t1 WHERE a IN (SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1); diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 262013e0d2c..42754cea19f 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -558,7 +558,7 @@ CREATE VIEW v1 AS SELECT SQL_CACHE SQL_NO_CACHE NOW(); --error ER_WRONG_USAGE CREATE VIEW v1 AS SELECT SQL_NO_CACHE SQL_CACHE NOW(); ---error ER_WRONG_USAGE +--error ER_DUP_ARGUMENT CREATE VIEW v1 AS SELECT SQL_CACHE SQL_NO_CACHE SQL_CACHE NOW(); # Check CREATE VIEW in a prepared statement in a procedure. diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index aa537d3596b..8e6a6c29f59 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -1785,16 +1785,16 @@ CREATE TABLE t1 (i INT); # We do not have to drop this procedure and view because they won't be # created. ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO @a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file"; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file"; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE(); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 FROM (SELECT 1) AS d1 into @w; --error ER_VIEW_SELECT_VARIABLE CREATE PROCEDURE bug20953(i INT) CREATE VIEW v AS SELECT i; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 94d779de203..4e8354a99be 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -440,7 +440,7 @@ drop procedure b| drop procedure if exists b2| --enable_warnings create procedure b2(x int) -repeat(select 1 into outfile 'b2'); +repeat(select 1) into outfile 'b2'; insert into test.t1 values (repeat("b2",3), x); set x = x-1; until x = 0 end repeat| @@ -8221,19 +8221,20 @@ DROP FUNCTION f1; # the mysql.proc table. # ---disable_warnings -drop procedure if exists p; ---enable_warnings -set @old_mode= @@sql_mode; -set @@sql_mode= cast(pow(2,32)-1 as unsigned integer); -select @@sql_mode into @full_mode; -create procedure p() as begin end; -call p(); -set @@sql_mode= @old_mode; +# XXX Oracle parser is not fixed jet +#--disable_warnings +#drop procedure if exists p; +#--enable_warnings +#set @old_mode= @@sql_mode; +#set @@sql_mode= cast(pow(2,32)-1 as unsigned integer); +#select @@sql_mode into @full_mode; +#create procedure p() as begin end; +#call p(); +#set @@sql_mode= @old_mode; # Rename SQL modes that differ in name between the server and the table definition. -select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; -select name from mysql.proc where name = 'p' and sql_mode = @full_mode; -drop procedure p; +#select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode; +#select name from mysql.proc where name = 'p' and sql_mode = @full_mode; +#drop procedure p; # # Bug#43962 "Packets out of order" calling a SHOW TABLE STATUS @@ -9581,6 +9582,155 @@ drop procedure p; drop view v; drop table t, tmp_t; +--echo # +--echo # MDEV-14857: problem with 10.2.11 server crashing when +--echo # executing stored procedure +--echo # + +SET max_sp_recursion_depth=10; + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT); + +delimiter ||; + +CREATE PROCEDURE proc_0() +BEGIN + CALL empty_1(); + CALL proc_1(); +END || + +CREATE PROCEDURE proc_1() +BEGIN + CALL proc_2(); + CALL proc_3(); + CALL proc_4(); + CALL proc_5(); +END || + +CREATE PROCEDURE proc_2() + CALL proc_6(); +|| + +CREATE PROCEDURE proc_3() +BEGIN + CALL empty_2(); + CALL empty_3(); +END || + +CREATE PROCEDURE proc_4() + CALL proc_7(); +|| + +CREATE PROCEDURE proc_5() + CALL proc_select(); +|| + +CREATE PROCEDURE proc_6() +BEGIN + CALL empty_4(); + CALL empty_5(); + CALL empty_6(); + CALL empty_7(); + CALL proc_8(); +END || + +CREATE PROCEDURE proc_7() + CALL proc_9('foo'); +|| + +CREATE PROCEDURE proc_8() + CALL proc_10(); +|| + +CREATE PROCEDURE proc_9(IN opt VARCHAR(40)) + IF LEFT(opt,1) <> '_' THEN + CALL proc_11(); + END IF; +|| + +CREATE PROCEDURE proc_10() + CALL proc_12(); +|| + +CREATE PROCEDURE proc_11() +BEGIN + CALL empty_8(); + CALL empty_9(); + CALL empty_10(); + CALL proc_13(); +END || + +CREATE PROCEDURE proc_12() +BEGIN + CALL empty_11(); + CALL empty_12(); + CALL empty_13(); +END || + +CREATE PROCEDURE proc_13() +BEGIN + CALL proc_9('_bar'); + CALL empty_14(); +END || + +delimiter ;|| + +CREATE PROCEDURE empty_1() BEGIN END ; +CREATE PROCEDURE empty_2() BEGIN END ; +CREATE PROCEDURE empty_3() BEGIN END ; +CREATE PROCEDURE empty_4() BEGIN END ; +CREATE PROCEDURE empty_5() BEGIN END ; +CREATE PROCEDURE empty_6() BEGIN END ; +CREATE PROCEDURE empty_7() BEGIN END ; +CREATE PROCEDURE empty_8() BEGIN END ; +CREATE PROCEDURE empty_9() BEGIN END ; +CREATE PROCEDURE empty_10() BEGIN END ; +CREATE PROCEDURE empty_11() BEGIN END ; +CREATE PROCEDURE empty_12() BEGIN END ; +CREATE PROCEDURE empty_13() BEGIN END ; +CREATE PROCEDURE empty_14() BEGIN END ; + +CREATE PROCEDURE proc_select() + SELECT * FROM t1 WHERE NOT EXISTS ( SELECT * FROM t2) +; + +CALL proc_0(); + +# Cleanup +DROP PROCEDURE empty_1; +DROP PROCEDURE empty_2; +DROP PROCEDURE empty_3; +DROP PROCEDURE empty_4; +DROP PROCEDURE empty_5; +DROP PROCEDURE empty_6; +DROP PROCEDURE empty_7; +DROP PROCEDURE empty_8; +DROP PROCEDURE empty_9; +DROP PROCEDURE empty_10; +DROP PROCEDURE empty_11; +DROP PROCEDURE empty_12; +DROP PROCEDURE empty_13; +DROP PROCEDURE empty_14; +DROP PROCEDURE proc_0; +DROP PROCEDURE proc_1; +DROP PROCEDURE proc_2; +DROP PROCEDURE proc_3; +DROP PROCEDURE proc_4; +DROP PROCEDURE proc_5; +DROP PROCEDURE proc_6; +DROP PROCEDURE proc_7; +DROP PROCEDURE proc_8; +DROP PROCEDURE proc_9; +DROP PROCEDURE proc_10; +DROP PROCEDURE proc_11; +DROP PROCEDURE proc_12; +DROP PROCEDURE proc_13; +DROP PROCEDURE proc_select; +DROP TABLE t1, t2; + +SET max_sp_recursion_depth=default; + --echo #End of 10.1 tests --echo # diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test index 97a694f585a..921b0e44c43 100644 --- a/mysql-test/t/sql_mode.test +++ b/mysql-test/t/sql_mode.test @@ -25,7 +25,8 @@ show create table t1; set @@sql_mode="no_field_options,mysql323,mysql40"; show variables like 'sql_mode'; show create table t1; -set sql_mode="postgresql,oracle,mssql,db2,maxdb"; +# set sql_mode="postgresql,oracle,mssql,db2,maxdb"; +set sql_mode="postgresql,mssql,db2,maxdb"; select @@sql_mode; show create table t1; drop table t1; @@ -521,7 +522,7 @@ SET sql_mode=DEFAULT; CREATE OR REPLACE TABLE t1 (a TEXT); PREPARE stmt FROM 'INSERT INTO t1 (a) VALUES (2||3)'; EXECUTE stmt; -SET sql_mode=ORACLE; +# SET sql_mode=ORACLE; EXECUTE stmt; ALTER TABLE t1 ADD b INT; EXECUTE stmt; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 7412eae8ecf..01e12f6d8d4 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -53,7 +53,7 @@ SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c O SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1); SELECT 1 IN (SELECT 1); SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); --- error ER_PARSE_ERROR +-- error ER_CANT_USE_OPTION_HERE select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1)); -- error ER_PARSE_ERROR SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1)); @@ -99,7 +99,8 @@ select (select a from t3), a from t2; select * from t2 where t2.a=(select a from t1); insert into t3 values (6),(7),(3); select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1); -(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3; +(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) +union (select * from t4 order by a limit 2) order by a limit 3; (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2; @@ -2606,8 +2607,6 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS (SELECT i FROM t1) ); -#TODO:not supported ---error ER_PARSE_ERROR SELECT * FROM t1 WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); @@ -4231,31 +4230,31 @@ INSERT INTO t1 VALUES (1),(2); CREATE TABLE t2( a INT, b INT ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM ( SELECT 1 a UNION SELECT a INTO @var FROM t1 WHERE a = 2 ) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM ( SELECT 1 a UNION SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2 ) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM ( SELECT 1 a UNION @@ -4283,25 +4282,25 @@ SELECT * FROM ( SELECT * FROM ((SELECT 1 a) UNION SELECT 1 a) q; SELECT * FROM (SELECT 1 a UNION (SELECT 1 a)) alias; SELECT * FROM (SELECT 1 UNION SELECT 1) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM ((SELECT 1 a INTO @a)) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a; SELECT * FROM (SELECT 1 a ORDER BY a) t1a; @@ -4315,7 +4314,7 @@ SELECT * FROM (SELECT 1 a UNION SELECT 1 a ORDER BY a LIMIT 1) t1a; # aliases after. # SELECT * FROM t1 JOIN (SELECT 1 UNION SELECT 1) alias ON 1; ---error ER_DERIVED_MUST_HAVE_ALIAS +--error ER_PARSE_ERROR SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1; --error ER_PARSE_ERROR SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 1; @@ -4326,10 +4325,14 @@ SELECT * FROM t1 JOIN (t1 t1a) t1a ON 1; --error ER_PARSE_ERROR SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 1; +--error ER_PARSE_ERROR SELECT * FROM t1 JOIN (t1 t1a) ON 1; +--error ER_PARSE_ERROR SELECT * FROM t1 JOIN ((t1 t1a)) ON 1; +--error ER_PARSE_ERROR SELECT * FROM (t1 t1a); +--error ER_PARSE_ERROR SELECT * FROM ((t1 t1a)); SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1; @@ -4347,41 +4350,41 @@ SELECT * FROM t1 WHERE a = ALL ( SELECT 1 ); SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION SELECT 1 ); SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); SELECT * FROM t1 WHERE a = ( SELECT 1 ); SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT ( SELECT 1 INTO @v ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT ( SELECT 1 INTO OUTFILE 'file' ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT ( SELECT 1 INTO DUMPFILE 'file' ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT ( SELECT 1 UNION SELECT 1 INTO @v ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' ); # Make sure context is popped when we leave the nested select @@ -4393,12 +4396,9 @@ SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2); # Make sure the parser does not allow nested UNIONs anywhere ---error ER_PARSE_ERROR SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ); ---error ER_PARSE_ERROR ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1; ---error ER_PARSE_ERROR SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ); --error ER_PARSE_ERROR SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1; @@ -4407,25 +4407,19 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1)); --error ER_PARSE_ERROR SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ); ---error ER_DERIVED_MUST_HAVE_ALIAS +--error ER_PARSE_ERROR SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ); SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a; SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a; ---error ER_PARSE_ERROR SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ); ---error ER_PARSE_ERROR SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ); ---error ER_PARSE_ERROR SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ); ---error ER_PARSE_ERROR SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) ); --error ER_PARSE_ERROR SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ); ---error ER_PARSE_ERROR SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ); ---error ER_PARSE_ERROR SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ); --error ER_PARSE_ERROR SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ); @@ -4435,17 +4429,17 @@ SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v ); SELECT EXISTS(SELECT 1+1); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT EXISTS(SELECT 1+1 INTO @test); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v ); ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v ); DROP TABLE t1, t2; diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index f90f1e2e927..74106385cf9 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -1462,7 +1462,7 @@ INSERT IGNORE INTO t3 VALUES (0); SELECT alias1.f11 AS field2 FROM ( t3 AS alias2 JOIN t1 AS alias3 ON alias3.f10 = 1) -LEFT JOIN ( t2 AS alias1 ) ON alias3.f11 = 1 +LEFT JOIN t2 AS alias1 ON alias3.f11 = 1 WHERE alias2.f11 IN ( SELECT f11 FROM t2 ) GROUP BY field2 ; diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index bfd3b28a5b2..66c11b61435 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1848,9 +1848,9 @@ drop database mysqltest4; CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM; INSERT INTO t1 VALUES (0),(8); -SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2)); +SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2); PREPARE stmt FROM " -SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2)) +SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2) "; execute stmt; execute stmt; diff --git a/mysql-test/t/test.test b/mysql-test/t/test.test new file mode 100644 index 00000000000..3a4534dcf94 --- /dev/null +++ b/mysql-test/t/test.test @@ -0,0 +1,26 @@ +select 1 union ( select 2 union select 3); +explain extended +select 1 union ( select 2 union select 3); +select 1 union ( select 1 union select 1); +explain extended +select 1 union ( select 1 union select 1); +select 1 union all ( select 1 union select 1); +explain extended +select 1 union all ( select 1 union select 1); +select 1 union ( select 1 union all select 1); +explain extended +select 1 union ( select 1 union all select 1); +select 1 union select 1 union all select 1; +explain extended +select 1 union select 1 union all select 1; + +(select 1 as a) union (select 2) order by a; +explain extended +(select 1 as a) union (select 2) order by a; +/* select#1 */ select 1 AS `a` union /* select#2 */ select 2 AS `2` order by `a`; +explain extended +/* select#1 */ select 1 AS `a` union /* select#2 */ select 2 AS `2` order by `a`; + +select 1 union ( select 1 union (select 1 union (select 1 union select 1))); +explain extended all +select 1 union ( select 1 union (select 1 union (select 1 union select 1))); diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index a2e1fd09ade..47fc07cac3b 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -973,12 +973,12 @@ DROP TABLE t1; # # Bug#23345: Wrongly allowed INTO in a non-last select of a UNION. +# (fixed) # ---error 1221 +--error ER_CANT_USE_OPTION_HERE (select 1 into @var) union (select 1); (select 1) union (select 1 into @var); -select @var; ---error 1172 +--error ER_TOO_MANY_ROWS (select 2) union (select 1 into @var); # @@ -1102,11 +1102,11 @@ SELECT a INTO DUMPFILE 'union.out.file2' FROM ( SELECT a FROM t1 UNION SELECT a INTO @v FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1; SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; -- echo # Tests fix in parser rule query_expression_body. @@ -1361,15 +1361,15 @@ SET @@global.slow_query_log= @old_slow_query_log; CREATE TABLE t1 (a int); CREATE TABLE t2 (b int); CREATE TABLE t3 (c int); -SELECT a FROM t1 UNION SELECT b FROM t2 JOIN (t3) ON ( t2.b = t3.c ); +SELECT a FROM t1 UNION SELECT b FROM t2 JOIN t3 ON ( t2.b = t3.c ); DROP TABLE t1, t2, t3; CREATE TABLE t1 (pk int NOT NULL); CREATE TABLE t2 (pk int NOT NULL, fk int NOT NULL); -SELECT t1.pk FROM t1 LEFT JOIN (t2) ON (t1.pk = t2.fk) +SELECT t1.pk FROM t1 LEFT JOIN t2 ON (t1.pk = t2.fk) UNION -SELECT t1.pk FROM t1 LEFT JOIN (t2) ON (t1.pk = t2.fk); +SELECT t1.pk FROM t1 LEFT JOIN t2 ON (t1.pk = t2.fk); DROP TABLE t1,t2; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 00be48c172c..b5132e94b1f 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -832,12 +832,12 @@ drop view v4, v3, v2, v1; # # VIEW over SELECT with prohibited clauses # --- error ER_PARSE_ERROR +-- error ER_CANT_USE_OPTION_HERE create view v1 as select 5 into @w; --- error ER_PARSE_ERROR +-- error ER_CANT_USE_OPTION_HERE create view v1 as select 5 into outfile 'ttt'; create table t1 (a int); --- error ER_PARSE_ERROR +-- error ER_CANT_USE_OPTION_HERE create view v1 as select a from t1 procedure analyse(); # now derived tables are allowed create view v1 as select 1 from (select 1) as d1; @@ -3178,7 +3178,7 @@ DROP VIEW IF EXISTS v1; let $query = SELECT * FROM (SELECT 1) AS t into @w; eval $query; ---error ER_PARSE_ERROR +--error ER_CANT_USE_OPTION_HERE eval CREATE VIEW v1 AS $query; --echo # Previously the following would fail. eval $query; @@ -4111,7 +4111,7 @@ CREATE OR REPLACE view v1 AS ; SELECT 1 -FROM (( SELECT 1 +FROM ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4119,8 +4119,8 @@ FROM (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t1) -LEFT OUTER JOIN (( SELECT 1 +) t1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4128,8 +4128,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t2) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t2 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4137,8 +4137,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t3) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t3 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4146,8 +4146,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t4) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t4 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4155,8 +4155,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t5) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t5 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4164,8 +4164,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t6) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t6 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4173,8 +4173,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t7) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t7 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -4182,18 +4182,18 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t8) ON 1=1 +) t8 ON 1=1 ; SELECT 1 -FROM (v1 t1) -LEFT OUTER JOIN (v1 t2) ON 1=1 -LEFT OUTER JOIN (v1 t3) ON 1=1 -LEFT OUTER JOIN (v1 t4) ON 1=1 -LEFT OUTER JOIN (v1 t5) ON 1=1 -LEFT OUTER JOIN (v1 t6) ON 1=1 -LEFT OUTER JOIN (v1 t7) ON 1=1 -LEFT OUTER JOIN (v1 t8) ON 1=1 +FROM v1 t1 +LEFT OUTER JOIN v1 t2 ON 1=1 +LEFT OUTER JOIN v1 t3 ON 1=1 +LEFT OUTER JOIN v1 t4 ON 1=1 +LEFT OUTER JOIN v1 t5 ON 1=1 +LEFT OUTER JOIN v1 t6 ON 1=1 +LEFT OUTER JOIN v1 t7 ON 1=1 +LEFT OUTER JOIN v1 t8 ON 1=1 ; drop view v1; @@ -5202,7 +5202,7 @@ CREATE OR REPLACE view v1 AS ; SELECT 1 -FROM (( SELECT 1 +FROM ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5210,8 +5210,8 @@ FROM (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t1) -LEFT OUTER JOIN (( SELECT 1 +) t1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5219,8 +5219,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t2) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t2 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5228,8 +5228,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t3) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t3 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5237,8 +5237,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t4) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t4 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5246,8 +5246,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t5) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t5 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5255,8 +5255,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t6) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t6 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5264,8 +5264,8 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t7) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 +) t7 ON 1=1 +LEFT OUTER JOIN ( SELECT 1 FROM t1 a_alias_1 LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 @@ -5273,18 +5273,18 @@ LEFT OUTER JOIN (( SELECT 1 LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t8) ON 1=1 +) t8 ON 1=1 ; SELECT 1 -FROM (v1 t1) -LEFT OUTER JOIN (v1 t2) ON 1=1 -LEFT OUTER JOIN (v1 t3) ON 1=1 -LEFT OUTER JOIN (v1 t4) ON 1=1 -LEFT OUTER JOIN (v1 t5) ON 1=1 -LEFT OUTER JOIN (v1 t6) ON 1=1 -LEFT OUTER JOIN (v1 t7) ON 1=1 -LEFT OUTER JOIN (v1 t8) ON 1=1 +FROM v1 t1 +LEFT OUTER JOIN v1 t2 ON 1=1 +LEFT OUTER JOIN v1 t3 ON 1=1 +LEFT OUTER JOIN v1 t4 ON 1=1 +LEFT OUTER JOIN v1 t5 ON 1=1 +LEFT OUTER JOIN v1 t6 ON 1=1 +LEFT OUTER JOIN v1 t7 ON 1=1 +LEFT OUTER JOIN v1 t8 ON 1=1 ; drop view v1; diff --git a/sql/events.cc b/sql/events.cc index 9ecc55fbdf0..9879a32c0a9 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -807,12 +807,13 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */) */ if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS) { - DBUG_ASSERT(thd->lex->select_lex.db); - if (!is_infoschema_db(thd->lex->select_lex.db) && // There is no events in I_S - check_access(thd, EVENT_ACL, thd->lex->select_lex.db, + DBUG_ASSERT(thd->lex->first_select_lex()->db); + if (!is_infoschema_db(thd->lex->first_select_lex()->db) && // There is no events in I_S + check_access(thd, EVENT_ACL, thd->lex->first_select_lex()->db, NULL, NULL, 0, 0)) DBUG_RETURN(1); - db= normalize_db_name(thd->lex->select_lex.db, db_tmp, sizeof(db_tmp)); + db= normalize_db_name(thd->lex->first_select_lex()->db, db_tmp, + sizeof(db_tmp)); } ret= db_repository->fill_schema_events(thd, tables, db); diff --git a/sql/item.cc b/sql/item.cc index 92459bd6f7f..9b2e37cbce3 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -738,7 +738,13 @@ Item_ident::Item_ident(THD *thd, Name_resolution_context *context_arg, alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX), cached_table(0), depended_from(0), can_be_depended(TRUE) { + DBUG_ENTER("Item_ident::Item_ident"); + DBUG_PRINT("XXX", ("Name: %s cur sel: %p (%d)", field_name.str, + thd->lex->current_select, + (thd->lex->current_select ? + thd->lex->current_select->select_number : 0))); name= *field_name_arg; + DBUG_VOID_RETURN; } @@ -747,13 +753,17 @@ Item_ident::Item_ident(THD *thd, TABLE_LIST *view_arg, :Item_result_field(thd), orig_db_name(NullS), orig_table_name(view_arg->table_name), orig_field_name(*field_name_arg), - context(&view_arg->view->select_lex.context), + /* TODO: suspicious use of first_select_lex */ + context(&view_arg->view->first_select_lex()->context), db_name(NullS), table_name(view_arg->alias), field_name(*field_name_arg), alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX), cached_table(NULL), depended_from(NULL), can_be_depended(TRUE) { + DBUG_ENTER("Item_ident::Item_ident"); + DBUG_PRINT("XXX", ("Name: %s", field_name.str)); name= *field_name_arg; + DBUG_VOID_RETURN; } @@ -775,7 +785,11 @@ Item_ident::Item_ident(THD *thd, Item_ident *item) cached_table(item->cached_table), depended_from(item->depended_from), can_be_depended(item->can_be_depended) -{} +{ + DBUG_ENTER("Item_ident::Item_ident"); + DBUG_PRINT("XXX", ("Name: %s", field_name.str)); + DBUG_VOID_RETURN; +} void Item_ident::cleanup() { diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 55196b451de..7f2371d6955 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -123,13 +123,6 @@ void Item_subselect::init(st_select_lex *select_lex, else engine= new subselect_single_select_engine(select_lex, result, this); } - { - SELECT_LEX *upper= unit->outer_select(); - if (upper->parsing_place == IN_HAVING) - upper->subquery_in_having= 1; - /* The subquery is an expression cache candidate */ - upper->expr_cache_may_be_used[upper->parsing_place]= TRUE; - } DBUG_PRINT("info", ("engine: 0x%lx", (ulong)engine)); DBUG_VOID_RETURN; } @@ -219,7 +212,8 @@ Item_subselect::~Item_subselect() if (own_engine) delete engine; else - engine->cleanup(); + if (engine) // can be empty in case of EOM + engine->cleanup(); engine= NULL; DBUG_VOID_RETURN; } @@ -243,6 +237,14 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) DBUG_ASSERT(unit->thd == thd); + { + SELECT_LEX *upper= unit->outer_select(); + if (upper->parsing_place == IN_HAVING) + upper->subquery_in_having= 1; + /* The subquery is an expression cache candidate */ + upper->expr_cache_may_be_used[upper->parsing_place]= TRUE; + } + status_var_increment(thd_param->status_var.feature_subquery); DBUG_ASSERT(fixed == 0); diff --git a/sql/log_event.cc b/sql/log_event.cc index 73987a562fa..f9b24d1f544 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -4083,7 +4083,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, have to use the transactional cache to ensure we don't calculate any checksum for the CREATE part. */ - trx_cache= (lex->select_lex.item_list.elements && + trx_cache= (lex->first_select_lex()->item_list.elements && thd->is_current_stmt_binlog_format_row()) || (thd->variables.option_bits & OPTION_GTID_BEGIN); use_cache= (lex->tmp_table() && @@ -6970,8 +6970,8 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi, ex.skip_lines = skip_lines; List<Item> field_list; - thd->lex->select_lex.context.resolve_in_table_list_only(&tables); - set_fields(tables.db, field_list, &thd->lex->select_lex.context); + thd->lex->first_select_lex()->context.resolve_in_table_list_only(&tables); + set_fields(tables.db, field_list, &thd->lex->first_select_lex()->context); thd->variables.pseudo_thread_id= thread_id; if (net) { diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 01aff0a9e7d..3859a81e528 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -4535,7 +4535,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records) if (max_cost != DBL_MAX && (busy_blocks+index_reads_cost) >= n_blocks) return 1; */ - JOIN *join= param->thd->lex->select_lex.join; + JOIN *join= param->thd->lex->first_select_lex()->join; if (!join || join->table_count == 1) { /* No join, assume reading is done in one 'sweep' */ diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc index 1d6fb4dabfe..b723385bc0a 100644 --- a/sql/opt_table_elimination.cc +++ b/sql/opt_table_elimination.cc @@ -617,7 +617,7 @@ void eliminate_tables(JOIN *join) we should also take into account tables mentioned in "val". */ if (join->thd->lex->sql_command == SQLCOM_INSERT_SELECT && - join->select_lex == &thd->lex->select_lex) + join->select_lex == thd->lex->first_select_lex()) { List_iterator<Item> val_it(thd->lex->value_list); while ((item= val_it++)) @@ -640,7 +640,7 @@ void eliminate_tables(JOIN *join) used_tables |= (*(cur_list->item))->used_tables(); } - if (join->select_lex == &thd->lex->select_lex) + if (join->select_lex == thd->lex->first_select_lex()) { /* Multi-table UPDATE: don't eliminate tables referred from SET statement */ diff --git a/sql/set_var.cc b/sql/set_var.cc index 311b33bc0dd..bf80a836b9c 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -741,7 +741,7 @@ int sql_set_variables(THD *thd, List<set_var_base> *var_list, bool free) err: if (free) - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, thd->lex->first_select_lex()); DBUG_RETURN(error); } diff --git a/sql/sp.cc b/sql/sp.cc index 8f4acd40f10..bc7da657462 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -807,7 +807,6 @@ static sp_head *sp_compile(THD *thd, String *defstr, sql_mode_t sql_mode, else { sp= thd->lex->sphead; - sp->set_select_number(thd->select_number); } thd->pop_internal_handler(); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 5bd4ff95f9c..781f903e859 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -303,7 +303,7 @@ sp_get_flags_for_command(LEX *lex) - EXPLAIN DELETE ... - ANALYZE DELETE ... */ - if (lex->select_lex.item_list.is_empty() && + if (lex->first_select_lex()->item_list.is_empty() && !lex->describe && !lex->analyze_stmt) flags= 0; else @@ -545,6 +545,7 @@ sp_head::sp_head(const Sp_handler *sph) Database_qualified_name(&null_clex_str, &null_clex_str), m_handler(sph), m_flags(0), + m_tmp_query(NULL), m_explicit_name(false), /* FIXME: the only use case when name is NULL is events, and it should @@ -558,7 +559,7 @@ sp_head::sp_head(const Sp_handler *sph) m_defstr(null_clex_str), m_sp_cache_version(0), m_creation_ctx(0), - unsafe_flags(0), m_select_number(1), + unsafe_flags(0), m_created(0), m_modified(0), m_recursion_level(0), @@ -580,6 +581,7 @@ sp_head::sp_head(const Sp_handler *sph) m_backpatch_goto.empty(); m_cont_backpatch.empty(); m_lex.empty(); + m_stmt_lex.empty(); my_hash_init(&m_sptabs, system_charset_info, 0, 0, 0, sp_table_key, 0, 0); my_hash_init(&m_sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0); @@ -701,6 +703,7 @@ sp_head::~sp_head() THD::lex. It is safe to not update LEX::ptr because further query string parsing and execution will be stopped anyway. */ + DBUG_ASSERT(m_lex.elements == m_stmt_lex.elements); while ((lex= (LEX *)m_lex.pop())) { THD *thd= lex->thd; @@ -708,6 +711,7 @@ sp_head::~sp_head() lex_end(thd->lex); delete thd->lex; thd->lex= lex; + thd->stmt_lex= m_stmt_lex.pop(); } my_hash_free(&m_sptabs); @@ -1002,7 +1006,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) backup_arena; query_id_t old_query_id; TABLE *old_derived_tables; - LEX *old_lex; + LEX *old_lex, *old_stmt_lex; Item_change_list old_change_list; String old_packet; uint old_server_status; @@ -1105,6 +1109,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) do it in each instruction */ old_lex= thd->lex; + old_stmt_lex= thd->stmt_lex; /* We should also save Item tree change list to avoid rollback something too early in the calling query. @@ -1251,6 +1256,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) DBUG_ASSERT(thd->change_list.is_empty()); old_change_list.move_elements_to(&thd->change_list); thd->lex= old_lex; + thd->stmt_lex= old_stmt_lex; thd->set_query_id(old_query_id); DBUG_ASSERT(!thd->derived_tables); thd->derived_tables= old_derived_tables; @@ -2041,26 +2047,8 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) if (!err_status) { - /* - Normally the counter is not reset between parsing and first execution, - but it is possible in case of error to have parsing on one CALL and - first execution (where VIEW will be parsed and added). So we store the - counter after parsing and restore it before execution just to avoid - repeating SELECT numbers. - */ - thd->select_number= m_select_number; - err_status= execute(thd, TRUE); DBUG_PRINT("info", ("execute returned %d", (int) err_status)); - /* - This execution of the SP was aborted with an error (e.g. "Table not - found"). However it might still have consumed some numbers from the - thd->select_number counter. The next sp->exec() call must not use the - consumed numbers, so we remember the first free number (We know that - nobody will use it as this execution has stopped with an error). - */ - if (err_status) - set_select_number(thd->select_number); } if (save_log_general) @@ -2161,10 +2149,11 @@ sp_head::reset_lex(THD *thd, sp_lex_local *sublex) { DBUG_ENTER("sp_head::reset_lex"); LEX *oldlex= thd->lex; + LEX *oldstmtlex= thd->stmt_lex; - thd->set_local_lex(sublex); + thd->set_local_lex(sublex, sublex); - DBUG_RETURN(m_lex.push_front(oldlex)); + DBUG_RETURN(m_lex.push_front(oldlex) || m_stmt_lex.push_front(oldstmtlex)); } @@ -3032,7 +3021,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, We should not save old value since it is saved/restored in sp_head::execute() when we are entering/leaving routine. */ - thd->lex= m_lex; + thd->lex= thd->stmt_lex= m_lex; thd->set_query_id(next_query_id()); diff --git a/sql/sp_head.h b/sql/sp_head.h index 977e20a07b9..23e1e1db54a 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -235,7 +235,6 @@ class sp_head :private Query_arena, */ uint32 unsafe_flags; - uint m_select_number; public: inline Stored_program_creation_ctx *get_creation_ctx() { @@ -572,10 +571,12 @@ class sp_head :private Query_arena, { DBUG_ENTER("sp_head::restore_lex"); LEX *oldlex= (LEX *) m_lex.pop(); + LEX *oldstmtlex= (LEX *) m_stmt_lex.pop(); if (!oldlex) DBUG_RETURN(false); // Nothing to restore LEX *sublex= thd->lex; - if (thd->restore_from_local_lex_to_old_lex(oldlex))// This restores thd->lex + // This restores thd->lex and thd->stmt_lex + if (thd->restore_from_local_lex_to_old_lex(oldlex, oldstmtlex)) DBUG_RETURN(true); if (!sublex->sp_lex_in_use) { @@ -818,8 +819,6 @@ class sp_head :private Query_arena, sp_pcontext *get_parse_context() { return m_pcont; } - void set_select_number(uint num) { m_select_number= num; } - bool check_execute_access(THD *thd) const; private: @@ -829,6 +828,7 @@ class sp_head :private Query_arena, sp_pcontext *m_pcont; ///< Parse context List<LEX> m_lex; ///< Temp. store for the other lex + List<LEX> m_stmt_lex; ///< Temp. store for the other stmt_lex DYNAMIC_ARRAY m_instr; ///< The "instructions" enum backpatch_instr_type { GOTO, CPOP, HPOP }; diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 6b418e9e387..7f6d48d838e 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -164,9 +164,10 @@ bool sp_rcontext::resolve_type_ref(THD *thd, Column_definition *def, // Make %TYPE variables see temporary tables that shadow permanent tables thd->temporary_tables= open_tables_state_backup.temporary_tables; - if ((table_list= lex.select_lex.add_table_to_list(thd, ref, NULL, 0, - TL_READ_NO_INSERT, - MDL_SHARED_READ)) && + if ((table_list= + lex.first_select_lex()->add_table_to_list(thd, ref, NULL, 0, + TL_READ_NO_INSERT, + MDL_SHARED_READ)) && !check_table_access(thd, SELECT_ACL, table_list, TRUE, UINT_MAX, FALSE) && !open_tables_only_view_structure(thd, table_list, thd->mdl_context.has_locks())) @@ -223,9 +224,10 @@ bool sp_rcontext::resolve_table_rowtype_ref(THD *thd, // Make %ROWTYPE variables see temporary tables that shadow permanent tables thd->temporary_tables= open_tables_state_backup.temporary_tables; - if ((table_list= lex.select_lex.add_table_to_list(thd, ref, NULL, 0, - TL_READ_NO_INSERT, - MDL_SHARED_READ)) && + if ((table_list= + lex.first_select_lex()->add_table_to_list(thd, ref, NULL, 0, + TL_READ_NO_INSERT, + MDL_SHARED_READ)) && !check_table_access(thd, SELECT_ACL, table_list, TRUE, UINT_MAX, FALSE) && !open_tables_only_view_structure(thd, table_list, thd->mdl_context.has_locks())) diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index ce12b73a9e2..604b9b6b83f 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -306,7 +306,7 @@ static bool open_only_one_table(THD* thd, TABLE_LIST* table, bool is_view_operator_func) { LEX *lex= thd->lex; - SELECT_LEX *select= &lex->select_lex; + SELECT_LEX *select= lex->first_select_lex(); TABLE_LIST *save_next_global, *save_next_local; bool open_error; save_next_global= table->next_global; @@ -1296,7 +1296,7 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables) bool Sql_cmd_analyze_table::execute(THD *thd) { LEX *m_lex= thd->lex; - TABLE_LIST *first_table= m_lex->select_lex.table_list.first; + TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first; bool res= TRUE; thr_lock_type lock_type = TL_READ_NO_INSERT; DBUG_ENTER("Sql_cmd_analyze_table::execute"); @@ -1316,7 +1316,7 @@ bool Sql_cmd_analyze_table::execute(THD *thd) */ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } - m_lex->select_lex.table_list.first= first_table; + m_lex->first_select_lex()->table_list.first= first_table; m_lex->query_tables= first_table; error: @@ -1327,7 +1327,7 @@ bool Sql_cmd_analyze_table::execute(THD *thd) bool Sql_cmd_check_table::execute(THD *thd) { LEX *m_lex= thd->lex; - TABLE_LIST *first_table= m_lex->select_lex.table_list.first; + TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first; thr_lock_type lock_type = TL_READ_NO_INSERT; bool res= TRUE; DBUG_ENTER("Sql_cmd_check_table::execute"); @@ -1340,7 +1340,7 @@ bool Sql_cmd_check_table::execute(THD *thd) lock_type, 0, 0, HA_OPEN_FOR_REPAIR, 0, &handler::ha_check, &view_check); - m_lex->select_lex.table_list.first= first_table; + m_lex->first_select_lex()->table_list.first= first_table; m_lex->query_tables= first_table; error: @@ -1351,7 +1351,7 @@ bool Sql_cmd_check_table::execute(THD *thd) bool Sql_cmd_optimize_table::execute(THD *thd) { LEX *m_lex= thd->lex; - TABLE_LIST *first_table= m_lex->select_lex.table_list.first; + TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first; bool res= TRUE; DBUG_ENTER("Sql_cmd_optimize_table::execute"); @@ -1373,7 +1373,7 @@ bool Sql_cmd_optimize_table::execute(THD *thd) */ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } - m_lex->select_lex.table_list.first= first_table; + m_lex->first_select_lex()->table_list.first= first_table; m_lex->query_tables= first_table; error: @@ -1384,7 +1384,7 @@ bool Sql_cmd_optimize_table::execute(THD *thd) bool Sql_cmd_repair_table::execute(THD *thd) { LEX *m_lex= thd->lex; - TABLE_LIST *first_table= m_lex->select_lex.table_list.first; + TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first; bool res= TRUE; DBUG_ENTER("Sql_cmd_repair_table::execute"); @@ -1408,7 +1408,7 @@ bool Sql_cmd_repair_table::execute(THD *thd) */ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } - m_lex->select_lex.table_list.first= first_table; + m_lex->first_select_lex()->table_list.first= first_table; m_lex->query_tables= first_table; error: diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 3d1e4c0fa65..dc4e9a91a7e 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -198,7 +198,7 @@ bool Sql_cmd_alter_table::execute(THD *thd) { LEX *lex= thd->lex; /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */ - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); /* first table of first SELECT_LEX */ TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first; /* @@ -342,7 +342,7 @@ bool Sql_cmd_alter_table::execute(THD *thd) bool Sql_cmd_discard_import_tablespace::execute(THD *thd) { /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */ - SELECT_LEX *select_lex= &thd->lex->select_lex; + SELECT_LEX *select_lex= thd->lex->first_select_lex(); /* first table of first SELECT_LEX */ TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 93dd6239749..ed3093488f3 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7221,7 +7221,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context, TABLE_LIST *first_select_table= (select_insert ? tables->next_local: 0); - SELECT_LEX *select_lex= select_insert ? &thd->lex->select_lex : + SELECT_LEX *select_lex= select_insert ? thd->lex->first_select_lex() : thd->lex->current_select; if (select_lex->first_cond_optimization) { @@ -7249,7 +7249,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context, { /* new counting for SELECT of INSERT ... SELECT command */ first_select_table= 0; - thd->lex->select_lex.insert_tables= tablenr; + thd->lex->first_select_lex()->insert_tables= tablenr; tablenr= 0; } if(table_list->jtbm_subselect) @@ -7795,7 +7795,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves, from subquery of VIEW, because tables of subquery belongs to VIEW (see condition before prepare_check_option() call) */ - bool it_is_update= (select_lex == &thd->lex->select_lex) && + bool it_is_update= (select_lex == thd->lex->first_select_lex()) && thd->lex->which_check_option_applicable(); bool save_is_item_list_lookup= select_lex->is_item_list_lookup; TABLE_LIST *derived= select_lex->master_unit()->derived; @@ -7815,7 +7815,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves, for (table= tables; table; table= table->next_local) { - if (select_lex == &thd->lex->select_lex && + if (select_lex == thd->lex->first_select_lex() && select_lex->first_cond_optimization && table->merged_for_insert && table->prepare_where(thd, conds, FALSE)) diff --git a/sql/sql_base.h b/sql/sql_base.h index 7a8d27c9147..bacdad0b2f4 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -364,10 +364,12 @@ inline bool setup_fields_with_no_wrap(THD *thd, Ref_ptr_array ref_pointer_array, bool allow_sum_func) { bool res; - thd->lex->select_lex.no_wrap_view_item= TRUE; + SELECT_LEX *first= thd->lex->first_select_lex(); + DBUG_ASSERT(thd->lex->current_select == first); + first->no_wrap_view_item= TRUE; res= setup_fields(thd, ref_pointer_array, item, mark_used_columns, sum_func_list, allow_sum_func); - thd->lex->select_lex.no_wrap_view_item= FALSE; + first->no_wrap_view_item= FALSE; return res; } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index ed5a8f84127..ef9feb7a3bc 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -4110,13 +4110,13 @@ Query_cache::is_cacheable(THD *thd, LEX *lex, if (thd->lex->safe_to_cache_query && (thd->variables.query_cache_type == 1 || - (thd->variables.query_cache_type == 2 && (lex->select_lex.options & - OPTION_TO_QUERY_CACHE))) && + (thd->variables.query_cache_type == 2 && + (lex->first_select_lex()->options & OPTION_TO_QUERY_CACHE))) && qc_is_able_to_intercept_result(thd)) { DBUG_PRINT("qcache", ("options: %lx %lx type: %u", (long) OPTION_TO_QUERY_CACHE, - (long) lex->select_lex.options, + (long) lex->first_select_lex()->options, (int) thd->variables.query_cache_type)); if (!(table_count= process_and_count_tables(thd, tables_used, @@ -4137,7 +4137,7 @@ Query_cache::is_cacheable(THD *thd, LEX *lex, ("not interesting query: %d or not cacheable, options %lx %lx type: %u net->vio present: %u", (int) lex->sql_command, (long) OPTION_TO_QUERY_CACHE, - (long) lex->select_lex.options, + (long) lex->first_select_lex()->options, (int) thd->variables.query_cache_type, (uint) MY_TEST(qc_is_able_to_intercept_result(thd)))); DBUG_RETURN(0); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2a66427a26f..cddd5651a47 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1368,12 +1368,13 @@ void THD::init(void) } -bool THD::restore_from_local_lex_to_old_lex(LEX *oldlex) +bool THD::restore_from_local_lex_to_old_lex(LEX *oldlex, LEX *oldstmtlex) { DBUG_ASSERT(lex->sphead); if (lex->sphead->merge_lex(this, oldlex, lex)) return true; lex= oldlex; + stmt_lex= oldstmtlex; return false; } @@ -3665,6 +3666,7 @@ Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg, id(id_arg), mark_used_columns(MARK_COLUMNS_READ), lex(lex_arg), + stmt_lex(lex_arg), db(NULL), db_length(0) { @@ -3682,7 +3684,7 @@ void Statement::set_statement(Statement *stmt) { id= stmt->id; mark_used_columns= stmt->mark_used_columns; - lex= stmt->lex; + stmt_lex= lex= stmt->lex; query_string= stmt->query_string; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 2bbcf3cd436..c30b1e6e8a7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1052,6 +1052,21 @@ class Statement: public ilink, public Query_arena LEX_CSTRING name; /* name for named prepared statements */ LEX *lex; // parse tree descriptor + /* + LEX which represents current statement (conventional, SP or PS) + + For example during view parsing THD::lex will point to the views LEX and + THD::stmt_lex will point to LEX of the statement where the view will be + included + + Currently it is used to have always correct select numbering inside + statement (LEX::current_select_number) without storing and restoring a + global counter which was THD::select_number. + + TODO: make some unified statement representation (now SP has different) + to store such data like LEX::current_select_number. + */ + LEX *stmt_lex; /* Points to the query associated with this statement. It's const, but we need to declare it char * because all table handlers are written @@ -2874,7 +2889,6 @@ class THD :public Statement, uint tmp_table, global_disable_checkpoint; uint server_status,open_options; enum enum_thread_type system_thread; - uint select_number; //number of select (used for EXPLAIN) /* Current or next transaction isolation level. When a connection is established, the value is taken from @@ -4397,6 +4411,7 @@ class THD :public Statement, TMP_TABLE_SHARE* save_tmp_table_share(TABLE *table); void restore_tmp_table_share(TMP_TABLE_SHARE *share); + bool inline is_main_lex(LEX *lex) { return lex == &main_lex; } private: /* Whether a lock has been acquired? */ bool m_tmp_tables_locked; @@ -4573,10 +4588,11 @@ class THD :public Statement, /** Switch to a sublex, to parse a substatement or an expression. */ - void set_local_lex(sp_lex_local *sublex) + void set_local_lex(sp_lex_local *sublex, LEX *stmtlex) { DBUG_ASSERT(lex->sphead); lex= sublex; + stmt_lex= stmtlex; /* Reset part of parser state which needs this. */ m_parser_state->m_yacc.reset_before_substatement(); } @@ -4592,7 +4608,7 @@ class THD :public Statement, See also sp_head::merge_lex(). */ - bool restore_from_local_lex_to_old_lex(LEX *oldlex); + bool restore_from_local_lex_to_old_lex(LEX *oldlex, LEX *oldstmtlex); inline void prepare_logs_for_admin_command() { @@ -5946,7 +5962,8 @@ class select_dumpvar :public select_result_interceptor { inline bool add_item_to_list(THD *thd, Item *item) { - return thd->lex->current_select->add_item_to_list(thd, item); + bool res= thd->lex->current_select->add_item_to_list(thd, item); + return res; } inline bool add_value_to_list(THD *thd, Item *value) diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index 2047c7c8762..f493a97b3cc 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -679,7 +679,7 @@ void With_element::move_anchors_ahead() st_select_lex *next_sl; st_select_lex *new_pos= spec->first_select(); st_select_lex *last_sl; - new_pos->linkage= UNION_TYPE; + new_pos->set_linkage(UNION_TYPE); for (st_select_lex *sl= new_pos; sl; sl= next_sl) { next_sl= sl->next_select(); @@ -825,9 +825,9 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd, if (parser_state.init(thd, (char*) unparsed_spec.str, unparsed_spec.length)) goto err; lex_start(thd); - with_select= &lex->select_lex; - with_select->select_number= ++thd->select_number; parse_status= parse_sql(thd, &parser_state, 0); + with_select= lex->first_select_lex(); + //with_select->select_number= ++thd->select_number; if (parse_status) goto err; spec_tables= lex->query_tables; @@ -962,8 +962,9 @@ bool With_element::prepare_unreferenced(THD *thd) rename_columns_of_derived_unit(thd, spec) || check_duplicate_names(thd, first_sl->item_list, 1))) rc= true; - + thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED; + return rc; } @@ -1055,13 +1056,16 @@ bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem) } with= with_elem; if (!with_elem->is_referenced() || with_elem->is_recursive) + { derived= with_elem->spec; + } else { if(!(derived= with_elem->clone_parsed_spec(thd, this))) return true; derived->with_element= with_elem; } + select_lex->add_statistics(derived); with_elem->inc_references(); return false; } diff --git a/sql/sql_cte.h b/sql/sql_cte.h index 036f0335c10..304d72b57d6 100644 --- a/sql/sql_cte.h +++ b/sql/sql_cte.h @@ -277,8 +277,7 @@ class With_clause : public Sql_alloc */ With_clause *next_with_clause; /* Set to true if dependencies between with elements have been checked */ - bool dependencies_are_checked; - + bool dependencies_are_checked; /* The bitmap of all recursive with elements whose specifications are not complied with restrictions imposed by the SQL standards @@ -302,9 +301,8 @@ class With_clause : public Sql_alloc bool with_recursive; With_clause(bool recursive_fl, With_clause *emb_with_clause) - : owner(NULL), - embedding_with_clause(emb_with_clause), next_with_clause(NULL), - dependencies_are_checked(false), unrestricted(0), + : owner(NULL), embedding_with_clause(emb_with_clause), + next_with_clause(NULL), dependencies_are_checked(false), unrestricted(0), with_prepared_anchor(0), cleaned(0), stabilized(0), with_recursive(recursive_fl) { } @@ -318,8 +316,12 @@ class With_clause : public Sql_alloc last_next= &this->next_with_clause; } + st_select_lex_unit *get_owner() { return owner; } + void set_owner(st_select_lex_unit *unit) { owner= unit; } + void attach_to(st_select_lex *select_lex); + With_clause *pop() { return embedding_with_clause; } bool check_dependencies(); @@ -352,7 +354,6 @@ bool With_element::is_unrestricted() } inline - bool With_element::is_with_prepared_anchor() { return owner->with_prepared_anchor & get_elem_map(); @@ -436,9 +437,20 @@ void With_element::prepare_for_next_iteration() inline void st_select_lex_unit::set_with_clause(With_clause *with_cl) { - with_clause= with_cl; - if (with_clause) - with_clause->set_owner(this); + with_clause= with_cl; + if (with_clause) + with_clause->set_owner(this); +} + +inline +void With_clause::attach_to(st_select_lex *select_lex) +{ + for (With_element *with_elem= with_list.first; + with_elem; + with_elem= with_elem->next) + { + select_lex->register_unit(with_elem->spec, NULL); + } } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 3a161ce6d31..3472157dfcc 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -256,7 +256,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, bool reverse= FALSE; ORDER *order= (ORDER *) ((order_list && order_list->elements) ? order_list->first : NULL); - SELECT_LEX *select_lex= &thd->lex->select_lex; + SELECT_LEX *select_lex= thd->lex->first_select_lex(); killed_state killed_status= NOT_KILLED; THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE; bool with_select= !select_lex->item_list.is_empty(); @@ -291,7 +291,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, } THD_STAGE_INFO(thd, stage_init); table->map=1; - query_plan.select_lex= &thd->lex->select_lex; + query_plan.select_lex= thd->lex->first_select_lex(); query_plan.table= table; query_plan.updating_a_view= MY_TEST(table_list->view); @@ -323,7 +323,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, setup_order(thd, select_lex->ref_pointer_array, &tables, fields, all_fields, order)) { - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, thd->lex->first_select_lex()); DBUG_RETURN(TRUE); } } @@ -807,14 +807,16 @@ l bool *delete_while_scanning) { Item *fake_conds= 0; - SELECT_LEX *select_lex= &thd->lex->select_lex; + SELECT_LEX *select_lex= thd->lex->first_select_lex(); DBUG_ENTER("mysql_prepare_delete"); List<Item> all_fields; *delete_while_scanning= true; thd->lex->allow_sum_func= 0; - if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, - &thd->lex->select_lex.top_join_list, + if (setup_tables_and_check_access(thd, + &thd->lex->first_select_lex()->context, + &thd->lex->first_select_lex()-> + top_join_list, table_list, select_lex->leaf_tables, FALSE, DELETE_ACL, SELECT_ACL, TRUE)) @@ -886,21 +888,23 @@ int mysql_multi_delete_prepare(THD *thd) lex->query_tables also point on local list of DELETE SELECT_LEX */ - if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, - &thd->lex->select_lex.top_join_list, + if (setup_tables_and_check_access(thd, + &thd->lex->first_select_lex()->context, + &thd->lex->first_select_lex()-> + top_join_list, lex->query_tables, - lex->select_lex.leaf_tables, FALSE, - DELETE_ACL, SELECT_ACL, FALSE)) + lex->first_select_lex()->leaf_tables, + FALSE, DELETE_ACL, SELECT_ACL, FALSE)) DBUG_RETURN(TRUE); - if (lex->select_lex.handle_derived(thd->lex, DT_MERGE)) + if (lex->first_select_lex()->handle_derived(thd->lex, DT_MERGE)) DBUG_RETURN(TRUE); /* Multi-delete can't be constructed over-union => we always have single SELECT on top and have to check underlying SELECTs of it */ - lex->select_lex.exclude_from_table_unique_test= TRUE; + lex->first_select_lex()->exclude_from_table_unique_test= TRUE; /* Fix tables-to-be-deleted-from list to point at opened tables */ for (target_tbl= (TABLE_LIST*) aux_tables; target_tbl; @@ -942,8 +946,8 @@ int mysql_multi_delete_prepare(THD *thd) Reset the exclude flag to false so it doesn't interfare with further calls to unique_table */ - lex->select_lex.exclude_from_table_unique_test= FALSE; - + lex->first_select_lex()->exclude_from_table_unique_test= FALSE; + if (lex->save_prep_leaf_tables()) DBUG_RETURN(TRUE); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index b857dc8d2ec..c7d5f2d88bb 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -99,7 +99,8 @@ mysql_handle_derived(LEX *lex, uint phases) processed normally. */ if (phases == DT_MERGE_FOR_INSERT && - cursor && cursor->top_table()->select_lex != &lex->select_lex) + cursor && (cursor->top_table()->select_lex != + lex->first_select_lex())) continue; for (; cursor && !res; diff --git a/sql/sql_do.cc b/sql/sql_do.cc index a25bdef3d9d..192c31af37a 100644 --- a/sql/sql_do.cc +++ b/sql/sql_do.cc @@ -33,7 +33,7 @@ bool mysql_do(THD *thd, List<Item> &values) DBUG_RETURN(TRUE); while ((value = li++)) (void) value->is_null(); - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, thd->lex->first_select_lex()); if (thd->is_error()) { diff --git a/sql/sql_error.cc b/sql/sql_error.cc index b1c7481bb8c..84bfa241535 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -782,7 +782,7 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show) List<Item> field_list; MEM_ROOT *mem_root= thd->mem_root; const Sql_condition *err; - SELECT_LEX *sel= &thd->lex->select_lex; + SELECT_LEX *sel= thd->lex->first_select_lex(); SELECT_LEX_UNIT *unit= &thd->lex->unit; ulonglong idx= 0; Protocol *protocol=thd->protocol; diff --git a/sql/sql_explain.h b/sql/sql_explain.h index 154769fe289..6e1799a98c9 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -207,6 +207,9 @@ class Explain_select : public Explain_basic_join Explain_select(MEM_ROOT *root, bool is_analyze) : Explain_basic_join(root), +#ifndef DBUG_OFF + select_lex(NULL), +#endif linkage(UNSPECIFIED_TYPE), message(NULL), having(NULL), having_value(Item::COND_UNDEF), @@ -218,6 +221,9 @@ class Explain_select : public Explain_basic_join void add_linkage(Json_writer *writer); public: +#ifndef DBUG_OFF + SELECT_LEX *select_lex; +#endif const char *select_type; enum sub_select_type linkage; diff --git a/sql/sql_help.cc b/sql/sql_help.cc index 4ccaa6a055f..2bb5a124e0d 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -87,7 +87,7 @@ enum enum_used_fields static bool init_fields(THD *thd, TABLE_LIST *tables, struct st_find_field *find_fields, uint count) { - Name_resolution_context *context= &thd->lex->select_lex.context; + Name_resolution_context *context= &thd->lex->first_select_lex()->context; DBUG_ENTER("init_fields"); context->resolve_in_table_list_only(tables); for (; count-- ; find_fields++) @@ -723,10 +723,11 @@ static bool mysqld_help_internal(THD *thd, const char *mask) Init tables and fields to be usable from items tables do not contain VIEWs => we can pass 0 as conds */ - thd->lex->select_lex.context.table_list= - thd->lex->select_lex.context.first_name_resolution_table= &tables[0]; - if (setup_tables(thd, &thd->lex->select_lex.context, - &thd->lex->select_lex.top_join_list, + thd->lex->first_select_lex()->context.table_list= + thd->lex->first_select_lex()->context.first_name_resolution_table= + &tables[0]; + if (setup_tables(thd, &thd->lex->first_select_lex()->context, + &thd->lex->first_select_lex()->top_join_list, tables, leaves, FALSE, FALSE)) goto error; memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields)); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 4ae66dcd32f..02508924123 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -241,7 +241,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, } else { // Part field list - SELECT_LEX *select_lex= &thd->lex->select_lex; + SELECT_LEX *select_lex= thd->lex->first_select_lex(); Name_resolution_context *context= &select_lex->context; Name_resolution_context_state ctx_state; int res; @@ -272,7 +272,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, /* Restore the current context. */ ctx_state.restore_state(context, table_list); - thd->lex->select_lex.no_wrap_view_item= FALSE; + thd->lex->first_select_lex()->no_wrap_view_item= FALSE; if (res) DBUG_RETURN(-1); @@ -656,7 +656,7 @@ static void save_insert_query_plan(THD* thd, TABLE_LIST *table_list) bool skip= MY_TEST(table_list->view); /* Save subquery children */ - for (SELECT_LEX_UNIT *unit= thd->lex->select_lex.first_inner_unit(); + for (SELECT_LEX_UNIT *unit= thd->lex->first_select_lex()->first_inner_unit(); unit; unit= unit->next_unit()) { @@ -777,7 +777,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, /* mysql_prepare_insert sets table_list->table if it was not set */ table= table_list->table; - context= &thd->lex->select_lex.context; + context= &thd->lex->first_select_lex()->context; /* These three asserts test the hypothesis that the resetting of the name resolution context below is not necessary at all since the list of local @@ -1064,7 +1064,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, } while (bulk_parameters_iterations(thd)); values_loop_end: - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, thd->lex->first_select_lex()); joins_freed= TRUE; /* @@ -1250,7 +1250,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, table->file->ha_release_auto_increment(); if (!joins_freed) - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, thd->lex->first_select_lex()); thd->abort_on_warning= 0; DBUG_RETURN(retval); } @@ -1280,7 +1280,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, static bool check_view_insertability(THD * thd, TABLE_LIST *view) { - uint num= view->view->select_lex.item_list.elements; + uint num= view->view->first_select_lex()->item_list.elements; TABLE *table= view->table; Field_translator *trans_start= view->field_translation, *trans_end= trans_start + num; @@ -1380,10 +1380,12 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, than INSERT. */ - if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, - &thd->lex->select_lex.top_join_list, + if (setup_tables_and_check_access(thd, + &thd->lex->first_select_lex()->context, + &thd->lex->first_select_lex()-> + top_join_list, table_list, - thd->lex->select_lex.leaf_tables, + thd->lex->first_select_lex()->leaf_tables, select_insert, INSERT_ACL, SELECT_ACL, TRUE)) DBUG_RETURN(TRUE); @@ -1391,7 +1393,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, if (insert_into_view && !fields.elements) { thd->lex->empty_field_list_on_rset= 1; - if (!thd->lex->select_lex.leaf_tables.head()->table || + if (!thd->lex->first_select_lex()->leaf_tables.head()->table || table_list->is_multitable()) { my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0), @@ -1465,7 +1467,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, enum_duplicates duplic, COND **where, bool select_insert) { - SELECT_LEX *select_lex= &thd->lex->select_lex; + SELECT_LEX *select_lex= thd->lex->first_select_lex(); Name_resolution_context *context= &select_lex->context; Name_resolution_context_state ctx_state; bool insert_into_view= (table_list->view != 0); @@ -3436,7 +3438,7 @@ bool Delayed_insert::handle_inserts(void) bool mysql_insert_select_prepare(THD *thd) { LEX *lex= thd->lex; - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); DBUG_ENTER("mysql_insert_select_prepare"); @@ -3525,7 +3527,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) select, LEX::current_select should point to the first select while we are fixing fields from insert list. */ - lex->current_select= &lex->select_lex; + lex->current_select= lex->first_select_lex(); res= (setup_fields(thd, Ref_ptr_array(), values, MARK_COLUMNS_READ, 0, 0) || check_insert_fields(thd, table_list, *fields, values, @@ -3541,7 +3543,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) if (info.handle_duplicates == DUP_UPDATE && !res) { - Name_resolution_context *context= &lex->select_lex.context; + Name_resolution_context *context= &lex->first_select_lex()->context; Name_resolution_context_state ctx_state; /* Save the state of the current name resolution context. */ @@ -3551,7 +3553,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) table_list->next_local= 0; context->resolve_in_table_list_only(table_list); - lex->select_lex.no_wrap_view_item= TRUE; + lex->first_select_lex()->no_wrap_view_item= TRUE; res= res || check_update_fields(thd, context->table_list, *info.update_fields, *info.update_values, @@ -3562,15 +3564,15 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) */ true, &map); - lex->select_lex.no_wrap_view_item= FALSE; + lex->first_select_lex()->no_wrap_view_item= FALSE; /* When we are not using GROUP BY and there are no ungrouped aggregate functions we can refer to other tables in the ON DUPLICATE KEY part. We use next_name_resolution_table descructively, so check it first (views?) */ DBUG_ASSERT (!table_list->next_name_resolution_table); - if (lex->select_lex.group_list.elements == 0 && - !lex->select_lex.with_sum_func) + if (lex->first_select_lex()->group_list.elements == 0 && + !lex->first_select_lex()->with_sum_func) /* We must make a single context out of the two separate name resolution contexts : the INSERT table and the tables in the SELECT part of INSERT ... SELECT. diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 16995f215e8..4f481b2211f 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -182,7 +182,7 @@ init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex) { TABLE_LIST *table_list; Table_ident *table_ident; - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); Name_resolution_context *context= &select_lex->context; /* We will call the parser to create a part_info struct based on the @@ -676,19 +676,25 @@ void LEX::start(THD *thd_arg) DBUG_ENTER("LEX::start"); thd= unit.thd= thd_arg; - + DBUG_PRINT("info", ("Lex %p stmt_lex: %p", thd->lex, thd->stmt_lex)); + DBUG_ASSERT(!explain); context_stack.empty(); + //empty select_stack + select_stack_top= 0; unit.init_query(); - select_lex.linkage= UNSPECIFIED_TYPE; + current_select_number= 0; + builtin_select.set_linkage(UNSPECIFIED_TYPE); + builtin_select.distinct= TRUE; /* 'parent_lex' is used in init_query() so it must be before it. */ - select_lex.parent_lex= this; - select_lex.init_query(); + builtin_select.parent_lex= this; + builtin_select.init_query(); curr_with_clause= 0; with_clauses_list= 0; with_clauses_list_last_next= &with_clauses_list; create_view= NULL; + field_list.empty(); value_list.empty(); update_list.empty(); set_var_list.empty(); @@ -702,17 +708,17 @@ void LEX::start(THD *thd_arg) auxiliary_table_list.empty(); unit.next= unit.master= unit.link_next= unit.return_to= 0; unit.prev= unit.link_prev= 0; - unit.slave= current_select= all_selects_list= &select_lex; - select_lex.master= &unit; - select_lex.prev= &unit.slave; - select_lex.link_next= select_lex.slave= select_lex.next= 0; - select_lex.link_prev= (st_select_lex_node**)&(all_selects_list); - select_lex.options= 0; - select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED; - select_lex.init_order(); - select_lex.group_list.empty(); - if (select_lex.group_list_ptrs) - select_lex.group_list_ptrs->clear(); + unit.slave= current_select= all_selects_list= &builtin_select; + builtin_select.master= &unit; + builtin_select.prev= &unit.slave; + builtin_select.link_next= builtin_select.slave= builtin_select.next= 0; + builtin_select.link_prev= (st_select_lex_node**)&(all_selects_list); + builtin_select.options= 0; + builtin_select.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED; + builtin_select.init_order(); + builtin_select.group_list.empty(); + if (builtin_select.group_list_ptrs) + builtin_select.group_list_ptrs->clear(); describe= 0; analyze_stmt= 0; explain_json= false; @@ -722,14 +728,14 @@ void LEX::start(THD *thd_arg) safe_to_cache_query= 1; parsing_options.reset(); empty_field_list_on_rset= 0; - select_lex.select_number= 1; + builtin_select.select_number= 1; part_info= 0; - select_lex.in_sum_expr=0; - select_lex.ftfunc_list_alloc.empty(); - select_lex.ftfunc_list= &select_lex.ftfunc_list_alloc; - select_lex.group_list.empty(); - select_lex.order_list.empty(); - select_lex.gorder_list.empty(); + builtin_select.in_sum_expr=0; + builtin_select.ftfunc_list_alloc.empty(); + builtin_select.ftfunc_list= &builtin_select.ftfunc_list_alloc; + builtin_select.group_list.empty(); + builtin_select.order_list.empty(); + builtin_select.gorder_list.empty(); m_sql_cmd= NULL; duplicates= DUP_ERROR; ignore= 0; @@ -740,6 +746,8 @@ void LEX::start(THD *thd_arg) query_tables= 0; reset_query_tables_list(FALSE); expr_allows_subselect= TRUE; + selects_allow_into= FALSE; + selects_allow_procedure= FALSE; use_only_table_context= FALSE; parse_vcol_expr= FALSE; check_exists= FALSE; @@ -750,7 +758,7 @@ void LEX::start(THD *thd_arg) event_parse_data= NULL; profile_options= PROFILE_NONE; nest_level=0 ; - select_lex.nest_level_base= &unit; + builtin_select.nest_level_base= &unit; allow_sum_func= 0; in_sum_func= NULL; @@ -772,6 +780,14 @@ void LEX::start(THD *thd_arg) win_spec= NULL; is_lex_started= TRUE; + + braces_depth= 0; + next_is_main= FALSE; + next_is_down= FALSE; + + wild= 0; + exchange= 0; + DBUG_VOID_RETURN; } @@ -1306,6 +1322,7 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd) { Lex_input_stream *lip= & thd->m_parser_state->m_lip; int token; + const int left_paren= (int) '('; if (lip->lookahead_token >= 0) { @@ -1349,6 +1366,34 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd) return WITH; } break; + case PARTITION_SYM: + case UNION_SYM: + if (thd->lex->current_select && + thd->lex->current_select->parsing_place == BEFORE_OPT_FIELD_LIST) + { + thd->lex->current_select->parsing_place= NO_MATTER; + } + break; + case left_paren: + if (!thd->lex->current_select || + thd->lex->current_select->parsing_place != BEFORE_OPT_FIELD_LIST) + return token; + token= lex_one_token(yylval, thd); + lip->add_digest_token(token, yylval); + lip->lookahead_yylval= lip->yylval; + lip->yylval= NULL; + lip->lookahead_token= token; + thd->lex->current_select->parsing_place= NO_MATTER; + if (token == LIKE) + return LEFT_PAREN_LIKE; + if (token == WITH) + return LEFT_PAREN_WITH; + if (token != left_paren && token != SELECT_SYM) + return LEFT_PAREN_ALT; + else + return left_paren; + break; + default: break; } @@ -1845,7 +1890,7 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) return(TEXT_STRING); } case MY_LEX_COMMENT: // Comment - lex->select_lex.options|= OPTION_FOUND_COMMENT; + lex->builtin_select.options|= OPTION_FOUND_COMMENT; while ((c = lip->yyGet()) != '\n' && c) ; lip->yyUnget(); // Safety against eof state = MY_LEX_START; // Try again @@ -1856,7 +1901,7 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) state=MY_LEX_CHAR; // Probable division break; } - lex->select_lex.options|= OPTION_FOUND_COMMENT; + lex->builtin_select.options|= OPTION_FOUND_COMMENT; /* Reject '/' '*', since we might need to turn off the echo */ lip->yyUnget(); @@ -2140,7 +2185,8 @@ void st_select_lex_node::init_query_common() { options= 0; sql_cache= SQL_CACHE_UNSPECIFIED; - linkage= UNSPECIFIED_TYPE; + set_linkage(UNSPECIFIED_TYPE); + distinct= TRUE; no_table_names_allowed= 0; uncacheable= 0; } @@ -2148,7 +2194,7 @@ void st_select_lex_node::init_query_common() void st_select_lex_unit::init_query() { init_query_common(); - linkage= GLOBAL_OPTIONS_TYPE; + set_linkage(GLOBAL_OPTIONS_TYPE); select_limit_cnt= HA_POS_ERROR; offset_limit_cnt= 0; union_distinct= 0; @@ -2198,7 +2244,7 @@ void st_select_lex::init_query() thus push_context should be moved to a place where query initialization is checked for failure. */ - parent_lex->push_context(&context, parent_lex->thd->mem_root); + //parent_lex->push_context(&context, parent_lex->thd->mem_ro:ot); cond_count= between_count= with_wild= 0; max_equal_elems= 0; ref_pointer_array.reset(); @@ -2248,6 +2294,7 @@ void st_select_lex::init_select() /* Set limit and offset to default values */ select_limit= 0; /* denotes the default limit = HA_POS_ERROR */ offset_limit= 0; /* denotes the default offset = 0 */ + is_set_query_expr_tail= false; with_sum_func= 0; is_correlated= 0; cur_pos_in_select_list= UNDEF_POS; @@ -2351,10 +2398,8 @@ void st_select_lex_node::fast_exclude() // Remove slave structure for (; slave; slave= slave->next) slave->fast_exclude(); - } - /** @brief Insert a new chain of nodes into another chain before a particular link @@ -2984,6 +3029,7 @@ LEX::LEX() INITIAL_LEX_PLUGIN_LIST_SIZE, 0); reset_query_tables_list(TRUE); mi.init(); + unit.slave= &builtin_select; } @@ -3010,12 +3056,12 @@ bool LEX::can_be_merged() // TODO: do not forget implement case when select_lex.table_list.elements==0 /* find non VIEW subqueries/unions */ - bool selects_allow_merge= (select_lex.next_select() == 0 && - !(select_lex.uncacheable & + bool selects_allow_merge= (first_select_lex()->next_select() == 0 && + !(first_select_lex()->uncacheable & UNCACHEABLE_RAND)); if (selects_allow_merge) { - for (SELECT_LEX_UNIT *tmp_unit= select_lex.first_inner_unit(); + for (SELECT_LEX_UNIT *tmp_unit= first_select_lex()->first_inner_unit(); tmp_unit; tmp_unit= tmp_unit->next_unit()) { @@ -3032,12 +3078,12 @@ bool LEX::can_be_merged() } return (selects_allow_merge && - select_lex.group_list.elements == 0 && - select_lex.having == 0 && - select_lex.with_sum_func == 0 && - select_lex.table_list.elements >= 1 && - !(select_lex.options & SELECT_DISTINCT) && - select_lex.select_limit == 0); + first_select_lex()->group_list.elements == 0 && + first_select_lex()->having == 0 && + first_select_lex()->with_sum_func == 0 && + first_select_lex()->table_list.elements >= 1 && + !(first_select_lex()->options & SELECT_DISTINCT) && + first_select_lex()->select_limit == 0); } @@ -3393,7 +3439,7 @@ void LEX::set_trg_event_type_for_tables() Do not iterate over sub-selects, only the tables in the outermost SELECT_LEX can be modified, if any. */ - TABLE_LIST *tables= select_lex.get_table_list(); + TABLE_LIST *tables= first_select_lex()->get_table_list(); while (tables) { @@ -3449,12 +3495,13 @@ TABLE_LIST *LEX::unlink_first_table(bool *link_to_local) /* and from local list if it is not empty */ - if ((*link_to_local= MY_TEST(select_lex.table_list.first))) + if ((*link_to_local= MY_TEST(first_select_lex()->table_list.first))) { - select_lex.context.table_list= - select_lex.context.first_name_resolution_table= first->next_local; - select_lex.table_list.first= first->next_local; - select_lex.table_list.elements--; //safety + first_select_lex()->context.table_list= + first_select_lex()->context.first_name_resolution_table= + first->next_local; + first_select_lex()->table_list.first= first->next_local; + first_select_lex()->table_list.elements--; //safety first->next_local= 0; /* Ensure that the global list has the same first table as the local @@ -3485,7 +3532,7 @@ TABLE_LIST *LEX::unlink_first_table(bool *link_to_local) void LEX::first_lists_tables_same() { - TABLE_LIST *first_table= select_lex.table_list.first; + TABLE_LIST *first_table= first_select_lex()->table_list.first; if (query_tables != first_table && first_table != 0) { TABLE_LIST *next; @@ -3510,6 +3557,25 @@ void LEX::first_lists_tables_same() } } +void LEX::fix_first_select_number() +{ + SELECT_LEX *first= first_select_lex(); + if (first && first->select_number != 1) + { + uint num= first->select_number; + for (SELECT_LEX *sel= all_selects_list; + sel; + sel= sel->next_select_in_list()) + { + if (sel->select_number < num) + sel->select_number++; + if (sel->select_number > num) + sel->select_number--; + } + first->select_number= 1; + } +} + /* Link table back that was unlinked with unlink_first_table() @@ -3535,10 +3601,10 @@ void LEX::link_first_table_back(TABLE_LIST *first, if (link_to_local) { - first->next_local= select_lex.table_list.first; - select_lex.context.table_list= first; - select_lex.table_list.first= first; - select_lex.table_list.elements++; //safety + first->next_local= first_select_lex()->table_list.first; + first_select_lex()->context.table_list= first; + first_select_lex()->table_list.first= first; + first_select_lex()->table_list.elements++; //safety } } } @@ -3567,19 +3633,19 @@ void LEX::cleanup_after_one_table_open() NOTE: all units will be connected to thd->lex->select_lex, because we have not UNION on most upper level. */ - if (all_selects_list != &select_lex) + if (all_selects_list != first_select_lex()) { derived_tables= 0; - select_lex.exclude_from_table_unique_test= false; + first_select_lex()->exclude_from_table_unique_test= false; /* cleunup underlying units (units of VIEW) */ - for (SELECT_LEX_UNIT *un= select_lex.first_inner_unit(); + for (SELECT_LEX_UNIT *un= first_select_lex()->first_inner_unit(); un; un= un->next_unit()) un->cleanup(); /* reduce all selects list to default state */ - all_selects_list= &select_lex; + all_selects_list= first_select_lex(); /* remove underlying units (units of VIEW) subtree */ - select_lex.cut_subtree(); + first_select_lex()->cut_subtree(); } } @@ -4428,7 +4494,7 @@ void st_select_lex::set_explain_type(bool on_the_fly) using_materialization= TRUE; } - if (&master_unit()->thd->lex->select_lex == this) + if (master_unit()->thd->lex->first_select_lex() == this) { type= is_primary ? "PRIMARY" : "SIMPLE"; } @@ -4622,8 +4688,8 @@ bool LEX::save_prep_leaf_tables() Query_arena *arena= thd->stmt_arena, backup; arena= thd->activate_stmt_arena_if_needed(&backup); //It is used for DETETE/UPDATE so top level has only one SELECT - DBUG_ASSERT(select_lex.next_select() == NULL); - bool res= select_lex.save_prep_leaf_tables(thd); + DBUG_ASSERT(first_select_lex()->next_select() == NULL); + bool res= first_select_lex()->save_prep_leaf_tables(thd); if (arena) thd->restore_active_arena(arena, &backup); @@ -4952,8 +5018,13 @@ bool LEX::is_partition_management() const SELECT_LEX *LEX::exclude_last_select() { - DBUG_ENTER("SELECT_LEX::exclude_last_select"); - SELECT_LEX *exclude= current_select; + return exclude_not_first_select(current_select); +} + +SELECT_LEX *LEX::exclude_not_first_select(SELECT_LEX *exclude) +{ + DBUG_ENTER("LEX::exclude_not_first_select"); + DBUG_PRINT("enter", ("exclude %p #%u", exclude, exclude->select_number)); SELECT_LEX_UNIT *unit= exclude->master_unit(); SELECT_LEX *sl; DBUG_ASSERT(unit->first_select() != exclude); @@ -4964,13 +5035,272 @@ SELECT_LEX *LEX::exclude_last_select() DBUG_PRINT("info", ("excl: %p unit: %p prev: %p", exclude, unit, sl)); if (!sl) DBUG_RETURN(NULL); - DBUG_ASSERT(exclude->next_select() == NULL); - exclude->exclude_from_tree(); + DBUG_ASSERT(&sl->next == exclude->prev); + + exclude->prev= NULL; + current_select= sl; DBUG_RETURN(exclude); } +/* + SELECT_1 -> SELECT_EXCL -> SELECT_3 ... + + SELECT_1 -> NULL + | + V + SELECT_EXCL -> SELECT_3 +*/ + + +SELECT_LEX *LEX::shift_selects_down(SELECT_LEX *exclude_start) +{ + SELECT_LEX_UNIT *unit= exclude_start->master_unit(); + SELECT_LEX *prev_select; + DBUG_ENTER("LEX::schift_selects_down"); + + for (prev_select= unit->first_select(); + prev_select && prev_select->next_select() != exclude_start; + prev_select= prev_select->next_select()) ; + if (!prev_select) + DBUG_RETURN(NULL); + + prev_select->next= NULL; + current_select= prev_select; + + SELECT_LEX *sl= exclude_start; + bool down= TRUE; + do{ + SELECT_LEX *next= sl->next_select(); + if (mysql_new_select(this, down, sl)) + DBUG_RETURN(NULL); + down= FALSE; + DBUG_ASSERT(sl->outer_select() == prev_select); + sl= next; + } while (sl); + + DBUG_ASSERT(unit != exclude_start->master_unit()); + unit->fix_distinct(exclude_start->master_unit()); + + current_select= prev_select; + DBUG_RETURN(prev_select); +} + + +SELECT_LEX_UNIT *LEX::alloc_unit() +{ + SELECT_LEX_UNIT *unit; + DBUG_ENTER("LEX::alloc_unit"); + if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT())) + DBUG_RETURN(NULL); + + unit->init_query(); + /* TODO: reentrant problem */ + unit->thd= thd; + unit->link_next= 0; + unit->link_prev= 0; + /* TODO: remove return_to */ + unit->return_to= NULL; + DBUG_RETURN(unit); +} + + +SELECT_LEX *LEX::alloc_select(bool select) +{ + SELECT_LEX *select_lex; + DBUG_ENTER("LEX::alloc_select"); + if (!(select_lex= new (thd->mem_root) SELECT_LEX())) + DBUG_RETURN(NULL); + DBUG_PRINT("info", ("Allocate select: %p #%u statement lex: %p", + select_lex, thd->stmt_lex->current_select_number, + thd->stmt_lex)); + select_lex->select_number= ++thd->stmt_lex->current_select_number; + select_lex->parent_lex= this; /* Used in init_query. */ + select_lex->init_query(); + if (select) + select_lex->init_select(); + select_lex->nest_level_base= &this->unit; + select_lex->include_global((st_select_lex_node**)&all_selects_list); + select_lex->context.resolve_in_select_list= TRUE; + DBUG_RETURN(select_lex); +} + +SELECT_LEX_UNIT * +LEX::create_unit(SELECT_LEX *first_sel) +{ + SELECT_LEX_UNIT *unit; + DBUG_ENTER("LEX::create_unit"); + + if (!(unit= alloc_unit())) + DBUG_RETURN(NULL); + + unit->register_select_chain(first_sel); + if (first_sel->next_select()) + { + unit->reset_distinct(); + DBUG_ASSERT(!unit->fake_select_lex); + if (unit->add_fake_select_lex(thd)) + DBUG_RETURN(NULL); + } + DBUG_RETURN(unit); +} + +SELECT_LEX_UNIT * +SELECT_LEX::attach_selects_chain(SELECT_LEX *first_sel, + Name_resolution_context *context) +{ + SELECT_LEX_UNIT *unit; + DBUG_ENTER("SELECT_LEX::attach_select_chain"); + + if (!(unit= parent_lex->alloc_unit())) + DBUG_RETURN(NULL); + + unit->register_select_chain(first_sel); + register_unit(unit, context); + if (first_sel->next_select()) + { + unit->reset_distinct(); + DBUG_ASSERT(!unit->fake_select_lex); + if (unit->add_fake_select_lex(parent_lex->thd)) + DBUG_RETURN(NULL); + } + + DBUG_RETURN(unit); +} + +SELECT_LEX * +LEX::wrap_unit_into_derived(SELECT_LEX_UNIT *unit) +{ + SELECT_LEX *wrapping_sel; + Table_ident *ti; + DBUG_ENTER("LEX::wrap_unit_into_derived"); + + if (!(wrapping_sel= alloc_select(TRUE))) + DBUG_RETURN(NULL); + Name_resolution_context *context= &wrapping_sel->context; + context->init(); + wrapping_sel->automatic_brackets= FALSE; + + wrapping_sel->register_unit(unit, context); + + /* stuff dummy SELECT * FROM (...) */ + + if (push_select(wrapping_sel)) // for Items & TABLE_LIST + DBUG_RETURN(NULL); + + /* add SELECT list*/ + { + Item *item= new (thd->mem_root) + Item_field(thd, context, NULL, NULL, &star_clex_str); + if (item == NULL) + goto err; + if (add_item_to_list(thd, item)) + goto err; + (wrapping_sel->with_wild)++; + } + + unit->first_select()->set_linkage(DERIVED_TABLE_TYPE); + + ti= new (thd->mem_root) Table_ident(unit); + if (ti == NULL) + goto err; + { + char buff[10]; + TABLE_LIST *table_list; + LEX_CSTRING alias; + alias.length= my_snprintf(buff, sizeof(buff), + "__%u", wrapping_sel->select_number); + alias.str= thd->strmake(buff, alias.length); + if (!alias.str) + goto err; + + if (!(table_list= wrapping_sel->add_table_to_list(thd, ti, &alias, + 0, TL_READ, + MDL_SHARED_READ))) + goto err; + + context->resolve_in_table_list_only(table_list); + wrapping_sel->add_joined_table(table_list); + } + + pop_select(); + + derived_tables|= DERIVED_SUBQUERY; + + DBUG_RETURN(wrapping_sel); + +err: + pop_select(); + DBUG_RETURN(NULL); +} + +SELECT_LEX *LEX::link_selects_chain_down(SELECT_LEX *sel) +{ + SELECT_LEX *dummy_select; + SELECT_LEX_UNIT *unit; + Table_ident *ti; + DBUG_ENTER("LEX::link_selects_chain_down"); + + if (!(dummy_select= alloc_select(TRUE))) + DBUG_RETURN(NULL); + Name_resolution_context *context= &dummy_select->context; + dummy_select->automatic_brackets= FALSE; + + if (!(unit= dummy_select->attach_selects_chain(sel, context))) + DBUG_RETURN(NULL); + + /* stuff dummy SELECT * FROM (...) */ + + if (push_select(dummy_select)) // for Items & TABLE_LIST + DBUG_RETURN(NULL); + + /* add SELECT list*/ + { + Item *item= new (thd->mem_root) + Item_field(thd, context, NULL, NULL, &star_clex_str); + if (item == NULL) + goto err; + if (add_item_to_list(thd, item)) + goto err; + (dummy_select->with_wild)++; + } + + sel->set_linkage(DERIVED_TABLE_TYPE); + + ti= new (thd->mem_root) Table_ident(unit); + if (ti == NULL) + goto err; + { + char buff[10]; + TABLE_LIST *table_list; + LEX_CSTRING alias; + alias.length= my_snprintf(buff, sizeof(buff), + "__%u", dummy_select->select_number); + alias.str= thd->strmake(buff, alias.length); + if (!alias.str) + goto err; + + if (!(table_list= dummy_select->add_table_to_list(thd, ti, &alias, + 0, TL_READ, + MDL_SHARED_READ))) + goto err; + + context->resolve_in_table_list_only(table_list); + dummy_select->add_joined_table(table_list); + } + + pop_select(); + + derived_tables|= DERIVED_SUBQUERY; + + DBUG_RETURN(dummy_select); + +err: + pop_select(); + DBUG_RETURN(NULL); +} + /** Put given (new) SELECT_LEX level below after currect (last) SELECT @@ -4993,13 +5323,43 @@ SELECT_LEX *LEX::exclude_last_select() bool LEX::add_unit_in_brackets(SELECT_LEX *nselect) { DBUG_ENTER("LEX::add_unit_in_brackets"); - bool distinct= nselect->master_unit()->union_distinct == nselect; - bool rc= add_select_to_union_list(distinct, nselect->linkage, 0); - if (rc) + SELECT_LEX_UNIT *unit= nselect->master_unit(); + int old_nest_level= nselect->nest_level; + bool distinct= unit->union_distinct == nselect; + if (add_select_to_union_list(distinct, nselect->linkage, 0)) DBUG_RETURN(TRUE); - SELECT_LEX* dummy_select= current_select; - dummy_select->automatic_brackets= TRUE; - dummy_select->linkage= nselect->linkage; + + SELECT_LEX *dummy= current_select; + dummy->next= NULL; + if (make_select_in_brackets(current_select, nselect, FALSE)) + DBUG_RETURN(TRUE); + + if (!distinct && nselect->master_unit()->union_distinct) + { + // move distinct pointer + if (unit->union_distinct->master_unit() != unit) + { + unit->union_distinct->master_unit()->union_distinct= unit->union_distinct; + unit->union_distinct= NULL; + } + } + else if (distinct) + unit->union_distinct= NULL;// distinkt was moved by add_select_to_union_list + + dummy->set_nest_level(old_nest_level); + DBUG_RETURN(FALSE); +} + + +bool LEX::make_select_in_brackets(SELECT_LEX* dummy_select, + SELECT_LEX *nselect, bool automatic) +{ + DBUG_ENTER("LEX::make_select_in_brackets"); + + int old_nest_level= nselect->nest_level; + dummy_select->automatic_brackets= automatic; + dummy_select->set_linkage(nselect->linkage); + current_select= dummy_select; // for mysql_new_select & Items /* stuff dummy SELECT * FROM (...) */ Name_resolution_context *context= &dummy_select->context; @@ -5014,12 +5374,19 @@ bool LEX::add_unit_in_brackets(SELECT_LEX *nselect) DBUG_RETURN(TRUE); (dummy_select->with_wild)++; - rc= mysql_new_select(this, 1, nselect); - nselect->linkage= DERIVED_TABLE_TYPE; - DBUG_ASSERT(nselect->outer_select() == dummy_select); + nselect->set_linkage(DERIVED_TABLE_TYPE); + SELECT_LEX *sl= nselect; + bool down= TRUE; + do{ + SELECT_LEX *next= sl->next_select(); + if (mysql_new_select(this, down, sl)) + DBUG_RETURN(TRUE); + down= FALSE; + DBUG_ASSERT(sl->outer_select() == dummy_select); + sl= next; + } while (sl); current_select= dummy_select; - current_select->nest_level--; SELECT_LEX_UNIT *unit= nselect->master_unit(); Table_ident *ti= new (thd->mem_root) Table_ident(unit); @@ -5043,12 +5410,63 @@ bool LEX::add_unit_in_brackets(SELECT_LEX *nselect) derived_tables|= DERIVED_SUBQUERY; + if (dummy_select->set_nest_level(old_nest_level)) + DBUG_RETURN(TRUE); + current_select= nselect; - current_select->nest_level++; - DBUG_RETURN(rc); + DBUG_RETURN(FALSE); +} + +bool LEX::push_context(Name_resolution_context *context) +{ + DBUG_ENTER("LEX::push_context"); + DBUG_PRINT("info", ("Context: %p Select: %p (%d)", + context, context->select_lex, + (context->select_lex ? + context->select_lex->select_number: + 0))); + bool res= context_stack.push_front(context, thd->mem_root); + DBUG_RETURN(res); +} + + +bool LEX::push_new_select(SELECT_LEX *last) +{ + DBUG_ENTER("LEX::push new_select"); + DBUG_PRINT("info", ("Push last select: %p (%d)", + last, last->select_number)); + bool res= last_select_stack.push_front(last, thd->mem_root); + DBUG_RETURN(res); +} + + +bool check_intersect_prefix(SELECT_LEX* first_in_unit) +{ + SELECT_LEX *sel; + for (sel= first_in_unit->next_select(); + sel && sel->linkage == INTERSECT_TYPE; + sel= sel->next_select()) + ; + return (sel == NULL); } +SELECT_LEX *LEX::pop_new_select_and_wrap() +{ + DBUG_ENTER("LEX::pop_new_select_and_wrap"); + SELECT_LEX *sel; + SELECT_LEX *last= pop_new_select(); + SELECT_LEX *first= last->next_select(); + last->cut_next(); + enum sub_select_type op= first->linkage; + bool ds= first->distinct; + if (!(sel= link_selects_chain_down(first))) + DBUG_RETURN(NULL); + last->link_neighbour(sel); + sel->set_linkage_and_distinct(op, ds); + DBUG_RETURN(sel); +} + /** Checks if we need finish "automatic brackets" mode @@ -7062,6 +7480,156 @@ Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond, } +bool st_select_lex::set_nest_level(int new_nest_level) +{ + DBUG_ENTER("st_select_lex::set_nest_level"); + DBUG_PRINT("enter", ("select #%d %p nest level: %d", + select_number, this, new_nest_level)); + if (new_nest_level > (int) MAX_SELECT_NESTING) + { + my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT, MYF(0)); + DBUG_RETURN(TRUE); + } + nest_level= new_nest_level; + new_nest_level++; + for (SELECT_LEX_UNIT *u= first_inner_unit(); u; u= u->next_unit()) + { + if (u->set_nest_level(new_nest_level)) + DBUG_RETURN(TRUE); + } + DBUG_RETURN(FALSE); +} + +bool st_select_lex_unit::set_nest_level(int new_nest_level) +{ + DBUG_ENTER("st_select_lex_unit::set_nest_level"); + for(SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) + { + if (sl->set_nest_level(new_nest_level)) + DBUG_RETURN(TRUE); + } + if (fake_select_lex && + fake_select_lex->set_nest_level(new_nest_level)) + DBUG_RETURN(TRUE); + DBUG_RETURN(FALSE); +} + + +bool st_select_lex::check_parameters(SELECT_LEX *main_select) +{ + DBUG_ENTER("st_select_lex::check_parameters"); + DBUG_PRINT("enter", ("select #%d %p nest level: %d", + select_number, this, nest_level)); + + + if ((options & OPTION_INTO_CLAUSE) && + (!parent_lex->selects_allow_into || + next_select() != NULL || + nest_level != 1)) + { + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "INTO"); + DBUG_RETURN(TRUE); + } + + if (options & OPTION_PROCEDURE_CLAUSE) + { + if (!parent_lex->selects_allow_procedure || + next_select() != NULL || + this != master_unit()->first_select() || + nest_level != 1) + { + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "PROCEDURE"); + DBUG_RETURN(TRUE); + } + if (options & OPTION_INTO_CLAUSE) + { + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "INTO"); + DBUG_RETURN(TRUE); + } + } + + if ((options & SELECT_HIGH_PRIORITY) && this != main_select) + { + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "HIGH_PRIORITY"); + DBUG_RETURN(TRUE); + } + if ((options & OPTION_BUFFER_RESULT) && this != main_select) + { + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_BUFFER_RESULT"); + DBUG_RETURN(TRUE); + } + if ((options & OPTION_FOUND_ROWS) && this != main_select) + { + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_CALC_FOUND_ROWS"); + DBUG_RETURN(TRUE); + } + if (options & OPTION_NO_QUERY_CACHE) + { + /* + Allow this flag only on the first top-level SELECT statement, if + SQL_CACHE wasn't specified. + */ + if (this != main_select) + { + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_NO_CACHE"); + DBUG_RETURN(TRUE); + } + if (main_select->sql_cache == SELECT_LEX::SQL_CACHE) + { + my_error(ER_WRONG_USAGE, MYF(0), "SQL_CACHE", "SQL_NO_CACHE"); + DBUG_RETURN(TRUE); + } + parent_lex->safe_to_cache_query=0; + main_select->sql_cache= SELECT_LEX::SQL_NO_CACHE; + } + if (options & OPTION_TO_QUERY_CACHE) + { + /* + Allow this flag only on the first top-level SELECT statement, if + SQL_NO_CACHE wasn't specified. + */ + if (this != main_select) + { + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_CACHE"); + DBUG_RETURN(TRUE); + } + if (main_select->sql_cache == SELECT_LEX::SQL_NO_CACHE) + { + my_error(ER_WRONG_USAGE, MYF(0), "SQL_NO_CACHE", "SQL_CACHE"); + DBUG_RETURN(TRUE); + } + parent_lex->safe_to_cache_query=1; + main_select->sql_cache= SELECT_LEX::SQL_CACHE; + } + + for (SELECT_LEX_UNIT *u= first_inner_unit(); u; u= u->next_unit()) + { + if (u->check_parameters(main_select)) + DBUG_RETURN(TRUE); + } + DBUG_RETURN(FALSE); +} + + +bool st_select_lex_unit::check_parameters(SELECT_LEX *main_select) +{ + for(SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) + { + if (sl->check_parameters(main_select)) + return TRUE; + } + return fake_select_lex && fake_select_lex->check_parameters(main_select); +} + + +bool LEX::check_main_unit_semantics() +{ + if (unit.set_nest_level(1) || + unit.check_parameters(first_select_lex())) + return TRUE; + return FALSE; +} + int set_statement_var_if_exists(THD *thd, const char *var_name, size_t var_name_length, ulonglong value) { @@ -7114,10 +7682,10 @@ bool LEX::create_or_alter_view_finalize(THD *thd, Table_ident *table_ident) { sql_command= SQLCOM_CREATE_VIEW; /* first table in list is target VIEW name */ - if (!select_lex.add_table_to_list(thd, table_ident, NULL, - TL_OPTION_UPDATING, - TL_IGNORE, - MDL_EXCLUSIVE)) + if (!first_select_lex()->add_table_to_list(thd, table_ident, NULL, + TL_OPTION_UPDATING, + TL_IGNORE, + MDL_EXCLUSIVE)) return true; query_tables->open_strategy= TABLE_LIST::OPEN_STUB; return false; @@ -7206,3 +7774,217 @@ Item *LEX::make_item_func_replace(THD *thd, new (thd->mem_root) Item_func_replace_oracle(thd, org, find, replace) : new (thd->mem_root) Item_func_replace(thd, org, find, replace); } + + +void st_select_lex_unit::reset_distinct() +{ + union_distinct= NULL; + for(SELECT_LEX *sl= first_select()->next_select(); + sl; + sl= sl->next_select()) + { + if (sl->distinct) + { + union_distinct= sl; + return; + } + } +} + + +void st_select_lex_unit::fix_distinct(st_select_lex_unit *new_unit) +{ + if (union_distinct) + { + if (this != union_distinct->master_unit()) + { + DBUG_ASSERT(new_unit == union_distinct->master_unit()); + new_unit->union_distinct= union_distinct; + reset_distinct(); + } + else + new_unit->reset_distinct(); + } +} + + +void st_select_lex_unit::register_select_chain(SELECT_LEX *first_sel) +{ + DBUG_ASSERT(first_sel != 0); + slave= first_sel; + first_sel->prev= &slave; + for(SELECT_LEX *sel=first_sel; sel; sel= sel->next_select()) + { + sel->master= (st_select_lex_node *)this; + uncacheable|= sel->uncacheable; + } +} + + +void st_select_lex::register_unit(SELECT_LEX_UNIT *unit, + Name_resolution_context *outer_context) +{ + if ((unit->next= slave)) + slave->prev= &unit->next; + unit->prev= &slave; + slave= unit; + unit->master= this; + uncacheable|= unit->uncacheable; + + for(SELECT_LEX *sel= unit->first_select();sel; sel= sel->next_select()) + { + sel->context.outer_context= outer_context; + } +} + + +void st_select_lex::add_statistics(SELECT_LEX_UNIT *unit) +{ + for (; + unit; + unit= unit->next_unit()) + for(SELECT_LEX *child= unit->first_select(); + child; + child= child->next_select()) + { + /* + A subselect can add fields to an outer select. + Reserve space for them. + */ + select_n_where_fields+= child->select_n_where_fields; + /* + Aggregate functions in having clause may add fields + to an outer select. Count them also. + */ + select_n_having_items+= child->select_n_having_items; + } +} + + +bool LEX::main_select_push() +{ + DBUG_ENTER("LEX::main_select_push"); + current_select_number= 1; + builtin_select.select_number= 1; + if (push_select(&builtin_select)) + DBUG_RETURN(TRUE); + DBUG_RETURN(FALSE); +} + +bool LEX::new_main_select_anker(SELECT_LEX *sel) +{ + DBUG_ENTER("LEX::new_main_select_anker"); + if (sel->set_nest_level(1)) + DBUG_RETURN(TRUE); + unit.register_select_chain(sel); + sel->options|= builtin_select.options; + + DBUG_RETURN(FALSE); +} + +bool Lex_order_limit_lock::set_to(SELECT_LEX *sel) +{ + /*TODO: lock */ + //if (lock.defined_lock && sel == sel->master_unit()->fake_select_lex) + // return TRUE; + if (lock.defined_timeout) + { + THD *thd= sel->parent_lex->thd; + if (set_statement_var_if_exists(thd, + C_STRING_WITH_LEN("lock_wait_timeout"), + lock.timeout) || + set_statement_var_if_exists(thd, + C_STRING_WITH_LEN("innodb_lock_wait_timeout"), + lock.timeout)) + return TRUE; + } + if (lock.defined_lock) + { + sel->parent_lex->safe_to_cache_query= 0; + if (lock.update_lock) + { + sel->lock_type= TL_WRITE; + sel->set_lock_for_tables(TL_WRITE); + } + else + { + sel->lock_type= TL_READ_WITH_SHARED_LOCKS; + sel->set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS); + } + } + sel->explicit_limit= limit.explicit_limit; + sel->select_limit= limit.select_limit; + sel->offset_limit= limit.offset_limit; + if (order_list) + { + if (sel->linkage != GLOBAL_OPTIONS_TYPE && + sel->olap != UNSPECIFIED_OLAP_TYPE && + (sel->linkage != UNION_TYPE || sel->braces)) + { + my_error(ER_WRONG_USAGE, MYF(0), + "CUBE/ROLLUP", "ORDER BY"); + return TRUE; + } + sel->order_list= *(order_list); + } + sel->is_set_query_expr_tail= true; + return FALSE; +} + + +static void change_item_list_context(List<Item> *list, + Name_resolution_context *context) +{ + List_iterator_fast<Item> it (*list); + Item *item; + while((item= it++)) + { + item->walk(&Item::change_context_processor, FALSE, (void *)context); + } +} + + +bool LEX::insert_select_hack(SELECT_LEX *sel) +{ + DBUG_ENTER("LEX::insert_select_hack"); + + DBUG_ASSERT(first_select_lex() == &builtin_select); + DBUG_ASSERT(sel != NULL); + // DBUG_ASSERT(sel->next_select() == NULL); + + + if (builtin_select.link_prev) + { + if ((*builtin_select.link_prev= builtin_select.link_next)) + ((st_select_lex *)builtin_select.link_next)->link_prev= + builtin_select.link_prev; + builtin_select.link_prev= NULL; // indicator of removal + } + + set_main_unit(sel->master_unit()); + + DBUG_ASSERT(builtin_select.table_list.elements == 1); + TABLE_LIST *insert_table= builtin_select.table_list.first; + + if (!(insert_table->next_local= sel->table_list.first)) + { + sel->table_list.next= &insert_table->next_local; + } + sel->table_list.first= insert_table; + sel->table_list.elements++; + insert_table->select_lex= sel; + + sel->context.first_name_resolution_table= insert_table; + builtin_select.context= sel->context; + change_item_list_context(&field_list, &sel->context); + + for (SELECT_LEX *sel= all_selects_list; + sel; + sel= sel->next_select_in_list()) + { + if (sel->select_number != 1) + sel->select_number--; + }; + + DBUG_RETURN(FALSE); +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 245e995bc2d..2e93eaac3ae 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -73,6 +73,16 @@ enum sub_select_type UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE, GLOBAL_OPTIONS_TYPE, DERIVED_TABLE_TYPE, OLAP_TYPE }; + +inline int cmp_unit_op(enum sub_select_type op1, enum sub_select_type op2) +{ + DBUG_ASSERT(op1 >= UNION_TYPE && op1 <= EXCEPT_TYPE); + DBUG_ASSERT(op2 >= UNION_TYPE && op2 <= EXCEPT_TYPE); + return (op1 == INTERSECT_TYPE ? 1 : 0) - (op2 == INTERSECT_TYPE ? 1 : 0); +} + +bool check_intersect_prefix(SELECT_LEX* first_in_unit); + enum unit_common_op {OP_MIX, OP_UNION, OP_INTERSECT, OP_EXCEPT}; enum enum_view_suid @@ -201,6 +211,7 @@ struct LEX_TYPE additional "partitions" column even if partitioning is not compiled in. */ #define DESCRIBE_PARTITIONS 4 +#define DESCRIBE_EXTENDED2 8 #ifdef MYSQL_SERVER @@ -420,9 +431,9 @@ class Index_hint : public Sql_alloc } void print(THD *thd, String *str); -}; +}; -/* +/* The state of the lex parsing for selects master and slaves are pointers to select_lex. @@ -432,7 +443,7 @@ class Index_hint : public Sql_alloc unit is container of either - One SELECT - UNION of selects - select_lex and unit are both inherited form select_lex_node + select_lex and unit are both inherited form st_select_lex_node neighbors are two select_lex or units on the same level All select describing structures linked with following pointers: @@ -574,6 +585,7 @@ class st_select_lex_node { */ uint8 uncacheable; enum sub_select_type linkage; + bool distinct; bool no_table_names_allowed; /* used for global order by */ static void *operator new(size_t size, MEM_ROOT *mem_root) throw () @@ -594,10 +606,28 @@ class st_select_lex_node { 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); + void link_neighbour(st_select_lex_node *neighbour) + { + DBUG_ASSERT(next == NULL); + DBUG_ASSERT(neighbour != NULL); + next= neighbour; + neighbour->prev= &next; + } + void cut_next() { next= NULL; } void include_standalone(st_select_lex_node *sel, st_select_lex_node **ref); void include_global(st_select_lex_node **plink); void exclude(); void exclude_from_tree(); + void exclude_from_global() + { + if (!link_prev) + return; + if (((*link_prev)= link_next)) + link_next->link_prev= link_prev; + link_next= NULL; + link_prev= NULL; + } + void set_slave(st_select_lex_node *slave_arg) { slave= slave_arg; } void move_node(st_select_lex_node *where_to_move) @@ -612,6 +642,22 @@ class st_select_lex_node { } st_select_lex_node *insert_chain_before(st_select_lex_node **ptr_pos_to_insert, st_select_lex_node *end_chain_node); + void set_linkage(enum sub_select_type l) + { + DBUG_ENTER("st_select_lex_node::set_linkage"); + DBUG_PRINT("info", ("node: %p linkage: %d->%d", this, linkage, l)); + linkage= l; + DBUG_VOID_RETURN; + } + /* + This method created for reiniting LEX in mysql_admin_table() and can be + used only if you are going remove all SELECT_LEX & units except belonger + to LEX (LEX::unit & LEX::select, for other purposes there are + SELECT_LEX_UNIT::exclude_level & SELECT_LEX_UNIT::exclude_tree. + + It is also used in parsing to detach builtin select. + */ + void cut_subtree() { slave= 0; } friend class st_select_lex_unit; friend bool mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *sel); friend bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, @@ -621,6 +667,8 @@ class st_select_lex_node { friend bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *orig_table_list); friend bool TABLE_LIST::init_derived(THD *thd, bool init_view); + + friend class st_select_lex; private: void fast_exclude(); }; @@ -666,9 +714,9 @@ class st_select_lex_unit: public st_select_lex_node { { } - TABLE *table; /* temporary table using for appending UNION results */ select_result *result; + st_select_lex *pre_last_parse; bool prepared, // prepare phase already performed for UNION (unit) optimized, // optimize phase already performed for UNION (unit) optimized_2, @@ -797,6 +845,16 @@ class st_select_lex_unit: public st_select_lex_node { int save_union_explain(Explain_query *output); int save_union_explain_part2(Explain_query *output); unit_common_op common_op(); + + void reset_distinct(); + void fix_distinct(st_select_lex_unit *new_unit); + + void register_select_chain(SELECT_LEX *first_sel); + + bool set_nest_level(int new_nest_level); + bool check_parameters(SELECT_LEX *main_select); + + friend class st_select_lex; }; typedef class st_select_lex_unit SELECT_LEX_UNIT; @@ -832,7 +890,13 @@ class st_select_lex: public st_select_lex_node Item *cond_pushed_into_having; /* condition pushed into the select's HAVING */ /* Saved values of the WHERE and HAVING clauses*/ Item::cond_result cond_value, having_value; - /* point on lex in which it was created, used in view subquery detection */ + /* + Point to the LEX in which it was created, used in view subquery detection. + + TODO: make also st_select_lex::parent_stmt_lex (see THD::stmt_lex) + and use st_select_lex::parent_lex & st_select_lex::parent_stmt_lex + instead of global (from THD) references where it is possible. + */ LEX *parent_lex; enum olap_type olap; /* FROM clause - points to the beginning of the TABLE_LIST::next_local list. */ @@ -900,6 +964,7 @@ class st_select_lex: public st_select_lex_node SQL_I_List<ORDER> order_list; /* ORDER clause */ SQL_I_List<ORDER> gorder_list; Item *select_limit, *offset_limit; /* LIMIT clause parameters */ + bool is_set_query_expr_tail; /// Array of pointers to top elements of all_fields list Ref_ptr_array ref_pointer_array; @@ -935,6 +1000,7 @@ class st_select_lex: public st_select_lex_node */ SELECT_LEX_UNIT *nest_level_base; int nest_level; /* nesting level of select */ + uint braces_depth; /* used for parsing and differ from above */ Item_sum *inner_sum_func_list; /* list of sum func in nested selects */ uint with_wild; /* item list contain '*' */ bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */ @@ -1019,6 +1085,10 @@ class st_select_lex: public st_select_lex_node void init_query(); void init_select(); st_select_lex_unit* master_unit() { return (st_select_lex_unit*) master; } + inline void set_master_unit(st_select_lex_unit *master_unit) + { + master= (st_select_lex_node *)master_unit; + } st_select_lex_unit* first_inner_unit() { return (st_select_lex_unit*) slave; @@ -1248,6 +1318,32 @@ class st_select_lex: public st_select_lex_node DBUG_ASSERT(this != sel); select_n_where_fields+= sel->select_n_where_fields; } + inline void set_linkage_and_distinct(enum sub_select_type l, bool d) + { + DBUG_ENTER("SELECT_LEX::set_linkage_and_distinct"); + DBUG_PRINT("info", ("select: %p distinct %d", this, d)); + set_linkage(l); + DBUG_ASSERT(l == UNION_TYPE || + l == INTERSECT_TYPE || + l == EXCEPT_TYPE); + if (d && master_unit() && master_unit()->union_distinct != this) + master_unit()->union_distinct= this; + distinct= d; + DBUG_VOID_RETURN; + } + bool set_nest_level(int new_nest_level); + bool check_parameters(SELECT_LEX *main_select); + void mark_select() + { + DBUG_ENTER("st_select_lex::mark_select()"); + DBUG_PRINT("info", ("Select #%d", select_number)); + DBUG_VOID_RETURN; + } + void register_unit(SELECT_LEX_UNIT *unit, + Name_resolution_context *outer_context); + SELECT_LEX_UNIT *attach_selects_chain(SELECT_LEX *sel, + Name_resolution_context *context); + void add_statistics(SELECT_LEX_UNIT *unit); }; typedef class st_select_lex SELECT_LEX; @@ -2612,7 +2708,8 @@ class Query_arena_memroot; struct LEX: public Query_tables_list { SELECT_LEX_UNIT unit; /* most upper unit */ - SELECT_LEX select_lex; /* first SELECT_LEX */ + inline SELECT_LEX *first_select_lex() {return unit.first_select();} + SELECT_LEX builtin_select; /* current SELECT_LEX in parsing */ SELECT_LEX *current_select; /* list of all SELECT_LEX */ @@ -2652,7 +2749,7 @@ struct LEX: public Query_tables_list DYNAMIC_ARRAY plugins; plugin_ref plugins_static_buffer[INITIAL_LEX_PLUGIN_LIST_SIZE]; - uint number_of_selects; // valid only for view + uint current_select_number; // valid for statment LEX (not view) /** Start of 'ON table', in trigger statements. */ const char* raw_trg_on_table_name_begin; @@ -2693,7 +2790,24 @@ 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); + uint braces_depth; + public: + inline void braces_start() + { + DBUG_ENTER("braces_start"); + braces_depth++; + DBUG_PRINT("info",("now depth is %u <", braces_depth)); + DBUG_VOID_RETURN; + } + inline void braces_end() + { + DBUG_ENTER("braces_end"); + braces_depth--; + DBUG_PRINT("info",("now depth is %u >", braces_depth)); + DBUG_VOID_RETURN; + } + inline uint get_braces_depth() { return braces_depth; } inline bool is_arena_for_set_stmt() {return arena_for_set_stmt != 0;} bool set_arena_for_set_stmt(Query_arena *backup); void reset_arena_for_set_stmt(Query_arena *backup); @@ -2719,6 +2833,9 @@ struct LEX: public Query_tables_list required a local context, the parser pops the top-most context. */ List<Name_resolution_context> context_stack; + List<SELECT_LEX> last_select_stack; + SELECT_LEX *select_stack[MAX_SELECT_NESTING]; + uint select_stack_top; SQL_I_List<ORDER> proc_list; SQL_I_List<TABLE_LIST> auxiliary_table_list, save_list; @@ -2758,6 +2875,8 @@ struct LEX: public Query_tables_list syntax error back. */ bool expr_allows_subselect; + bool selects_allow_into; + bool selects_allow_procedure; /* A special command "PARSE_VCOL_EXPR" is defined for the parser to translate a defining expression of a virtual column into an @@ -2812,6 +2931,8 @@ struct LEX: public Query_tables_list enum enum_yes_no_unknown tx_chain, tx_release; bool safe_to_cache_query; bool subqueries, ignore; + bool next_is_main; // use "main" SELECT_LEX for nrxt allocation; + bool next_is_down; // use "main" SELECT_LEX for nrxt allocation; st_parsing_options parsing_options; Alter_info alter_info; /* @@ -3002,19 +3123,23 @@ struct LEX: public Query_tables_list SELECT_LEX *sl; SELECT_LEX_UNIT *un; for (sl= current_select, un= sl->master_unit(); - un != &unit; - sl= sl->outer_select(), un= sl->master_unit()) + un && un != &unit; + sl= sl->outer_select(), un= (sl ? sl->master_unit() : NULL)) { sl->uncacheable|= cause; un->uncacheable|= cause; } - select_lex.uncacheable|= cause; + if (sl) + sl->uncacheable|= cause; + if (first_select_lex()) + first_select_lex()->uncacheable|= cause; } void set_trg_event_type_for_tables(); TABLE_LIST *unlink_first_table(bool *link_to_local); void link_first_table_back(TABLE_LIST *first, bool link_to_local); void first_lists_tables_same(); + void fix_first_select_number(); bool can_be_merged(); bool can_use_merged(); @@ -3052,14 +3177,90 @@ struct LEX: public Query_tables_list void cleanup_after_one_table_open(); - bool push_context(Name_resolution_context *context, MEM_ROOT *mem_root) + bool push_context(Name_resolution_context *context); + + void pop_context() { - return context_stack.push_front(context, mem_root); + DBUG_ENTER("LEX::pop_context"); + Name_resolution_context *context= context_stack.pop(); + DBUG_PRINT("info", ("Pop context %p Select: %p (%d)", + context, context->select_lex, + (context->select_lex ? + context->select_lex->select_number: + 0))); + DBUG_VOID_RETURN; } - void pop_context() + bool push_new_select(SELECT_LEX *last); + + SELECT_LEX *pop_new_select() + { + DBUG_ENTER("LEX::pop_new_select"); + SELECT_LEX* last= last_select_stack.pop(); + DBUG_PRINT("info", ("Pop last elect: %p (%d)", + last, last->select_number)); + DBUG_RETURN(last); + } + + SELECT_LEX *select_stack_head() { - context_stack.pop(); + if (likely(select_stack_top)) + return select_stack[select_stack_top - 1]; + return NULL; + } + + + bool push_select(SELECT_LEX *select_lex) + { + DBUG_ENTER("LEX::push_select"); + DBUG_PRINT("info", ("Top Select was %p (%d) depth: %u pushed: %p (%d)", + select_stack_head(), + select_stack_top, + (select_stack_top ? + select_stack_head()->select_number : + 0), + select_lex, select_lex->select_number)); + if (unlikely(select_stack_top == MAX_SELECT_NESTING)) + { + my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT, MYF(0)); + DBUG_RETURN(TRUE); + } + if (push_context(&select_lex->context)) + DBUG_RETURN(TRUE); + select_stack[select_stack_top++]= select_lex; + current_select= select_lex; + DBUG_RETURN(FALSE); + } + + SELECT_LEX *pop_select() + { + DBUG_ENTER("LEX::pop_select"); + SELECT_LEX *select_lex; + if (likely(select_stack_top)) + select_lex= select_stack[--select_stack_top]; + else + select_lex= 0; + DBUG_PRINT("info", ("Top Select is %p (%d) depth: %u poped: %p (%d)", + select_stack_head(), + select_stack_top, + (select_stack_top ? + select_stack_head()->select_number : + 0), + select_lex, + (select_lex ? select_lex->select_number : 0))); + DBUG_ASSERT(select_lex); + + pop_context(); + + if (unlikely(!select_stack_top)) + { + current_select= NULL; + DBUG_PRINT("info", ("Top Select is empty")); + } + else + current_select= select_stack[select_stack_top - 1]; + + DBUG_RETURN(select_lex); } bool copy_db_to(const char **p_db, size_t *p_db_length) const; @@ -3093,9 +3294,9 @@ struct LEX: public Query_tables_list on its top. So select_lex (as the first added) will be at the tail of the list. */ - if (&select_lex == all_selects_list && !sroutines.records) + if (first_select_lex() == all_selects_list && !sroutines.records) { - DBUG_ASSERT(!all_selects_list->next_select_in_list()); + // DBUG_ASSERT(!all_selects_list->next_select_in_list()); return TRUE; } return FALSE; @@ -3428,6 +3629,11 @@ struct LEX: public Query_tables_list { size_t pos= start - substatement_query(thd); size_t len= end - start; + if (!substatement_query(thd)) + { + pos= 0; + len= 0; + } DBUG_ASSERT(pos < UINT_MAX32); DBUG_ASSERT(len < UINT_MAX32); return add_placeholder(thd, name, (uint) pos, (uint) len); @@ -3640,6 +3846,7 @@ struct LEX: public Query_tables_list bool if_exists() const { return create_info.if_exists(); } SELECT_LEX *exclude_last_select(); + SELECT_LEX *exclude_not_first_select(SELECT_LEX *exclude); bool add_unit_in_brackets(SELECT_LEX *nselect); void check_automatic_up(enum sub_select_type type); bool create_or_alter_view_finalize(THD *thd, Table_ident *table_ident); @@ -3648,9 +3855,34 @@ struct LEX: public Query_tables_list bool add_create_view(THD *thd, DDL_options_st ddl, uint16 algorithm, enum_view_suid suid, Table_ident *table_ident); - bool add_grant_command(THD *thd, enum_sql_command sql_command_arg, stored_procedure_type type_arg); + bool make_select_in_brackets(SELECT_LEX* dummy_select, + SELECT_LEX *nselect, bool automatic); + SELECT_LEX *shift_selects_down(SELECT_LEX *exclude_start); + + SELECT_LEX_UNIT *alloc_unit(); + SELECT_LEX *alloc_select(bool is_select); + SELECT_LEX_UNIT *create_unit(SELECT_LEX*); + SELECT_LEX *wrap_unit_into_derived(SELECT_LEX_UNIT *unit); + SELECT_LEX *link_selects_chain_down(SELECT_LEX *sel); + bool main_select_push(); + bool new_main_select_anker(SELECT_LEX *sel); + bool insert_select_hack(SELECT_LEX *sel); + SELECT_LEX *pop_new_select_and_wrap(); + + void set_main_unit(st_select_lex_unit *u) + { + unit.options= u->options; + unit.uncacheable= u->uncacheable; + unit.register_select_chain(u->first_select()); + unit.first_select()->options|= builtin_select.options; + unit.fake_select_lex= u->fake_select_lex; + unit.union_distinct= u->union_distinct; + unit.set_with_clause(u->with_clause); + builtin_select.exclude_from_global(); + } + bool check_main_unit_semantics(); }; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 6cd0b76c66d..0c649d0e150 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -329,10 +329,13 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, if (mysql_handle_single_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) || mysql_handle_single_derived(thd->lex, table_list, DT_PREPARE)) DBUG_RETURN(TRUE); - if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, - &thd->lex->select_lex.top_join_list, + if (setup_tables_and_check_access(thd, + &thd->lex->first_select_lex()->context, + &thd->lex->first_select_lex()-> + top_join_list, table_list, - thd->lex->select_lex.leaf_tables, FALSE, + thd->lex->first_select_lex()->leaf_tables, + FALSE, INSERT_ACL | UPDATE_ACL, INSERT_ACL | UPDATE_ACL, FALSE)) DBUG_RETURN(-1); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 82794367b74..fdaac157906 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1978,10 +1978,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, Init TABLE_LIST members necessary when the undelrying table is view. */ - table_list.select_lex= &(thd->lex->select_lex); + table_list.select_lex= thd->lex->first_select_lex(); thd->lex-> - select_lex.table_list.link_in_list(&table_list, - &table_list.next_local); + first_select_lex()->table_list.link_in_list(&table_list, + &table_list.next_local); thd->lex->add_to_query_tables(&table_list); if (is_infoschema_db(table_list.db, table_list.db_length)) @@ -2545,21 +2545,21 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, { LEX_STRING db; size_t dummy; - if (lex->select_lex.db == NULL && - lex->copy_db_to(&lex->select_lex.db, &dummy)) + if (lex->first_select_lex()->db == NULL && + lex->copy_db_to(&lex->first_select_lex()->db, &dummy)) { DBUG_RETURN(1); } schema_select_lex= new (thd->mem_root) SELECT_LEX(); schema_select_lex->table_list.first= NULL; if (lower_case_table_names == 1) - lex->select_lex.db= thd->strdup(lex->select_lex.db); - schema_select_lex->db= lex->select_lex.db; + lex->first_select_lex()->db= thd->strdup(lex->first_select_lex()->db); + schema_select_lex->db= lex->first_select_lex()->db; /* check_db_name() may change db.str if lower_case_table_names == 1, but that's ok as the db is allocted above in this case. */ - db.str= (char*) lex->select_lex.db; + db.str= (char*) lex->first_select_lex()->db; db.length= strlen(db.str); if (check_db_name(&db)) { @@ -3192,7 +3192,7 @@ mysql_execute_command(THD *thd) int up_result= 0; LEX *lex= thd->lex; /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */ - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); /* first table of first SELECT_LEX */ TABLE_LIST *first_table= select_lex->table_list.first; /* list of all tables in query */ @@ -3235,6 +3235,7 @@ mysql_execute_command(THD *thd) DBUG_ASSERT(first_table == all_tables && first_table != 0); */ lex->first_lists_tables_same(); + lex->fix_first_select_number(); /* should be assigned after making first tables same */ all_tables= lex->query_tables; /* set context for commands which do not use setup_tables */ @@ -7458,7 +7459,6 @@ void THD::reset_for_next_command(bool do_clear_error) clear_error(1); thd->free_list= 0; - thd->select_number= 1; /* Those two lines below are theoretically unneeded as THD::cleanup_after_query() should take care of this already. @@ -7547,11 +7547,7 @@ mysql_init_select(LEX *lex) SELECT_LEX *select_lex= lex->current_select; select_lex->init_select(); lex->wild= 0; - if (select_lex == &lex->select_lex) - { - DBUG_ASSERT(lex->result == 0); - lex->exchange= 0; - } + lex->exchange= 0; } @@ -7572,38 +7568,32 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex) { THD *thd= lex->thd; bool new_select= select_lex == NULL; + int old_nest_level= lex->current_select->nest_level; DBUG_ENTER("mysql_new_select"); if (new_select) { if (!(select_lex= new (thd->mem_root) SELECT_LEX())) DBUG_RETURN(1); - select_lex->select_number= ++thd->select_number; + select_lex->select_number= ++thd->stmt_lex->current_select_number; select_lex->parent_lex= lex; /* Used in init_query. */ select_lex->init_query(); select_lex->init_select(); + lex->current_select->braces_depth= lex->get_braces_depth(); } - lex->nest_level++; - if (lex->nest_level > (int) MAX_SELECT_NESTING) - { - my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT, MYF(0)); - DBUG_RETURN(1); - } - select_lex->nest_level= lex->nest_level; select_lex->nest_level_base= &thd->lex->unit; if (move_down) { + lex->nest_level++; + if (select_lex->set_nest_level(old_nest_level + 1)) + DBUG_RETURN(1); SELECT_LEX_UNIT *unit; lex->subqueries= TRUE; /* first select_lex of subselect or derived table */ - if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT())) + if (!(unit= lex->alloc_unit())) DBUG_RETURN(1); - unit->init_query(); - unit->thd= thd; unit->include_down(lex->current_select); - unit->link_next= 0; - unit->link_prev= 0; unit->return_to= lex->current_select; select_lex->include_down(unit); /* @@ -7638,14 +7628,18 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex) DBUG_RETURN(TRUE); } // SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 -- not possible - DBUG_ASSERT(!lex->current_select->order_list.first || - lex->current_select->braces); + //DBUG_ASSERT(!lex->current_select->order_list.first || + // lex->current_select->braces); // SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1; -- not possible - DBUG_ASSERT(!lex->current_select->explicit_limit || - lex->current_select->braces); + //DBUG_ASSERT(!lex->current_select->explicit_limit || + // lex->current_select->braces); + SELECT_LEX_NODE *save_slave= select_lex->slave; select_lex->include_neighbour(lex->current_select); - SELECT_LEX_UNIT *unit= select_lex->master_unit(); + select_lex->slave= save_slave; + SELECT_LEX_UNIT *unit= select_lex->master_unit(); + if (select_lex->set_nest_level(old_nest_level)) + DBUG_RETURN(1); if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd)) DBUG_RETURN(1); select_lex->context.outer_context= @@ -7701,9 +7695,10 @@ void mysql_init_multi_delete(LEX *lex) { lex->sql_command= SQLCOM_DELETE_MULTI; mysql_init_select(lex); - lex->select_lex.select_limit= 0; + lex->first_select_lex()->select_limit= 0; lex->unit.select_limit_cnt= HA_POS_ERROR; - lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list); + lex->first_select_lex()->table_list. + save_and_clear(&lex->auxiliary_table_list); lex->query_tables= 0; lex->query_tables_last= &lex->query_tables; } @@ -7985,7 +7980,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length) thd->reset_for_next_command(); if (!parse_sql(thd, & parser_state, NULL, true) && - all_tables_not_ok(thd, lex->select_lex.table_list.first)) + all_tables_not_ok(thd, lex->first_select_lex()->table_list.first)) error= 1; /* Ignore question */ thd->end_statement(); } @@ -8067,6 +8062,9 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, const char *alias_str; LEX *lex= thd->lex; DBUG_ENTER("add_table_to_list"); + DBUG_PRINT("enter", ("Table '%s' Select %p (%u)", + (alias ? alias->str : table->table.str), + this, select_number)); if (!table) DBUG_RETURN(0); // End of memory @@ -8160,7 +8158,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->schema_table_name= ptr->table_name; ptr->schema_table= schema_table; } - ptr->select_lex= lex->current_select; + ptr->select_lex= this; /* We can't cache internal temporary tables between prepares as the table may be deleted before next exection. @@ -8265,7 +8263,6 @@ bool st_select_lex::init_nested_join(THD *thd) nested_join= ptr->nested_join= ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST)))); - join_list->push_front(ptr, thd->mem_root); ptr->embedding= embedding; ptr->join_list= join_list; ptr->alias= (char*) "(nested_join)"; @@ -8371,7 +8368,6 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd) ptr->join_using_fields= prev_join_using; } } - join_list->push_front(ptr, thd->mem_root); nested_join->used_tables= nested_join->not_null_tables= (table_map) 0; DBUG_RETURN(ptr); } @@ -8563,7 +8559,7 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type) bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg) { SELECT_LEX *first_sl= first_select(); - DBUG_ENTER("add_fake_select_lex"); + DBUG_ENTER("st_select_lex_unit::add_fake_select_lex"); DBUG_ASSERT(!fake_select_lex); if (!(fake_select_lex= new (thd_arg->mem_root) SELECT_LEX())) @@ -8573,16 +8569,19 @@ bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg) fake_select_lex->select_number= INT_MAX; fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */ fake_select_lex->make_empty_select(); - fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE; + fake_select_lex->set_linkage(GLOBAL_OPTIONS_TYPE); fake_select_lex->select_limit= 0; + fake_select_lex->no_table_names_allowed= 1; + fake_select_lex->context.outer_context=first_sl->context.outer_context; /* allow item list resolving in fake select for ORDER BY */ fake_select_lex->context.resolve_in_select_list= TRUE; fake_select_lex->context.select_lex= fake_select_lex; fake_select_lex->nest_level_base= first_select()->nest_level_base; - fake_select_lex->nest_level=first_select()->nest_level; + if (fake_select_lex->set_nest_level(first_select()->nest_level)) + DBUG_RETURN(1); if (!is_unit_op()) { @@ -8595,7 +8594,7 @@ bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg) fake_select_lex->no_table_names_allowed= 1; thd_arg->lex->current_select= fake_select_lex; } - thd_arg->lex->pop_context(); + //thd_arg->lex->pop_context("add fake"); DBUG_RETURN(0); } @@ -8631,7 +8630,7 @@ push_new_name_resolution_context(THD *thd, left_op->first_leaf_for_name_resolution(); on_context->last_name_resolution_table= right_op->last_leaf_for_name_resolution(); - return thd->lex->push_context(on_context, thd->mem_root); + return thd->lex->push_context(on_context); } @@ -8986,7 +8985,7 @@ bool check_simple_select() { THD *thd= current_thd; LEX *lex= thd->lex; - if (lex->current_select != &lex->select_lex) + if (lex->current_select != lex->first_select_lex()) { char command[80]; Lex_input_stream *lip= & thd->m_parser_state->m_lip; @@ -9086,7 +9085,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) const char *msg= 0; TABLE_LIST *table; LEX *lex= thd->lex; - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); DBUG_ENTER("multi_update_precheck"); if (select_lex->item_list.elements != lex->value_list.elements) @@ -9122,7 +9121,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) /* Is there tables of subqueries? */ - if (&lex->select_lex != lex->all_selects_list) + if (lex->first_select_lex() != lex->all_selects_list) { DBUG_PRINT("info",("Checking sub query list")); for (table= tables; table; table= table->next_global) @@ -9165,7 +9164,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) bool multi_delete_precheck(THD *thd, TABLE_LIST *tables) { - SELECT_LEX *select_lex= &thd->lex->select_lex; + SELECT_LEX *select_lex= thd->lex->first_select_lex(); TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first; TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last; DBUG_ENTER("multi_delete_precheck"); @@ -9282,7 +9281,7 @@ static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl, bool multi_delete_set_locks_and_link_aux_tables(LEX *lex) { - TABLE_LIST *tables= lex->select_lex.table_list.first; + TABLE_LIST *tables= lex->first_select_lex()->table_list.first; TABLE_LIST *target_tbl; DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables"); @@ -9327,7 +9326,8 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex) bool update_precheck(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("update_precheck"); - if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements) + if (thd->lex->first_select_lex()->item_list.elements != + thd->lex->value_list.elements) { my_message(ER_WRONG_VALUE_COUNT, ER_THD(thd, ER_WRONG_VALUE_COUNT), MYF(0)); DBUG_RETURN(TRUE); @@ -9410,7 +9410,7 @@ void create_table_set_open_action_and_adjust_tables(LEX *lex) else create_table->open_type= OT_BASE_ONLY; - if (!lex->select_lex.item_list.elements) + if (!lex->first_select_lex()->item_list.elements) { /* Avoid opening and locking target table for ordinary CREATE TABLE @@ -9441,7 +9441,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *create_table) { LEX *lex= thd->lex; - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); ulong want_priv; bool error= TRUE; // Error message is given DBUG_ENTER("create_table_precheck"); @@ -9950,6 +9950,7 @@ bool parse_sql(THD *thd, Parser_state *parser_state, ((thd->variables.sql_mode & MODE_ORACLE) ? ORAparse(thd) : MYSQLparse(thd)) != 0; + thd->lex->current_select= thd->lex->first_select_lex(); /* Check that if MYSQLparse() failed either thd->is_error() is set, or an diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 9fc67272bfa..5385386349d 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -917,7 +917,8 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, goto end; table->get_fields_in_item_tree= true; - func_expr->walk(&Item::change_context_processor, 0, &lex.select_lex.context); + func_expr->walk(&Item::change_context_processor, 0, + &lex.first_select_lex()->context); thd->where= "partition function"; /* In execution we must avoid the use of thd->change_item_tree since diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index 0c1c9fb02de..2b069d06551 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -51,7 +51,7 @@ bool Sql_cmd_alter_table_exchange_partition::execute(THD *thd) /* Moved from mysql_execute_command */ LEX *lex= thd->lex; /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */ - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); /* first table of first SELECT_LEX */ TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first; /* @@ -739,7 +739,7 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd) int error; ha_partition *partition; ulong timeout= thd->variables.lock_wait_timeout; - TABLE_LIST *first_table= thd->lex->select_lex.table_list.first; + TABLE_LIST *first_table= thd->lex->first_select_lex()->table_list.first; Alter_info *alter_info= &thd->lex->alter_info; uint table_counter, i; List<String> partition_names_list; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index b81d1f7542b..ed098107dc2 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -167,20 +167,6 @@ class Prepared_statement: public Statement uint param_count; uint last_errno; uint flags; - /* - The value of thd->select_number at the end of the PREPARE phase. - - The issue is: each statement execution opens VIEWs, which may cause - select_lex objects to be created, and select_number values to be assigned. - - On the other hand, PREPARE assigns select_number values for triggers and - subqueries. - - In order for select_number values from EXECUTE not to conflict with - select_number values from PREPARE, we keep the number and set it at each - execution. - */ - uint select_number_after_prepare; char last_error[MYSQL_ERRMSG_SIZE]; my_bool iterations; my_bool start_param; @@ -1400,7 +1386,7 @@ static int mysql_test_update(Prepared_statement *stmt, int res; THD *thd= stmt->thd; uint table_count= 0; - SELECT_LEX *select= &stmt->lex->select_lex; + SELECT_LEX *select= stmt->lex->first_select_lex(); #ifndef NO_EMBEDDED_ACCESS_CHECKS uint want_privilege; #endif @@ -1454,10 +1440,10 @@ static int mysql_test_update(Prepared_statement *stmt, table_list->table->grant.want_privilege= want_privilege; table_list->register_want_access(want_privilege); #endif - thd->lex->select_lex.no_wrap_view_item= TRUE; + thd->lex->first_select_lex()->no_wrap_view_item= TRUE; res= setup_fields(thd, Ref_ptr_array(), select->item_list, MARK_COLUMNS_READ, 0, 0); - thd->lex->select_lex.no_wrap_view_item= FALSE; + thd->lex->first_select_lex()->no_wrap_view_item= FALSE; if (res) goto error; #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -1522,10 +1508,10 @@ static bool mysql_test_delete(Prepared_statement *stmt, goto error; } - DBUG_RETURN(mysql_prepare_delete(thd, table_list, - lex->select_lex.with_wild, - lex->select_lex.item_list, - &lex->select_lex.where, + DBUG_RETURN(mysql_prepare_delete(thd, table_list, + lex->first_select_lex()->with_wild, + lex->first_select_lex()->item_list, + &lex->first_select_lex()->where, &delete_while_scanning)); error: DBUG_RETURN(TRUE); @@ -1557,7 +1543,7 @@ static int mysql_test_select(Prepared_statement *stmt, SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_test_select"); - lex->select_lex.context.resolve_in_select_list= TRUE; + lex->first_select_lex()->context.resolve_in_select_list= TRUE; ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL; if (check_dependencies_in_with_clauses(lex->with_clauses_list)) @@ -1593,7 +1579,7 @@ static int mysql_test_select(Prepared_statement *stmt, if (!lex->describe && !thd->lex->analyze_stmt && !stmt->is_sql_prepare()) { /* Make copy of item list, as change_columns may change it */ - List<Item> fields(lex->select_lex.item_list); + List<Item> fields(lex->first_select_lex()->item_list); /* Change columns if a procedure like analyse() */ if (unit->last_procedure && unit->last_procedure->change_columns(thd, fields)) @@ -1751,7 +1737,7 @@ static bool select_like_stmt_test(Prepared_statement *stmt, THD *thd= stmt->thd; LEX *lex= stmt->lex; - lex->select_lex.context.resolve_in_select_list= TRUE; + lex->first_select_lex()->context.resolve_in_select_list= TRUE; if (specific_prepare && (*specific_prepare)(thd)) DBUG_RETURN(TRUE); @@ -1819,7 +1805,7 @@ static bool mysql_test_create_table(Prepared_statement *stmt) DBUG_ENTER("mysql_test_create_table"); THD *thd= stmt->thd; LEX *lex= stmt->lex; - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); bool res= FALSE; bool link_to_local; TABLE_LIST *create_table= lex->query_tables; @@ -2142,7 +2128,7 @@ static bool mysql_test_multidelete(Prepared_statement *stmt, { THD *thd= stmt->thd; - thd->lex->current_select= &thd->lex->select_lex; + thd->lex->current_select= thd->lex->first_select_lex(); if (add_item_to_list(thd, new (thd->mem_root) Item_null(thd))) { @@ -2181,13 +2167,14 @@ static bool mysql_test_multidelete(Prepared_statement *stmt, static int mysql_insert_select_prepare_tester(THD *thd) { - SELECT_LEX *first_select= &thd->lex->select_lex; + SELECT_LEX *first_select= thd->lex->first_select_lex(); TABLE_LIST *second_table= first_select->table_list.first->next_local; /* Skip first table, which is the table we are inserting in */ first_select->table_list.first= second_table; - thd->lex->select_lex.context.table_list= - thd->lex->select_lex.context.first_name_resolution_table= second_table; + thd->lex->first_select_lex()->context.table_list= + thd->lex->first_select_lex()->context.first_name_resolution_table= + second_table; return mysql_insert_select_prepare(thd); } @@ -2225,7 +2212,7 @@ static bool mysql_test_insert_select(Prepared_statement *stmt, return 1; /* store it, because mysql_insert_select_prepare_tester change it */ - first_local_table= lex->select_lex.table_list.first; + first_local_table= lex->first_select_lex()->table_list.first; DBUG_ASSERT(first_local_table != 0); res= @@ -2233,7 +2220,7 @@ static bool mysql_test_insert_select(Prepared_statement *stmt, &mysql_insert_select_prepare_tester, OPTION_SETUP_TABLES_DONE); /* revert changes made by mysql_insert_select_prepare_tester */ - lex->select_lex.table_list.first= first_local_table; + lex->first_select_lex()->table_list.first= first_local_table; return res; } @@ -2259,7 +2246,7 @@ static int mysql_test_handler_read(Prepared_statement *stmt, SQL_HANDLER *ha_table; DBUG_ENTER("mysql_test_handler_read"); - lex->select_lex.context.resolve_in_select_list= TRUE; + lex->first_select_lex()->context.resolve_in_select_list= TRUE; /* We don't have to test for permissions as this is already done during @@ -2268,7 +2255,7 @@ static int mysql_test_handler_read(Prepared_statement *stmt, if (!(ha_table= mysql_ha_read_prepare(thd, tables, lex->ha_read_mode, lex->ident.str, lex->insert_list, - lex->select_lex.where))) + lex->first_select_lex()->where))) DBUG_RETURN(1); if (!stmt->is_sql_prepare()) @@ -2309,7 +2296,7 @@ static bool check_prepared_statement(Prepared_statement *stmt) { THD *thd= stmt->thd; LEX *lex= stmt->lex; - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); TABLE_LIST *tables; enum enum_sql_command sql_command= lex->sql_command; int res= 0; @@ -2318,10 +2305,11 @@ static bool check_prepared_statement(Prepared_statement *stmt) sql_command, stmt->param_count)); lex->first_lists_tables_same(); + lex->fix_first_select_number(); tables= lex->query_tables; /* set context for commands which do not use setup_tables */ - lex->select_lex.context.resolve_in_table_list_only(select_lex-> + lex->first_select_lex()->context.resolve_in_table_list_only(select_lex-> get_table_list()); /* Reset warning count for each query that uses tables */ @@ -3004,7 +2992,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) { tables->reinit_before_use(thd); } - lex->current_select= &lex->select_lex; + lex->current_select= lex->first_select_lex(); if (lex->result) @@ -3869,8 +3857,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) */ status_var_increment(thd->status_var.com_stmt_prepare); + //thd->select_number= 0; if (! (lex= new (mem_root) st_lex_local)) DBUG_RETURN(TRUE); + stmt_lex= lex; if (set_db(thd->db, thd->db_length)) DBUG_RETURN(TRUE); @@ -3976,8 +3966,6 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) trans_rollback_implicit(thd); thd->mdl_context.release_transactional_locks(); } - - select_number_after_prepare= thd->select_number; /* Preserve CHANGE MASTER attributes */ lex_end_stage1(lex); @@ -4114,7 +4102,6 @@ Prepared_statement::execute_loop(String *expanded_query, */ DBUG_ASSERT(thd->free_list == NULL); - thd->select_number= select_number_after_prepare; /* Check if we got an error when sending long data */ if (state == Query_arena::STMT_ERROR) { @@ -4257,7 +4244,6 @@ Prepared_statement::execute_bulk_loop(String *expanded_query, #ifdef DBUG_ASSERT_EXISTS Item *free_list_state= thd->free_list; #endif - thd->select_number= select_number_after_prepare; thd->set_bulk_execution((void *)this); /* Check if we got an error when sending long data */ if (state == Query_arena::STMT_ERROR) @@ -4521,8 +4507,8 @@ bool Prepared_statement::validate_metadata(Prepared_statement *copy) if (is_sql_prepare() || lex->describe) return FALSE; - if (lex->select_lex.item_list.elements != - copy->lex->select_lex.item_list.elements) + if (lex->first_select_lex()->item_list.elements != + copy->lex->first_select_lex()->item_list.elements) { /** Column counts mismatch, update the client */ thd->server_status|= SERVER_STATUS_METADATA_CHANGED; diff --git a/sql/sql_priv.h b/sql/sql_priv.h index db75dc2198b..281373c1da5 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -184,6 +184,9 @@ #define OPTION_SKIP_REPLICATION (1ULL << 37) // THD, user #define OPTION_RPL_SKIP_PARALLEL (1ULL << 38) #define OPTION_FOUND_COMMENT (1ULL << 39) // SELECT, intern, parser +#define OPTION_NO_QUERY_CACHE (1ULL << 40) // SELECT, user +#define OPTION_INTO_CLAUSE (1ULL << 41) // Internal usage +#define OPTION_PROCEDURE_CLAUSE (1ULL << 42) // Internal usage /* The rest of the file is included in the server only */ #ifndef MYSQL_CLIENT @@ -352,6 +355,7 @@ enum enum_parsing_place IN_ON, IN_GROUP_BY, IN_ORDER_BY, + BEFORE_OPT_FIELD_LIST, PARSING_PLACE_SIZE /* always should be the last */ }; diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc index c1a13ebd210..a605f7f6bc4 100644 --- a/sql/sql_profile.cc +++ b/sql/sql_profile.cc @@ -110,7 +110,7 @@ int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table) }; ST_FIELD_INFO *field_info; - Name_resolution_context *context= &thd->lex->select_lex.context; + Name_resolution_context *context= &thd->lex->first_select_lex()->context; int i; for (i= 0; schema_table->fields_info[i].field_name != NULL; i++) @@ -403,7 +403,7 @@ bool PROFILING::show_profiles() QUERY_PROFILE *prof; List<Item> field_list; MEM_ROOT *mem_root= thd->mem_root; - SELECT_LEX *sel= &thd->lex->select_lex; + SELECT_LEX *sel= thd->lex->first_select_lex(); SELECT_LEX_UNIT *unit= &thd->lex->unit; ha_rows idx= 0; Protocol *protocol= thd->protocol; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ba3d2e7da2f..ab938ac92fa 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -347,7 +347,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result, ulong setup_tables_done_option) { bool res; - register SELECT_LEX *select_lex = &lex->select_lex; + register SELECT_LEX *select_lex= lex->first_select_lex(); DBUG_ENTER("handle_select"); MYSQL_SELECT_START(thd->query()); @@ -1082,6 +1082,7 @@ bool JOIN::prepare_stage2() void JOIN::build_explain() { + DBUG_ENTER("JOIN::build_explain"); create_explain_query_if_not_exists(thd->lex, thd->mem_root); have_query_plan= QEP_AVAILABLE; save_explain_data(thd->lex->explain, false /* can overwrite */, @@ -1105,6 +1106,7 @@ void JOIN::build_explain() get_using_temporary_read_tracker(); } } + DBUG_VOID_RETURN; } int JOIN::optimize() @@ -3285,6 +3287,26 @@ void JOIN::save_explain_data(Explain_query *output, bool can_overwrite, bool need_tmp_table, bool need_order, bool distinct) { + DBUG_ENTER("JOIN::save_explain_data"); + DBUG_PRINT("enter", ("Save explain Select_lex: %u (%p) parent lex: %p stmt_lex: %p present select: %u (%p)", + select_lex->select_number, select_lex, + select_lex->parent_lex, thd->stmt_lex, + (output->get_select(select_lex->select_number) ? + select_lex->select_number : 0), + (output->get_select(select_lex->select_number) ? + output->get_select(select_lex->select_number) + ->select_lex : NULL))); + /* + If there is SELECT in this statemet with the same number it must be the + same SELECT + */ + DBUG_ASSERT(select_lex->select_number == UINT_MAX || + select_lex->select_number == INT_MAX || + !output || + !output->get_select(select_lex->select_number) || + output->get_select(select_lex->select_number)->select_lex == + select_lex); + if (select_lex->select_number != UINT_MAX && select_lex->select_number != INT_MAX /* this is not a UNION's "fake select */ && have_query_plan != JOIN::QEP_NOT_PRESENT_YET && @@ -3302,7 +3324,7 @@ void JOIN::save_explain_data(Explain_query *output, bool can_overwrite, } save_explain_data_intern(thd->lex->explain, need_tmp_table, need_order, distinct, message); - return; + DBUG_VOID_RETURN; } /* @@ -3327,6 +3349,7 @@ void JOIN::save_explain_data(Explain_query *output, bool can_overwrite, } } } + DBUG_VOID_RETURN; } @@ -12380,7 +12403,8 @@ void JOIN::join_free() !(select_options & SELECT_NO_UNLOCK) && !select_lex->subquery_in_having && (select_lex == (thd->lex->unit.fake_select_lex ? - thd->lex->unit.fake_select_lex : &thd->lex->select_lex))) + thd->lex->unit.fake_select_lex : + thd->lex->first_select_lex()))) { /* TODO: unlock tables even if the join isn't top level select in the @@ -18067,7 +18091,7 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, new_table.no_rows= table->no_rows; if (create_internal_tmp_table(&new_table, table->key_info, start_recinfo, recinfo, - thd->lex->select_lex.options | + thd->lex->builtin_select.options | thd->variables.option_bits)) goto err2; if (open_tmp_table(&new_table)) @@ -24544,7 +24568,8 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta, */ if (real_table->merged_for_insert) { - TABLE_LIST *view_child= real_table->view->select_lex.table_list.first; + TABLE_LIST *view_child= + real_table->view->first_select_lex()->table_list.first; for (;view_child; view_child= view_child->next_local) { if (view_child->table == table) @@ -24976,8 +25001,9 @@ int JOIN::save_explain_data_intern(Explain_query *output, JOIN *join= this; /* Legacy: this code used to be a non-member function */ int cur_error= 0; DBUG_ENTER("JOIN::save_explain_data_intern"); - DBUG_PRINT("info", ("Select 0x%lx, type %s, message %s", - (ulong)join->select_lex, join->select_lex->type, + DBUG_PRINT("info", ("Select %p (%u), type %s, message %s", + join->select_lex, join->select_lex->select_number, + join->select_lex->type, message ? message : "NULL")); DBUG_ASSERT(have_query_plan == QEP_AVAILABLE); /* fake_select_lex is created/printed by Explain_union */ @@ -24994,6 +25020,11 @@ int JOIN::save_explain_data_intern(Explain_query *output, { explain= new (output->mem_root) Explain_select(output->mem_root, thd->lex->analyze_stmt); + if (!explain) + DBUG_RETURN(1); // EoM +#ifndef DBUG_OFF + explain->select_lex= select_lex; +#endif join->select_lex->set_explain_type(true); explain->select_id= join->select_lex->select_number; @@ -25605,6 +25636,18 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type) { str->append("/* select#"); str->append_ulonglong(select_number); + if (thd->lex->describe & DESCRIBE_EXTENDED2) + { + str->append("/"); + str->append_ulonglong(nest_level); + + if (master_unit()->fake_select_lex && + master_unit()->first_select() == this) + { + str->append(" Filter Select: "); + master_unit()->fake_select_lex->print(thd, str, query_type); + } + } str->append(" */ "); } diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc index 53c9c160593..18c76d7446d 100644 --- a/sql/sql_sequence.cc +++ b/sql/sql_sequence.cc @@ -220,8 +220,8 @@ bool check_sequence_fields(LEX *lex, List<Create_field> *fields) err: my_error(ER_SEQUENCE_INVALID_TABLE_STRUCTURE, MYF(0), - lex->select_lex.table_list.first->db, - lex->select_lex.table_list.first->table_name, reason); + lex->first_select_lex()->table_list.first->db, + lex->first_select_lex()->table_list.first->table_name, reason); DBUG_RETURN(TRUE); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 68ded844938..27e061fca45 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3936,8 +3936,9 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, case SQLCOM_SHOW_TABLE_STATUS: case SQLCOM_SHOW_TRIGGERS: case SQLCOM_SHOW_EVENTS: - thd->make_lex_string(&lookup_field_values->db_value, - lex->select_lex.db, strlen(lex->select_lex.db)); + thd->make_lex_string(&lookup_field_values->db_value, + lex->first_select_lex()->db, + strlen(lex->first_select_lex()->db)); if (wild) { thd->make_lex_string(&lookup_field_values->table_value, @@ -4330,10 +4331,10 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, temporary LEX. The latter is required to correctly open views and produce table describing their structure. */ - if (make_table_list(thd, &lex->select_lex, &db_name, &table_name)) + if (make_table_list(thd, lex->first_select_lex(), &db_name, &table_name)) goto end; - table_list= lex->select_lex.table_list.first; + table_list= lex->first_select_lex()->table_list.first; if (is_show_fields_or_keys) { @@ -6380,7 +6381,7 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, & 'field_translation_end' are uninitialized is this case. */ - List<Item> *fields= &tables->view->select_lex.item_list; + List<Item> *fields= &tables->view->first_select_lex()->item_list; List_iterator<Item> it(*fields); Item *item; Item_field *field; @@ -7354,7 +7355,7 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond) TABLE *table= tables->table; CHARSET_INFO *cs= system_charset_info; OPEN_TABLE_LIST *open_list; - if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild)) + if (!(open_list=list_open_tables(thd, thd->lex->first_select_lex()->db, wild)) && thd->is_fatal_error) DBUG_RETURN(1); @@ -7768,7 +7769,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) tmp_table_param->table_charset= cs; tmp_table_param->field_count= field_count; tmp_table_param->schema_table= 1; - SELECT_LEX *select_lex= thd->lex->current_select; + SELECT_LEX *select_lex= table_list->select_lex; bool keep_row_order= sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND; if (!(table= create_tmp_table(thd, tmp_table_param, field_list, (ORDER*) 0, 0, 0, @@ -7805,7 +7806,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) static int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) { ST_FIELD_INFO *field_info= schema_table->fields_info; - Name_resolution_context *context= &thd->lex->select_lex.context; + Name_resolution_context *context= &thd->lex->first_select_lex()->context; for (; field_info->field_name; field_info++) { if (field_info->old_name) @@ -7865,14 +7866,14 @@ int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) char tmp[128]; String buffer(tmp,sizeof(tmp), thd->charset()); LEX *lex= thd->lex; - Name_resolution_context *context= &lex->select_lex.context; + Name_resolution_context *context= &lex->first_select_lex()->context; ST_FIELD_INFO *field_info= &schema_table->fields_info[2]; LEX_CSTRING field_name= {field_info->field_name, strlen(field_info->field_name) }; buffer.length(0); buffer.append(field_info->old_name); - buffer.append(lex->select_lex.db); + buffer.append(lex->first_select_lex()->db); if (lex->wild && lex->wild->ptr()) { buffer.append(STRING_WITH_LEN(" (")); @@ -7905,7 +7906,7 @@ int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) int fields_arr[]= {3, 15, 14, 6, 16, 5, 17, 18, 19, -1}; int *field_num= fields_arr; ST_FIELD_INFO *field_info; - Name_resolution_context *context= &thd->lex->select_lex.context; + Name_resolution_context *context= &thd->lex->first_select_lex()->context; for (; *field_num >= 0; field_num++) { @@ -7936,7 +7937,7 @@ int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) int fields_arr[]= {0, 2, 1, 3, -1}; int *field_num= fields_arr; ST_FIELD_INFO *field_info; - Name_resolution_context *context= &thd->lex->select_lex.context; + Name_resolution_context *context= &thd->lex->first_select_lex()->context; for (; *field_num >= 0; field_num++) { @@ -7963,7 +7964,7 @@ int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) int fields_arr[]= {2, 3, 4, 27, 24, 23, 22, 26, 28, 29, 30, -1}; int *field_num= fields_arr; ST_FIELD_INFO *field_info; - Name_resolution_context *context= &thd->lex->select_lex.context; + Name_resolution_context *context= &thd->lex->first_select_lex()->context; for (; *field_num >= 0; field_num++) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9c746e470f7..8255aeb34d1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4673,7 +4673,7 @@ int create_table_impl(THD *thd, /* Restart statement transactions for the case of CREATE ... SELECT. */ - if (thd->lex->select_lex.item_list.elements && + if (thd->lex->first_select_lex()->item_list.elements && restart_trans_for_tables(thd, thd->lex->query_tables)) goto err; } @@ -9758,8 +9758,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, Filesort_tracker dummy_tracker(false); Filesort fsort(order, HA_POS_ERROR, true, NULL); - if (thd->lex->select_lex.setup_ref_array(thd, order_num) || - setup_order(thd, thd->lex->select_lex.ref_pointer_array, + if (thd->lex->first_select_lex()->setup_ref_array(thd, order_num) || + setup_order(thd, thd->lex->first_select_lex()->ref_pointer_array, &tables, fields, all_fields, order)) goto err; diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index dcce8ae3724..dd33d75a7db 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1357,11 +1357,12 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, List_iterator_fast<LEX_CSTRING> it_connection_cl_name(trigger_list->connection_cl_names); List_iterator_fast<LEX_CSTRING> it_db_cl_name(trigger_list->db_cl_names); List_iterator_fast<ulonglong> it_create_times(trigger_list->create_times); - LEX *old_lex= thd->lex, lex; + LEX *old_lex= thd->lex, *old_stmt_lex= thd->stmt_lex; + LEX lex; sp_rcontext *save_spcont= thd->spcont; sql_mode_t save_sql_mode= thd->variables.sql_mode; - thd->lex= &lex; + thd->lex= thd->stmt_lex= &lex; save_db.str= thd->db; save_db.length= thd->db_length; @@ -1580,6 +1581,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, } thd->reset_db(save_db.str, save_db.length); thd->lex= old_lex; + thd->stmt_lex= old_stmt_lex; thd->spcont= save_spcont; thd->variables.sql_mode= save_sql_mode; @@ -1593,6 +1595,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, err_with_lex_cleanup: lex_end(&lex); thd->lex= old_lex; + thd->stmt_lex= old_stmt_lex; thd->spcont= save_spcont; thd->variables.sql_mode= save_sql_mode; thd->reset_db(save_db.str, save_db.length); diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 1d6edbc5fc9..3fcab7c1bd8 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -493,7 +493,7 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref) bool Sql_cmd_truncate_table::execute(THD *thd) { bool res= TRUE; - TABLE_LIST *first_table= thd->lex->select_lex.table_list.first; + TABLE_LIST *first_table= thd->lex->first_select_lex()->table_list.first; DBUG_ENTER("Sql_cmd_truncate_table::execute"); if (check_one_table_access(thd, DROP_ACL, first_table)) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 362837834f2..5e7f871d472 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1393,7 +1393,7 @@ bool st_select_lex_unit::exec() union_result->change_select(); if (fake_select_lex) { - if (sl != &thd->lex->select_lex) + if (sl != thd->lex->first_select_lex()) fake_select_lex->uncacheable|= sl->uncacheable; else fake_select_lex->uncacheable= 0; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 3f39765b531..d8050b1ec77 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -272,7 +272,7 @@ int mysql_update(THD *thd, SQL_SELECT *select= NULL; SORT_INFO *file_sort= 0; READ_RECORD info; - SELECT_LEX *select_lex= &thd->lex->select_lex; + SELECT_LEX *select_lex= thd->lex->first_select_lex(); ulonglong id; List<Item> all_fields; killed_state killed_status= NOT_KILLED; @@ -321,7 +321,7 @@ int mysql_update(THD *thd, table->covering_keys= table->s->keys_in_use; table->quick_keys.clear_all(); - query_plan.select_lex= &thd->lex->select_lex; + query_plan.select_lex= thd->lex->first_select_lex(); query_plan.table= table; #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Force privilege re-checking for views after they have been opened. */ @@ -1076,7 +1076,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, TABLE *table= table_list->table; #endif List<Item> all_fields; - SELECT_LEX *select_lex= &thd->lex->select_lex; + SELECT_LEX *select_lex= thd->lex->first_select_lex(); DBUG_ENTER("mysql_prepare_update"); #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -1353,7 +1353,7 @@ int mysql_multi_update_prepare(THD *thd) LEX *lex= thd->lex; TABLE_LIST *table_list= lex->query_tables; TABLE_LIST *tl; - List<Item> *fields= &lex->select_lex.item_list; + List<Item> *fields= &lex->first_select_lex()->item_list; table_map tables_for_update; bool update_view= 0; /* @@ -1394,14 +1394,15 @@ int mysql_multi_update_prepare(THD *thd) if (mysql_handle_derived(lex, DT_PREPARE)) DBUG_RETURN(TRUE); - if (setup_tables_and_check_access(thd, &lex->select_lex.context, - &lex->select_lex.top_join_list, + if (setup_tables_and_check_access(thd, + &lex->first_select_lex()->context, + &lex->first_select_lex()->top_join_list, table_list, - lex->select_lex.leaf_tables, FALSE, - UPDATE_ACL, SELECT_ACL, FALSE)) + lex->first_select_lex()->leaf_tables, + FALSE, UPDATE_ACL, SELECT_ACL, FALSE)) DBUG_RETURN(TRUE); - if (lex->select_lex.handle_derived(thd->lex, DT_MERGE)) + if (lex->first_select_lex()->handle_derived(thd->lex, DT_MERGE)) DBUG_RETURN(TRUE); if (setup_fields_with_no_wrap(thd, Ref_ptr_array(), @@ -1424,13 +1425,14 @@ int mysql_multi_update_prepare(THD *thd) thd->table_map_for_update= tables_for_update= get_table_map(fields); - if (unsafe_key_update(lex->select_lex.leaf_tables, tables_for_update)) + if (unsafe_key_update(lex->first_select_lex()->leaf_tables, + tables_for_update)) DBUG_RETURN(true); /* Setup timestamp handling and locking mode */ - List_iterator<TABLE_LIST> ti(lex->select_lex.leaf_tables); + List_iterator<TABLE_LIST> ti(lex->first_select_lex()->leaf_tables); while ((tl= ti++)) { TABLE *table= tl->table; @@ -1523,7 +1525,7 @@ int mysql_multi_update_prepare(THD *thd) Check that we are not using table that we are updating, but we should skip all tables of UPDATE SELECT itself */ - lex->select_lex.exclude_from_table_unique_test= TRUE; + lex->first_select_lex()->exclude_from_table_unique_test= TRUE; /* We only need SELECT privilege for columns in the values list */ ti.rewind(); while ((tl= ti++)) @@ -1555,7 +1557,7 @@ int mysql_multi_update_prepare(THD *thd) Set exclude_from_table_unique_test value back to FALSE. It is needed for further check in multi_update::prepare whether to use record cache. */ - lex->select_lex.exclude_from_table_unique_test= FALSE; + lex->first_select_lex()->exclude_from_table_unique_test= FALSE; if (lex->save_prep_leaf_tables()) DBUG_RETURN(TRUE); @@ -1584,7 +1586,7 @@ bool mysql_multi_update(THD *thd, DBUG_ENTER("mysql_multi_update"); if (!(*result= new (thd->mem_root) multi_update(thd, table_list, - &thd->lex->select_lex.leaf_tables, + &thd->lex->first_select_lex()->leaf_tables, fields, values, handle_duplicates, ignore))) { diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 26941e9d6e7..7213f4a4e8a 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -254,7 +254,7 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view, LEX *lex= thd->lex; /* first table in list is target VIEW name => cut off it */ TABLE_LIST *tbl; - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); SELECT_LEX *sl; bool res= TRUE; DBUG_ENTER("create_view_precheck"); @@ -324,7 +324,9 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view, } } - if (&lex->select_lex != lex->all_selects_list) +#if 0 + if (lex->first_select_lex() != lex->all_selects_list) +#endif { /* check tables of subqueries */ for (tbl= tables; tbl; tbl= tbl->next_global) @@ -400,7 +402,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, TABLE_LIST *view= lex->unlink_first_table(&link_to_local); TABLE_LIST *tables= lex->query_tables; TABLE_LIST *tbl; - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); SELECT_LEX *sl; SELECT_LEX_UNIT *unit= &lex->unit; bool res= FALSE; @@ -982,7 +984,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, view->algorithm != VIEW_ALGORITHM_TMPTABLE))) { /* TODO: change here when we will support UNIONs */ - for (TABLE_LIST *tbl= lex->select_lex.table_list.first; + for (TABLE_LIST *tbl= lex->first_select_lex()->table_list.first; tbl; tbl= tbl->next_local) { @@ -1100,8 +1102,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, UNION */ if (view->updatable_view && - !lex->select_lex.master_unit()->is_unit_op() && - !(lex->select_lex.table_list.first)->next_local && + !lex->first_select_lex()->master_unit()->is_unit_op() && + !(lex->first_select_lex()->table_list.first)->next_local && find_table_in_global_list(lex->query_tables->next_global, lex->query_tables->db, lex->query_tables->table_name)) @@ -1148,7 +1150,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, bool open_view_no_parse) { - SELECT_LEX *end, *UNINIT_VAR(view_select); + SELECT_LEX_NODE *end; + SELECT_LEX *UNINIT_VAR(view_select); LEX *old_lex, *lex; Query_arena *arena, backup; TABLE_LIST *top_view= table->top_table(); @@ -1193,8 +1196,6 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, */ mysql_derived_reinit(thd, NULL, table); - thd->select_number+= table->view->number_of_selects; - DEBUG_SYNC(thd, "after_cached_view_opened"); DBUG_RETURN(0); } @@ -1349,8 +1350,6 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, goto end; lex_start(thd); - view_select= &lex->select_lex; - view_select->select_number= ++thd->select_number; sql_mode_t saved_mode= thd->variables.sql_mode; /* switch off modes which can prevent normal parsing of VIEW @@ -1385,8 +1384,8 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, parse_status= parse_sql(thd, & parser_state, table->view_creation_ctx); - lex->number_of_selects= - (thd->select_number - view_select->select_number) + 1; + view_select= lex->first_select_lex(); + //view_select->select_number= ++thd->select_number; /* Restore environment. */ @@ -1537,7 +1536,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, This may change in future, for example if we enable merging of views with subqueries in select list. */ - view_main_select_tables= lex->select_lex.table_list.first; + view_main_select_tables= lex->first_select_lex()->table_list.first; /* Let us set proper lock type for tables of the view's main @@ -1565,7 +1564,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, /* Fields in this view can be used in upper select in case of merge. */ if (table->select_lex) - table->select_lex->add_where_field(&lex->select_lex); + table->select_lex->add_where_field(lex->first_select_lex()); } /* This method has a dependency on the proper lock type being set, @@ -1587,8 +1586,8 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, old_lex->safe_to_cache_query= (old_lex->safe_to_cache_query && lex->safe_to_cache_query); /* move SQL_CACHE to whole query */ - if (view_select->options & OPTION_TO_QUERY_CACHE) - old_lex->select_lex.options|= OPTION_TO_QUERY_CACHE; + if (lex->first_select_lex()->options & OPTION_TO_QUERY_CACHE) + old_lex->first_select_lex()->options|= OPTION_TO_QUERY_CACHE; #ifndef NO_EMBEDDED_ACCESS_CHECKS if (table->view_suid) @@ -1670,9 +1669,10 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, tbl->grant.want_privilege= top_view->grant.orig_want_privilege; /* prepare view context */ - lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables); - lex->select_lex.context.outer_context= 0; - lex->select_lex.select_n_having_items+= + lex->first_select_lex()-> + context.resolve_in_table_list_only(view_main_select_tables); + lex->first_select_lex()->context.outer_context= 0; + lex->first_select_lex()->select_n_having_items+= table->select_lex->select_n_having_items; table->where= view_select->where; @@ -1683,12 +1683,13 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, */ if (!table->select_lex->master_unit()->is_unit_op() && table->select_lex->order_list.elements == 0) - table->select_lex->order_list.push_back(&lex->select_lex.order_list); + table->select_lex->order_list. + push_back(&lex->first_select_lex()->order_list); else { if (old_lex->sql_command == SQLCOM_SELECT && (old_lex->describe & DESCRIBE_EXTENDED) && - lex->select_lex.order_list.elements && + lex->first_select_lex()->order_list.elements && !table->select_lex->master_unit()->is_unit_op()) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, @@ -1723,7 +1724,11 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, lex->unit.include_down(table->select_lex); lex->unit.slave= view_select; // fix include_down initialisation /* global SELECT list linking */ - end= view_select; // primary SELECT_LEX is always last + /* + The primary SELECT_LEX is always last (because parsed first) if WITH not + used, otherwise it is good start point for last element finding + */ + for (end= view_select; end->link_next; end= end->link_next); end->link_next= old_lex->all_selects_list; old_lex->all_selects_list->link_prev= &end->link_next; old_lex->all_selects_list= lex->all_selects_list; @@ -1905,7 +1910,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view) */ if ((!view->view && !view->belong_to_view) || thd->lex->sql_command == SQLCOM_INSERT || - thd->lex->select_lex.select_limit == 0) + thd->lex->first_select_lex()->select_limit == 0) DBUG_RETURN(FALSE); /* it is normal table or query without LIMIT */ table= view->table; view= view->top_table(); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e4555ddeb11..25e7d2aab46 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -506,6 +506,7 @@ bool LEX::add_select_to_union_list(bool is_union_distinct, { const char *type_name= (type == INTERSECT_TYPE ? "INTERSECT" : (type == EXCEPT_TYPE ? "EXCEPT" : "UNION")); + DBUG_ENTER("LEX::add_select_to_union_list"); /* Only the last SELECT can have INTO. Since the grammar won't allow INTO in a nested SELECT, we make this check only when creating a top-level SELECT. @@ -513,28 +514,28 @@ bool LEX::add_select_to_union_list(bool is_union_distinct, if (is_top_level && result) { my_error(ER_WRONG_USAGE, MYF(0), type_name, "INTO"); - return TRUE; + DBUG_RETURN(TRUE); } if (current_select->order_list.first && !current_select->braces) { my_error(ER_WRONG_USAGE, MYF(0), type_name, "ORDER BY"); - return TRUE; + DBUG_RETURN(TRUE); } if (current_select->explicit_limit && !current_select->braces) { my_error(ER_WRONG_USAGE, MYF(0), type_name, "LIMIT"); - return TRUE; + DBUG_RETURN(TRUE); } if (current_select->linkage == GLOBAL_OPTIONS_TYPE) { thd->parse_error(); - return TRUE; + DBUG_RETURN(TRUE); } if (!is_union_distinct && (type == INTERSECT_TYPE || type == EXCEPT_TYPE)) { my_error(ER_WRONG_USAGE, MYF(0), type_name, "ALL"); - return TRUE; + DBUG_RETURN(TRUE); } /* Priority implementation, but also trying to keep things as flat @@ -549,27 +550,26 @@ bool LEX::add_select_to_union_list(bool is_union_distinct, */ SELECT_LEX *prev= exclude_last_select(); if (add_unit_in_brackets(prev)) - return TRUE; - return add_select_to_union_list(is_union_distinct, type, 0); + DBUG_RETURN(TRUE); + bool res= add_select_to_union_list(is_union_distinct, type, 0); + DBUG_RETURN(res); } else { check_automatic_up(type); } - /* This counter shouldn't be incremented for UNION parts */ - nest_level--; if (mysql_new_select(this, 0, NULL)) - return TRUE; + DBUG_RETURN(TRUE); mysql_init_select(this); - current_select->linkage= type; + current_select->set_linkage(type); if (is_union_distinct) /* UNION DISTINCT - remember position */ { current_select->master_unit()->union_distinct= current_select; } - else - DBUG_ASSERT(type == UNION_TYPE); - return FALSE; + //else + // DBUG_ASSERT(type == UNION_TYPE); + DBUG_RETURN(FALSE); } @@ -614,6 +614,7 @@ void sp_create_assignment_lex(THD *thd, bool no_lookahead) lex->sphead->m_tmp_query= lip->get_tok_end(); /* Inherit from outer lex. */ lex->option_type= old_lex->option_type; + lex->main_select_push(); } } @@ -673,6 +674,9 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead) if (sp->add_instr(i)) return true; } + lex->pop_select(); + if (Lex->check_main_unit_semantics()) + return true; enum_var_type inner_option_type= lex->option_type; if (lex->sphead->restore_lex(thd)) return true; @@ -777,6 +781,20 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) LEX_CSTRING name; uint offset; } sp_cursor_name_and_offset; + struct + { + enum sub_select_type unit_type; + bool distinct; + } unit_operation; + struct + { + SELECT_LEX *first; + SELECT_LEX *prev_last; + } select_list; + SQL_I_List<ORDER> *select_order; + Lex_select_lock select_lock; + Lex_select_limit select_limit; + Lex_order_limit_lock *order_limit_lock; /* pointers */ Create_field *create_field; @@ -821,6 +839,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) handlerton *db_type; st_select_lex *select_lex; + st_select_lex_unit *select_lex_unit; struct p_elem_val *p_elem_value; class Window_frame *window_frame; class Window_frame_bound *window_frame_bound; @@ -829,7 +848,6 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) /* enums */ enum enum_view_suid view_suid; - enum sub_select_type unit_type; enum Condition_information_item::Name cond_info_item_name; enum enum_diag_condition_item_name diag_condition_item_name; enum Diagnostics_information::Which_area diag_area; @@ -866,10 +884,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %parse-param { THD *thd } %lex-param { THD *thd } /* - Currently there are 102 shift/reduce conflicts. + Currently there are 98 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 102 +%expect 96 /* Comments for TOKENS. @@ -1182,6 +1200,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token LEAVES %token LEAVE_SYM %token LEFT /* SQL-2003-R */ +%token LEFT_PAREN_ALT /* INTERNAL */ +%token LEFT_PAREN_WITH /* INTERNAL */ +%token LEFT_PAREN_LIKE /* INTERNAL */ %token LESS_SYM %token LEVEL_SYM %token LEX_HOSTNAME @@ -1608,6 +1629,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %right NOT_SYM NOT2_SYM %right BINARY COLLATE_SYM %left INTERVAL_SYM +/* +%left INTERSECT_SYM +%left UNION_SYM EXCEPT_SYM +%left ',' +*/ %type <lex_str> IDENT IDENT_QUOTED DECIMAL_NUM FLOAT_NUM NUM LONG_NUM @@ -1625,7 +1651,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); NCHAR_STRING %type <lex_str_ptr> - opt_table_alias + opt_table_alias_clause + table_alias_clause %type <lex_string_with_pos> ident ident_with_tok_start @@ -1670,7 +1697,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_temporary all_or_any opt_distinct opt_ignore_leaves fulltext_options union_option opt_not - select_derived_init transaction_access_mode_types + transaction_access_mode_types opt_natural_language_mode opt_query_expansion opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt @@ -1781,9 +1808,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); join_table_list join_table table_factor table_ref esc_table_ref table_primary_ident table_primary_derived - select_derived derived_table_list - select_derived_union - derived_query_specification + derived_table_list table_reference_list_parens + nested_table_reference_list join_table_parens %type <date_time_type> date_time_type; %type <interval> interval @@ -1823,12 +1849,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <variable> internal_variable_name %type <select_lex> subselect - get_select_lex get_select_lex_derived query_specification - query_term_union_not_ready - query_term_union_ready + query_primary + query_primary_parens + +%type <select_lex_unit> query_expression_body - select_paren_derived + query_expression + query_expression_unit %type <boolfunc2creator> comp_op @@ -1840,11 +1868,25 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <virtual_column> opt_check_constraint check_constraint virtual_column_func column_default_expr -%type <unit_type> unit_type_decl + +%type <unit_operation> unit_type_decl + +%type <select_lock> + opt_select_lock_type + select_lock_type + opt_lock_wait_timeout_new + +%type <select_limit> opt_limit_clause limit_clause limit_options + +%type <order_limit_lock> + query_expression_tail + order_or_limit + +%type <select_order> opt_order_clause order_clause order_list %type <NONE> analyze_stmt_command - query verb_clause create change select do drop insert replace insert2 + query verb_clause create change select_new do drop insert replace insert2 insert_values update delete truncate rename compound_statement show describe load alter optimize keycache preload flush reset purge begin commit rollback savepoint release @@ -1860,7 +1902,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); assign_to_keycache_parts preload_list preload_list_or_parts preload_keys preload_keys_parts select_item_list select_item values_list no_braces - opt_limit_clause delete_limit_clause fields opt_values values + delete_limit_clause fields opt_values values procedure_list procedure_list2 procedure_item field_def handler opt_generated_always opt_ignore opt_column opt_restrict @@ -1880,9 +1922,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); table_to_table_list table_to_table opt_table_list opt_as handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild - union_clause union_list - subselect_start opt_and charset - subselect_end select_var_list select_var_list_init help + opt_and charset + select_var_list select_var_list_init help opt_extended_describe shutdown opt_format_json prepare prepare_src execute deallocate @@ -2001,7 +2042,7 @@ query: END_OF_INPUT { if (!thd->bootstrap && - (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) + (!(thd->lex->builtin_select.options & OPTION_FOUND_COMMENT))) my_yyabort_error((ER_EMPTY_QUERY, MYF(0))); thd->lex->sql_command= SQLCOM_EMPTY_QUERY; @@ -2095,7 +2136,7 @@ statement: | revoke | rollback | savepoint - | select + | select_new | set | signal_stmt | show @@ -2125,14 +2166,22 @@ deallocate_or_drop: ; prepare: - PREPARE_SYM ident FROM prepare_src + PREPARE_SYM + { + if (Lex->main_select_push()) + MYSQL_YYABORT; + } + 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= $2; + lex->prepared_stmt_name= $3; + Lex->pop_select(); //main select } ; @@ -2151,10 +2200,21 @@ execute: LEX *lex= thd->lex; lex->sql_command= SQLCOM_EXECUTE; lex->prepared_stmt_name= $2; + if (Lex->main_select_push()) + MYSQL_YYABORT; } execute_using - {} - | EXECUTE_SYM IMMEDIATE_SYM prepare_src + { + 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 { if (Lex->table_or_sp_used()) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), @@ -2162,7 +2222,11 @@ execute: Lex->sql_command= SQLCOM_EXECUTE_IMMEDIATE; } execute_using - {} + { + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; + } ; execute_using: @@ -2447,15 +2511,22 @@ connection_name: /* create a table */ create: - create_or_replace opt_temporary TABLE_SYM opt_if_not_exists table_ident - { + create_or_replace opt_temporary TABLE_SYM opt_if_not_exists + { LEX *lex= thd->lex; lex->create_info.init(); + if (lex->main_select_push()) + MYSQL_YYABORT; + lex->current_select->parsing_place= BEFORE_OPT_FIELD_LIST; if (lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2, $1 | $4)) MYSQL_YYABORT; - if (!lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - TL_WRITE, MDL_EXCLUSIVE)) + } + table_ident + { + LEX *lex= thd->lex; + if (!lex->builtin_select.add_table_to_list(thd, $6, NULL, + TL_OPTION_UPDATING, + TL_WRITE, MDL_EXCLUSIVE)) MYSQL_YYABORT; lex->alter_info.reset(); /* @@ -2470,7 +2541,7 @@ create: create_body { LEX *lex= thd->lex; - lex->current_select= &lex->select_lex; + lex->current_select= &lex->builtin_select; if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) && !lex->create_info.db_type) { @@ -2479,20 +2550,23 @@ create: ER_WARN_USING_OTHER_HANDLER, ER_THD(thd, ER_WARN_USING_OTHER_HANDLER), hton_name(lex->create_info.db_type)->str, - $5->table.str); + $6->table.str); } create_table_set_open_action_and_adjust_tables(lex); + Lex->pop_select(); //main select } | create_or_replace opt_temporary SEQUENCE_SYM opt_if_not_exists table_ident { LEX *lex= thd->lex; + if (Lex->main_select_push()) + MYSQL_YYABORT; lex->create_info.init(); if (lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2, $1 | $4)) MYSQL_YYABORT; - if (!lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - TL_WRITE, MDL_EXCLUSIVE)) + if (!lex->builtin_select.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + TL_WRITE, MDL_EXCLUSIVE)) MYSQL_YYABORT; /* @@ -2515,8 +2589,8 @@ create: if (lex->create_info.seq_create_info->check_and_adjust(1)) { my_error(ER_SEQUENCE_INVALID_DATA, MYF(0), - lex->select_lex.table_list.first->db, - lex->select_lex.table_list.first->table_name); + lex->builtin_select.table_list.first->db, + lex->builtin_select.table_list.first->table_name); MYSQL_YYABORT; } @@ -2528,7 +2602,7 @@ create: Lex->create_info.used_fields|= HA_CREATE_USED_SEQUENCE; Lex->create_info.sequence= 1; - lex->current_select= &lex->select_lex; + lex->current_select= &lex->builtin_select; if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) && !lex->create_info.db_type) { @@ -2540,42 +2614,69 @@ create: $5->table.str); } create_table_set_open_action_and_adjust_tables(lex); + Lex->pop_select(); //main select } - | create_or_replace opt_unique INDEX_SYM opt_if_not_exists ident + | create_or_replace opt_unique INDEX_SYM opt_if_not_exists + { + if (Lex->main_select_push()) + MYSQL_YYABORT; + } + ident opt_key_algorithm_clause ON table_ident { - if (Lex->add_create_index_prepare($8)) + if (Lex->add_create_index_prepare($9)) MYSQL_YYABORT; - if (Lex->add_create_index($2, &$5, $6, $1 | $4)) + if (Lex->add_create_index($2, &$6, $7, $1 | $4)) MYSQL_YYABORT; } '(' key_list ')' opt_lock_wait_timeout normal_key_options - opt_index_lock_algorithm { } - | create_or_replace fulltext INDEX_SYM opt_if_not_exists ident + opt_index_lock_algorithm + { + Lex->pop_select(); //main select + } + | create_or_replace fulltext INDEX_SYM + { + if (Lex->main_select_push()) + MYSQL_YYABORT; + } + opt_if_not_exists ident ON table_ident { - if (Lex->add_create_index_prepare($7)) + if (Lex->add_create_index_prepare($8)) MYSQL_YYABORT; - if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4)) + if (Lex->add_create_index($2, &$6, HA_KEY_ALG_UNDEF, $1 | $5)) MYSQL_YYABORT; } '(' key_list ')' opt_lock_wait_timeout fulltext_key_options - opt_index_lock_algorithm { } - | create_or_replace spatial INDEX_SYM opt_if_not_exists ident + opt_index_lock_algorithm + { + Lex->pop_select(); //main select + } + | create_or_replace spatial INDEX_SYM + { + if (Lex->main_select_push()) + MYSQL_YYABORT; + } + opt_if_not_exists ident ON table_ident { - if (Lex->add_create_index_prepare($7)) + if (Lex->add_create_index_prepare($8)) MYSQL_YYABORT; - if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4)) + if (Lex->add_create_index($2, &$6, HA_KEY_ALG_UNDEF, $1 | $5)) MYSQL_YYABORT; } '(' key_list ')' opt_lock_wait_timeout spatial_key_options - opt_index_lock_algorithm { } + opt_index_lock_algorithm + { + Lex->pop_select(); //main select + } | create_or_replace DATABASE opt_if_not_exists ident { Lex->create_info.default_table_charset= NULL; Lex->create_info.used_fields= 0; + if (Lex->main_select_push()) + MYSQL_YYABORT; } opt_create_database_options { @@ -2583,51 +2684,94 @@ create: if (lex->set_command_with_check(SQLCOM_CREATE_DB, 0, $1 | $3)) MYSQL_YYABORT; lex->name= $4; + Lex->pop_select(); //main select } | create_or_replace definer_opt opt_view_suid VIEW_SYM opt_if_not_exists table_ident { + if (Lex->main_select_push()) + MYSQL_YYABORT; if (Lex->add_create_view(thd, $1 | $5, DTYPE_ALGORITHM_UNDEFINED, $3, $6)) MYSQL_YYABORT; } view_list_opt AS view_select - { } + { + Lex->pop_select(); //main select + } | create_or_replace view_algorithm definer_opt opt_view_suid VIEW_SYM opt_if_not_exists table_ident { if (Lex->add_create_view(thd, $1 | $6, $2, $4, $7)) MYSQL_YYABORT; + if (Lex->main_select_push()) + MYSQL_YYABORT; } view_list_opt AS view_select - { } + { + Lex->pop_select(); //main select + } | create_or_replace definer_opt TRIGGER_SYM - { Lex->create_info.set($1); } + { + if (Lex->main_select_push()) + MYSQL_YYABORT; + Lex->create_info.set($1); + } trigger_tail - { } + { + Lex->pop_select(); //main select + } | create_or_replace definer_opt PROCEDURE_SYM - { Lex->create_info.set($1); } + { + if (Lex->main_select_push()) + MYSQL_YYABORT; + Lex->create_info.set($1); + } sp_tail - { } + { + Lex->pop_select(); //main select + } | create_or_replace definer_opt EVENT_SYM - { Lex->create_info.set($1); } + { + if (Lex->main_select_push()) + MYSQL_YYABORT; + Lex->create_info.set($1); + } event_tail - { } + { + Lex->pop_select(); //main select + } | create_or_replace definer FUNCTION_SYM - { Lex->create_info.set($1); } + { + if (Lex->main_select_push()) + MYSQL_YYABORT; + Lex->create_info.set($1); + } sf_tail - { } + { + Lex->pop_select(); //main select + } | create_or_replace no_definer FUNCTION_SYM - { Lex->create_info.set($1); } + { + if (Lex->main_select_push()) + MYSQL_YYABORT; + Lex->create_info.set($1); + } create_function_tail - { } + { + Lex->pop_select(); //main select + } | create_or_replace no_definer AGGREGATE_SYM FUNCTION_SYM { + if (Lex->main_select_push()) + MYSQL_YYABORT; Lex->create_info.set($1); Lex->udf.type= UDFTYPE_AGGREGATE; } udf_tail - { } + { + Lex->pop_select(); //main select + } | create_or_replace USER_SYM opt_if_not_exists clear_privileges grant_list opt_require_clause opt_resource_options { @@ -2974,7 +3118,7 @@ clear_privileges: lex->columns.empty(); lex->grant= lex->grant_tot_col= 0; lex->all_privileges= 0; - lex->select_lex.db= 0; + lex->builtin_select.db= 0; lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0; bzero((char *)&(lex->mqh),sizeof(lex->mqh)); @@ -3044,8 +3188,13 @@ 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 */ @@ -3356,7 +3505,7 @@ sp_cursor_stmt: DBUG_ASSERT(thd->free_list == NULL); Lex->sphead->reset_lex(thd, $1); } - select + select_new { DBUG_ASSERT(Lex == $1); if ($1->stmt_finalize(thd) || @@ -3462,10 +3611,16 @@ sp_hcond: ; signal_stmt: - SIGNAL_SYM signal_value opt_set_signal_information + SIGNAL_SYM { - if (Lex->add_signal_statement(thd, $2)) + if (Lex->main_select_push()) + YYABORT; + } + signal_value opt_set_signal_information + { + if (Lex->add_signal_statement(thd, $3)) MYSQL_YYABORT; + Lex->pop_select(); //main select } ; @@ -3591,9 +3746,14 @@ resignal_stmt: ; get_diagnostics: - GET_SYM which_area DIAGNOSTICS_SYM diagnostics_information + GET_SYM which_area DIAGNOSTICS_SYM + { + if (Lex->main_select_push()) + YYABORT; + } + diagnostics_information { - Diagnostics_information *info= $4; + Diagnostics_information *info= $5; info->set_which_da($2); @@ -3602,6 +3762,7 @@ get_diagnostics: if (Lex->m_sql_cmd == NULL) MYSQL_YYABORT; + Lex->pop_select(); //main select } ; @@ -3769,7 +3930,16 @@ sp_decl_idents: sp_opt_default: /* Empty */ { $$ = NULL; } - | DEFAULT expr { $$ = $2; } + | DEFAULT + { + if (Lex->main_select_push()) + MYSQL_YYABORT; + } + expr + { + Lex->pop_select(); //main select + $$ = $3; + } ; /* @@ -3871,10 +4041,15 @@ sp_proc_stmt_statement: sp_proc_stmt_return: RETURN_SYM - { Lex->sphead->reset_lex(thd); } + { + Lex->sphead->reset_lex(thd); + if (Lex->main_select_push()) + MYSQL_YYABORT; + } 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) || @@ -3912,6 +4087,8 @@ assignment_source_expr: { DBUG_ASSERT(thd->free_list == NULL); Lex->sphead->reset_lex(thd, $1); + if (Lex->main_select_push()) + MYSQL_YYABORT; } expr { @@ -3920,6 +4097,7 @@ 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; } @@ -4024,9 +4202,14 @@ sp_fetch_list: ; sp_if: - { Lex->sphead->reset_lex(thd); } + { + Lex->sphead->reset_lex(thd); + if (Lex->main_select_push()) + MYSQL_YYABORT; + } expr THEN_SYM { + Lex->pop_select(); //main select LEX *lex= Lex; sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont; @@ -4138,12 +4321,18 @@ case_stmt_specification: ; case_stmt_body: - { Lex->sphead->reset_lex(thd); /* For expr $2 */ } + { + Lex->sphead->reset_lex(thd); /* For expr $2 */ + + if (Lex->main_select_push()) + MYSQL_YYABORT; + } expr { if (Lex->case_stmt_action_expr($2)) MYSQL_YYABORT; + Lex->pop_select(); //main select if (Lex->sphead->restore_lex(thd)) MYSQL_YYABORT; } @@ -4167,6 +4356,9 @@ simple_when_clause: WHEN_SYM { Lex->sphead->reset_lex(thd); /* For expr $3 */ + + if (Lex->main_select_push()) + MYSQL_YYABORT; } expr { @@ -4175,6 +4367,8 @@ 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; @@ -4191,12 +4385,17 @@ 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; @@ -4304,6 +4503,7 @@ 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; } @@ -4316,7 +4516,12 @@ while_body: repeat_body: sp_proc_stmts1 UNTIL_SYM - { Lex->sphead->reset_lex(thd); } + { + Lex->sphead->reset_lex(thd); + + if (Lex->main_select_push()) + MYSQL_YYABORT; + } expr END REPEAT_SYM { LEX *lex= Lex; @@ -4327,6 +4532,8 @@ 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 */ @@ -4355,9 +4562,14 @@ 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 - { } + { + // while body pop main select + } | label_ident ':' REPEAT_SYM { if (Lex->sp_push_loop_label(thd, &$1)) @@ -4382,9 +4594,13 @@ 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); } | REPEAT_SYM @@ -4791,25 +5007,15 @@ size_number: */ create_body: - '(' create_field_list ')' + create_field_list_parens { Lex->create_info.option_list= NULL; } opt_create_table_options opt_create_partitioning opt_create_select {} | opt_create_table_options opt_create_partitioning opt_create_select {} - /* - the following rule is redundant, but there's a shift/reduce - conflict that prevents the rule above from parsing a syntax like - CREATE TABLE t1 (SELECT 1); - */ - | '(' create_select_query_specification ')' - | '(' create_select_query_specification ')' - { Select->set_braces(1);} union_list {} - | '(' create_select_query_specification ')' - { Select->set_braces(1);} union_order_or_limit {} | create_like { Lex->create_info.add(DDL_options_st::OPT_LIKE); - TABLE_LIST *src_table= Lex->select_lex.add_table_to_list(thd, + TABLE_LIST *src_table= Lex->builtin_select.add_table_to_list(thd, $1, NULL, 0, TL_READ, MDL_SHARED_READ); if (! src_table) MYSQL_YYABORT; @@ -4820,32 +5026,51 @@ create_body: create_like: LIKE table_ident { $$= $2; } - | '(' LIKE table_ident ')' { $$= $3; } + | LEFT_PAREN_LIKE LIKE table_ident ')' { $$= $3; } ; opt_create_select: - /* empty */ {} + /* empty */ { } | opt_duplicate opt_as create_select_query_expression ; - + create_select_query_expression: - opt_with_clause SELECT_SYM create_select_part2 opt_table_expression - create_select_part4 - { - Select->set_braces(0); - Select->set_with_clause($1); + query_expression + { + SELECT_LEX *first_select= $1->first_select(); + + Lex->insert_select_hack(first_select); + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; + + if (Lex->sql_command == SQLCOM_INSERT || + Lex->sql_command == SQLCOM_REPLACE) + { + if (Lex->sql_command == SQLCOM_INSERT) + Lex->sql_command= SQLCOM_INSERT_SELECT; + else + Lex->sql_command= SQLCOM_REPLACE_SELECT; + } } - union_clause - | opt_with_clause SELECT_SYM create_select_part2 - create_select_part3_union_not_ready create_select_part4 + | LEFT_PAREN_WITH with_clause query_expression_body ')' { - Select->set_with_clause($1); + SELECT_LEX *first_select= $3->first_select(); + $3->set_with_clause($2); + $2->attach_to(first_select); + + Lex->insert_select_hack(first_select); + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; + + if (Lex->sql_command == SQLCOM_INSERT || + Lex->sql_command == SQLCOM_REPLACE) + { + if (Lex->sql_command == SQLCOM_INSERT) + Lex->sql_command= SQLCOM_INSERT_SELECT; + else + Lex->sql_command= SQLCOM_REPLACE_SELECT; + } } - | '(' create_select_query_specification ')' - | '(' create_select_query_specification ')' - { Select->set_braces(1);} union_list {} - | '(' create_select_query_specification ')' - { Select->set_braces(1);} union_order_or_limit {} ; opt_create_partitioning: @@ -4932,12 +5157,17 @@ partition_entry: thd->parse_error(ER_PARTITION_ENTRY_ERROR); MYSQL_YYABORT; } + if (Lex->main_select_push()) + MYSQL_YYABORT; /* We enter here when opening the frm file to translate partition info string into part_info data structure. */ } - partition {} + partition + { + Lex->pop_select(); //main select + } ; partition: @@ -5545,56 +5775,6 @@ opt_part_option: End of partition parser part */ -create_select_query_specification: - opt_with_clause SELECT_SYM create_select_part2 create_select_part3 - create_select_part4 - { - Select->set_with_clause($1); - } - ; - -create_select_part2: - { - LEX *lex=Lex; - if (lex->sql_command == SQLCOM_INSERT) - lex->sql_command= SQLCOM_INSERT_SELECT; - else if (lex->sql_command == SQLCOM_REPLACE) - lex->sql_command= SQLCOM_REPLACE_SELECT; - /* - The following work only with the local list, the global list - is created correctly in this case - */ - lex->current_select->table_list.save_and_clear(&lex->save_list); - mysql_init_select(lex); - lex->current_select->parsing_place= SELECT_LIST; - } - select_options select_item_list - { - Select->parsing_place= NO_MATTER; - } - ; - -create_select_part3: - opt_table_expression - | create_select_part3_union_not_ready - ; - -create_select_part3_union_not_ready: - table_expression order_or_limit - | order_or_limit - ; - -create_select_part4: - opt_select_lock_type - { - /* - The following work only with the local list, the global list - is created correctly in this case - */ - Lex->current_select->table_list.push_front(&Lex->save_list); - } - ; - opt_as: /* empty */ {} | AS {} @@ -5812,7 +5992,7 @@ create_table_option: } | UNION_SYM opt_equal { - Lex->select_lex.table_list.save_and_clear(&Lex->save_list); + Lex->builtin_select.table_list.save_and_clear(&Lex->save_list); } '(' opt_table_list ')' { @@ -5821,8 +6001,8 @@ create_table_option: from the global list. */ LEX *lex=Lex; - lex->create_info.merge_list= lex->select_lex.table_list; - lex->select_lex.table_list= lex->save_list; + lex->create_info.merge_list= lex->builtin_select.table_list; + lex->builtin_select.table_list= lex->save_list; /* When excluding union list from the global list we assume that elements of the former immediately follow elements which represent @@ -5998,6 +6178,13 @@ create_field_list: } ; +create_field_list_parens: + LEFT_PAREN_ALT field_list ')' + { + Lex->create_last_non_select_table= Lex->last_table(); + } + ; + field_list: field_list_item | field_list ',' field_list_item @@ -6261,6 +6448,8 @@ parse_vcol_expr: Prevent the end user from invoking this command. */ MYSQL_YYABORT_UNLESS(Lex->parse_vcol_expr); + if (Lex->main_select_push()) + MYSQL_YYABORT; } expr { @@ -6268,13 +6457,29 @@ parse_vcol_expr: if (!v) MYSQL_YYABORT; Lex->last_field->vcol_info= v; + Lex->pop_select(); //main select } ; parenthesized_expr: - subselect + remember_tok_start + query_expression { - $$= new (thd->mem_root) Item_singlerow_subselect(thd, $1); + 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) MYSQL_YYABORT; } @@ -7165,22 +7370,24 @@ alter: Lex->table_type= TABLE_TYPE_UNKNOWN; Lex->sql_command= SQLCOM_ALTER_TABLE; Lex->duplicates= DUP_ERROR; - Lex->select_lex.init_order(); + Lex->builtin_select.init_order(); Lex->create_info.init(); Lex->create_info.row_type= ROW_TYPE_NOT_USED; Lex->alter_info.reset(); Lex->no_write_to_binlog= 0; Lex->create_info.storage_media= HA_SM_DEFAULT; + if (Lex->main_select_push()) + MYSQL_YYABORT; DBUG_ASSERT(!Lex->m_sql_cmd); } alter_options TABLE_SYM table_ident opt_lock_wait_timeout { - if (!Lex->select_lex.add_table_to_list(thd, $5, NULL, + if (!Lex->builtin_select.add_table_to_list(thd, $5, NULL, TL_OPTION_UPDATING, TL_READ_NO_INSERT, MDL_SHARED_UPGRADABLE)) MYSQL_YYABORT; - Lex->select_lex.db= (Lex->select_lex.table_list.first)->db; + Lex->builtin_select.db= (Lex->builtin_select.table_list.first)->db; Lex->create_last_non_select_table= Lex->last_table(); } alter_commands @@ -7191,12 +7398,15 @@ alter: Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table(); if (Lex->m_sql_cmd == NULL) MYSQL_YYABORT; + Lex->pop_select(); //main select } } | ALTER DATABASE ident_or_empty { Lex->create_info.default_table_charset= NULL; Lex->create_info.used_fields= 0; + if (Lex->main_select_push()) + MYSQL_YYABORT; } create_database_options { @@ -7206,6 +7416,7 @@ alter: if (lex->name.str == NULL && lex->copy_db_to(&lex->name.str, &lex->name.length)) MYSQL_YYABORT; + Lex->pop_select(); //main select } | ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM { @@ -7221,6 +7432,8 @@ alter: if (lex->sphead) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE")); + if (Lex->main_select_push()) + MYSQL_YYABORT; lex->sp_chistics.init(); } sp_a_chistics @@ -7229,6 +7442,9 @@ alter: lex->sql_command= SQLCOM_ALTER_PROCEDURE; lex->spname= $3; + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; } | ALTER FUNCTION_SYM sp_name { @@ -7236,6 +7452,8 @@ alter: if (lex->sphead) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION")); + if (Lex->main_select_push()) + MYSQL_YYABORT; lex->sp_chistics.init(); } sp_a_chistics @@ -7244,14 +7462,23 @@ alter: lex->sql_command= SQLCOM_ALTER_FUNCTION; lex->spname= $3; + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; } | ALTER view_algorithm definer_opt opt_view_suid VIEW_SYM table_ident { + if (Lex->main_select_push()) + MYSQL_YYABORT; if (Lex->add_alter_view(thd, $2, $4, $6)) MYSQL_YYABORT; } view_list_opt AS view_select - {} + { + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; + } | ALTER definer_opt opt_view_suid VIEW_SYM table_ident /* We have two separate rules for ALTER VIEW rather that @@ -7259,14 +7486,22 @@ alter: with the ALTER EVENT below. */ { + if (Lex->main_select_push()) + MYSQL_YYABORT; if (Lex->add_alter_view(thd, VIEW_ALGORITHM_INHERIT, $3, $5)) MYSQL_YYABORT; } view_list_opt AS view_select - {} + { + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; + } | ALTER definer_opt remember_name EVENT_SYM sp_name { - /* + if (Lex->main_select_push()) + MYSQL_YYABORT; + /* It is safe to use Lex->spname because ALTER EVENT xxx RENATE TO yyy DO ALTER EVENT RENAME TO is not allowed. Lex->spname is used in the case of RENAME TO @@ -7298,6 +7533,8 @@ alter: */ Lex->sql_command= SQLCOM_ALTER_EVENT; Lex->stmt_definition_end= (char*)YYLIP->get_cpp_ptr(); + + Lex->pop_select(); //main select } | ALTER TABLESPACE alter_tablespace_info { @@ -7341,15 +7578,17 @@ alter: lex->create_info.init(); lex->no_write_to_binlog= 0; DBUG_ASSERT(!lex->m_sql_cmd); + if (Lex->main_select_push()) + MYSQL_YYABORT; } table_ident { LEX *lex= Lex; if (!(lex->create_info.seq_create_info= new (thd->mem_root) sequence_definition()) || - !lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_SEQUENCE, - TL_WRITE, MDL_EXCLUSIVE)) + !lex->builtin_select.add_table_to_list(thd, $5, NULL, + TL_OPTION_SEQUENCE, + TL_WRITE, MDL_EXCLUSIVE)) MYSQL_YYABORT; } sequence_defs @@ -7358,6 +7597,9 @@ alter: Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence(); if (Lex->m_sql_cmd == NULL) MYSQL_YYABORT; + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; } ; @@ -7508,18 +7750,18 @@ alter_commands: { LEX *lex= thd->lex; size_t dummy; - lex->select_lex.db=$6->db.str; - if (lex->select_lex.db == NULL && - lex->copy_db_to(&lex->select_lex.db, &dummy)) + lex->builtin_select.db=$6->db.str; + if (lex->builtin_select.db == NULL && + lex->copy_db_to(&lex->builtin_select.db, &dummy)) { MYSQL_YYABORT; } lex->name= $6->table; lex->alter_info.flags|= Alter_info::ALTER_EXCHANGE_PARTITION; - if (!lex->select_lex.add_table_to_list(thd, $6, NULL, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_NO_WRITE)) + if (!lex->builtin_select.add_table_to_list(thd, $6, NULL, + TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_NO_WRITE)) MYSQL_YYABORT; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) @@ -7770,9 +8012,9 @@ alter_list_item: { LEX *lex=Lex; size_t dummy; - lex->select_lex.db=$3->db.str; - if (lex->select_lex.db == NULL && - lex->copy_db_to(&lex->select_lex.db, &dummy)) + lex->builtin_select.db=$3->db.str; + if (lex->builtin_select.db == NULL && + lex->copy_db_to(&lex->builtin_select.db, &dummy)) { MYSQL_YYABORT; } @@ -8046,9 +8288,13 @@ 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: @@ -8074,6 +8320,8 @@ 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 { @@ -8082,6 +8330,7 @@ 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 } ; @@ -8110,6 +8359,8 @@ 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(); @@ -8124,6 +8375,7 @@ 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 } ; @@ -8240,6 +8492,8 @@ 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 { @@ -8250,6 +8504,7 @@ 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 } ; @@ -8287,6 +8542,8 @@ 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 { @@ -8295,6 +8552,7 @@ 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 } ; @@ -8308,9 +8566,13 @@ 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; @@ -8404,9 +8666,13 @@ 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: @@ -8449,8 +8715,8 @@ adm_partition: cache_keys_spec: { - Lex->select_lex.alloc_index_hints(thd); - Select->set_index_hint_type(INDEX_HINT_USE, + Lex->builtin_select.alloc_index_hints(thd); + Select->set_index_hint_type(INDEX_HINT_USE, INDEX_HINT_MASK_ALL); } cache_key_list_or_empty @@ -8471,194 +8737,327 @@ opt_ignore_leaves: Select : retrieve data from table */ - -select: - opt_with_clause select_init +select_new: + query_expression { - LEX *lex= Lex; - lex->sql_command= SQLCOM_SELECT; - lex->current_select->set_with_clause($1); - } - ; + Lex->selects_allow_into= TRUE; + Lex->selects_allow_procedure= TRUE; + Lex->set_main_unit($1); + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; -select_init: - SELECT_SYM select_options_and_item_list select_init3 - | '(' select_paren ')' - | '(' select_paren ')' union_list - | '(' select_paren ')' union_order_or_limit - ; -union_list_part2: - SELECT_SYM select_options_and_item_list select_init3_union_query_term - | '(' select_paren_union_query_term ')' - | '(' select_paren_union_query_term ')' union_list - | '(' select_paren_union_query_term ')' union_order_or_limit + SELECT_LEX *fake= Lex->unit.fake_select_lex; + if (fake) + { + fake->no_table_names_allowed= 1; + Lex->push_select(fake); + } + else + Lex->push_select(Lex->first_select_lex()); + Lex->sql_command= SQLCOM_SELECT; + } ; -select_paren: + +query_specification: + SELECT_SYM { - /* - In order to correctly parse UNION's global ORDER BY we need to - set braces before parsing the clause. - */ - Lex->current_select->set_braces(true); + SELECT_LEX *sel; + LEX *lex= Lex; + if (lex->current_select && + lex->current_select->parsing_place == BEFORE_OPT_FIELD_LIST) + lex->current_select->parsing_place= NO_MATTER; + if (!(sel= Lex->alloc_select(TRUE)) || + Lex->push_select(sel)) + MYSQL_YYABORT; + sel->init_select(); + sel->braces= FALSE; } - SELECT_SYM select_options_and_item_list select_part3 - opt_select_lock_type + select_options { - DBUG_ASSERT(Lex->current_select->braces); + Select->parsing_place= SELECT_LIST; } - | '(' select_paren ')' - ; - -select_paren_union_query_term: + select_item_list { - /* - In order to correctly parse UNION's global ORDER BY we need to - set braces before parsing the clause. - */ - Lex->current_select->set_braces(true); + Select->parsing_place= NO_MATTER; } - SELECT_SYM select_options_and_item_list select_part3_union_query_term - opt_select_lock_type + opt_into + opt_from_clause + opt_where_clause + opt_group_clause + opt_having_clause + opt_window_clause { - DBUG_ASSERT(Lex->current_select->braces); + $$= Lex->pop_select(); } - | '(' select_paren_union_query_term ')' ; -select_paren_view: - { - /* - In order to correctly parse UNION's global ORDER BY we need to - set braces before parsing the clause. - */ - Lex->current_select->set_braces(true); - } - SELECT_SYM select_options_and_item_list select_part3_view - opt_select_lock_type - { - DBUG_ASSERT(Lex->current_select->braces); - } - | '(' select_paren_view ')' +opt_from_clause: + /* Empty */ + | from_clause ; -/* The equivalent of select_paren for nested queries. */ -select_paren_derived: + +query_primary: + query_specification + { $$= $1; } + | query_primary_parens + { $$= $1; } + ; + +query_primary_parens: + '(' query_expression_unit { - Lex->current_select->set_braces(true); + SELECT_LEX *last= $2->pre_last_parse->next_select(); + int cmp= cmp_unit_op($2->first_select()->next_select()->linkage, + last->linkage); + if (cmp < 0) + { + if (!check_intersect_prefix($2->first_select())) + { + if (Lex->pop_new_select_and_wrap() == NULL) + MYSQL_YYABORT; + } + } + Lex->push_select($2->fake_select_lex); } - SELECT_SYM select_part2_derived - opt_table_expression - opt_order_clause - opt_limit_clause - opt_select_lock_type + query_expression_tail ')' { - DBUG_ASSERT(Lex->current_select->braces); - $$= Lex->current_select->master_unit()->first_select(); + Lex->pop_select(); + if ($4) + { + ($4)->set_to($2->fake_select_lex); + } + $$= $2->first_select(); } - | '(' select_paren_derived ')' { $$= $2; } - ; - -select_init3: - opt_table_expression - opt_select_lock_type + | '(' query_primary { - /* Parentheses carry no meaning here */ - Lex->current_select->set_braces(false); + Lex->push_select($2); } - union_clause - | select_part3_union_not_ready - opt_select_lock_type + query_expression_tail ')' { - /* Parentheses carry no meaning here */ - Lex->current_select->set_braces(false); + Lex->pop_select(); + $$= $2; + $$->braces= TRUE; + if ($4) + { + if ($2->next_select()) + { + SELECT_LEX_UNIT *unit= $2->master_unit(); + if (!unit) + unit= Lex->create_unit($2); + if (!unit) + YYABORT; + if (!unit->fake_select_lex->is_set_query_expr_tail) + $4->set_to(unit->fake_select_lex); + else + { + $$= Lex->wrap_unit_into_derived(unit); + if (!$$) + YYABORT; + $4->set_to($$); + } + } + else if (!$2->is_set_query_expr_tail) + { + $4->set_to($2); + } + else + { + SELECT_LEX_UNIT *unit= Lex->create_unit($2); + if (!unit) + YYABORT; + $$= Lex->wrap_unit_into_derived(unit); + if (!$$) + YYABORT; + $4->set_to($$); + } + } } ; - -select_init3_union_query_term: - opt_table_expression - opt_select_lock_type +query_expression_unit: + query_primary + unit_type_decl + query_primary { - /* Parentheses carry no meaning here */ - Lex->current_select->set_braces(false); + SELECT_LEX *sel1; + SELECT_LEX *sel2; + if (!$1->next_select()) + sel1= $1; + else + { + sel1= Lex->wrap_unit_into_derived($1->master_unit()); + if (!sel1) + YYABORT; + } + if (!$3->next_select()) + sel2= $3; + else + { + sel2= Lex->wrap_unit_into_derived($3->master_unit()); + if (!sel2) + YYABORT; + } + sel1->link_neighbour(sel2); + sel2->set_linkage_and_distinct($2.unit_type, $2.distinct); + $$= Lex->create_unit(sel1); + $$->pre_last_parse= sel1; + if ($$ == NULL) + YYABORT; } - union_clause - | select_part3_union_not_ready_noproc - opt_select_lock_type + | query_expression_unit + unit_type_decl + query_primary { - /* Parentheses carry no meaning here */ - Lex->current_select->set_braces(false); + SELECT_LEX *sel1; + if (!$3->next_select()) + sel1= $3; + else + { + sel1= Lex->wrap_unit_into_derived($3->master_unit()); + if (!sel1) + YYABORT; + } + SELECT_LEX *last= $1->pre_last_parse->next_select(); + + int cmp= cmp_unit_op($2.unit_type, last->linkage); + if (cmp == 0) + { + // do nothing, this part will be just connected + } + else if (cmp > 0) + { + // Store beginning and continue to connect parts + if (Lex->push_new_select($1->pre_last_parse)) + MYSQL_YYABORT; + } + else /* cmp < 0 */ + { + // wrap stored part in a select, then continue to connect parts + if (!check_intersect_prefix($1->first_select())) + { + if ((last= Lex->pop_new_select_and_wrap()) == NULL) + MYSQL_YYABORT; + last->set_master_unit($1); + } + } + last->link_neighbour(sel1); + sel1->set_master_unit($1); + sel1->set_linkage_and_distinct($2.unit_type, $2.distinct); + $$= $1; + $$->pre_last_parse= last; } ; - -select_init3_view: - opt_table_expression opt_select_lock_type +query_expression_body: + query_primary { - Lex->current_select->set_braces(false); + Lex->push_select($1); } - | opt_table_expression opt_select_lock_type + query_expression_tail { - Lex->current_select->set_braces(false); + Lex->pop_select(); + SELECT_LEX *sel= $1; + if ($3) + { + if ($1->next_select()) + { + SELECT_LEX_UNIT *unit= $1->master_unit(); + if (!unit) + unit= Lex->create_unit($1); + if (!unit) + YYABORT; + if (!unit->fake_select_lex->is_set_query_expr_tail) + $3->set_to(unit->fake_select_lex); + else + { + SELECT_LEX *sel= Lex->wrap_unit_into_derived(unit); + if (!sel) + YYABORT; + $3->set_to(sel); + } + } + else if (!$1->is_set_query_expr_tail) + $3->set_to($1); + else + { + SELECT_LEX_UNIT *unit= $1->master_unit(); + if (!unit) + unit= Lex->create_unit($1); + if (!unit) + YYABORT; + sel= Lex->wrap_unit_into_derived(unit); + if (!sel) + YYABORT; + $3->set_to(sel); + } + } + $$= Lex->create_unit(sel); + if ($$ == NULL) + YYABORT; } - union_list_view - | order_or_limit opt_select_lock_type + | query_expression_unit { - Lex->current_select->set_braces(false); + SELECT_LEX *last= $1->pre_last_parse->next_select(); + int cmp= cmp_unit_op($1->first_select()->next_select()->linkage, + last->linkage); + if (cmp < 0) + { + if (!check_intersect_prefix($1->first_select())) + { + if (Lex->pop_new_select_and_wrap() == NULL) + MYSQL_YYABORT; + } + } + Lex->push_select($1->fake_select_lex); } - | table_expression order_or_limit opt_select_lock_type + query_expression_tail { - Lex->current_select->set_braces(false); + Lex->pop_select(); + if ($3) + { + ($3)->set_to($1->fake_select_lex); + } + $$= $1; } ; -/* - The SELECT parts after select_item_list that cannot be followed by UNION. -*/ - -select_part3: - opt_table_expression - | select_part3_union_not_ready - ; - -select_part3_union_query_term: - opt_table_expression - | select_part3_union_not_ready_noproc - ; - -select_part3_view: - opt_table_expression - | order_or_limit - | table_expression order_or_limit +query_expression: + opt_with_clause + query_expression_body + { + if ($1) + { + $2->set_with_clause($1); + $1->attach_to($2->first_select()); + } + $$= $2; + } ; -select_part3_union_not_ready: - select_part3_union_not_ready_noproc - | table_expression procedure_clause - | table_expression order_or_limit procedure_clause - ; +subselect: + 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; + } -select_part3_union_not_ready_noproc: - order_or_limit - | into opt_table_expression opt_order_clause opt_limit_clause - | table_expression into - | table_expression order_or_limit - | table_expression order_or_limit into - ; + // 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); + if (curr_sel) + { + curr_sel->register_unit($2, &curr_sel->context); + curr_sel->add_statistics($2); + } -select_options_and_item_list: - { - LEX *lex= Lex; - SELECT_LEX *sel= lex->current_select; - if (sel->linkage != UNION_TYPE) - mysql_init_select(lex); - lex->current_select->parsing_place= SELECT_LIST; - } - select_options select_item_list - { - Select->parsing_place= NO_MATTER; + $$= $2->first_select(); } ; @@ -8666,18 +9065,6 @@ select_options_and_item_list: /** <table expression>, as in the SQL standard. */ -table_expression: - from_clause - opt_where_clause - opt_group_clause - opt_having_clause - opt_window_clause - ; - -opt_table_expression: - /* Empty */ - | table_expression - ; from_clause: FROM table_reference_list @@ -8715,59 +9102,63 @@ select_option: query_expression_option | SQL_NO_CACHE_SYM { - /* - Allow this flag only on the first top-level SELECT statement, if - SQL_CACHE wasn't specified, and only once per query. - */ - if (Lex->current_select != &Lex->select_lex) - my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_NO_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE) - my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_CACHE", "SQL_NO_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE) + /* + Allow this flag once per query. + */ + if (Select->options & OPTION_NO_QUERY_CACHE) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_NO_CACHE")); - - Lex->safe_to_cache_query=0; - Lex->select_lex.options&= ~OPTION_TO_QUERY_CACHE; - Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE; + Select->options|= OPTION_NO_QUERY_CACHE; } | SQL_CACHE_SYM { - /* - Allow this flag only on the first top-level SELECT statement, if - SQL_NO_CACHE wasn't specified, and only once per query. - */ - if (Lex->current_select != &Lex->select_lex) - my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE) - my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_NO_CACHE", "SQL_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE) + /* + Allow this flag once per query. + */ + if (Select->options & OPTION_TO_QUERY_CACHE) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_CACHE")); - - Lex->safe_to_cache_query=1; - Lex->select_lex.options|= OPTION_TO_QUERY_CACHE; - Lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE; + Select->options|= OPTION_TO_QUERY_CACHE; } ; opt_select_lock_type: /* empty */ - | FOR_SYM UPDATE_SYM opt_lock_wait_timeout + { $$.empty(); } + | select_lock_type + { $$= $1; } + ; + +select_lock_type: + FOR_SYM UPDATE_SYM opt_lock_wait_timeout_new { - LEX *lex=Lex; - lex->current_select->lock_type= TL_WRITE; - lex->current_select->set_lock_for_tables(TL_WRITE); - lex->safe_to_cache_query=0; + $$= $3; + $$.defined_lock= TRUE; + $$.update_lock= TRUE; } - | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM opt_lock_wait_timeout + | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM opt_lock_wait_timeout_new { - LEX *lex=Lex; - lex->current_select->lock_type= TL_READ_WITH_SHARED_LOCKS; - lex->current_select-> - set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS); - lex->safe_to_cache_query=0; + $$= $5; + $$.defined_lock= TRUE; + $$.update_lock= FALSE; } ; +opt_lock_wait_timeout_new: + /* empty */ + { + $$.empty(); + } + | WAIT_SYM ulong_num + { + $$.defined_timeout= TRUE; + $$.timeout= $2; + } + | NOWAIT_SYM + { + $$.defined_timeout= TRUE; + $$.timeout= 0; + } + ; + select_item_list: select_item_list ',' select_item | select_item @@ -10934,10 +11325,15 @@ esc_table_ref: /* Equivalent to <table reference list> in the SQL:2003 standard. */ /* Warning - may return NULL in case of incomplete SELECT */ derived_table_list: - esc_table_ref { $$=$1; } + esc_table_ref + { + $$=$1; + Select->add_joined_table($1); + } | derived_table_list ',' esc_table_ref { MYSQL_YYABORT_UNLESS($1 && ($$=$3)); + Select->add_joined_table($3); } ; @@ -10956,11 +11352,18 @@ join_table: left-associative joins. */ table_ref normal_join table_ref %prec TABLE_REF_PRIORITY - { MYSQL_YYABORT_UNLESS($1 && ($$=$3)); $3->straight=$2; } + { + MYSQL_YYABORT_UNLESS($1 && ($$=$3)); + Select->add_joined_table($1); + Select->add_joined_table($3); + $3->straight=$2; + } | table_ref normal_join table_ref ON { MYSQL_YYABORT_UNLESS($1 && $3); + Select->add_joined_table($1); + Select->add_joined_table($3); /* Change the current name resolution context to a local context. */ if (push_new_name_resolution_context(thd, $1, $3)) MYSQL_YYABORT; @@ -10977,6 +11380,8 @@ join_table: USING { MYSQL_YYABORT_UNLESS($1 && $3); + Select->add_joined_table($1); + Select->add_joined_table($3); } '(' using_list ')' { @@ -10987,6 +11392,8 @@ join_table: | table_ref NATURAL inner_join table_factor { MYSQL_YYABORT_UNLESS($1 && ($$=$4)); + Select->add_joined_table($1); + Select->add_joined_table($4); $4->straight=$3; add_join_natural($1,$4,NULL,Select); } @@ -10996,6 +11403,8 @@ join_table: ON { MYSQL_YYABORT_UNLESS($1 && $5); + Select->add_joined_table($1); + Select->add_joined_table($5); /* Change the current name resolution context to a local context. */ if (push_new_name_resolution_context(thd, $1, $5)) MYSQL_YYABORT; @@ -11012,6 +11421,8 @@ join_table: | table_ref LEFT opt_outer JOIN_SYM table_factor { MYSQL_YYABORT_UNLESS($1 && $5); + Select->add_joined_table($1); + Select->add_joined_table($5); } USING '(' using_list ')' { @@ -11022,6 +11433,8 @@ join_table: | table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor { MYSQL_YYABORT_UNLESS($1 && $6); + Select->add_joined_table($1); + Select->add_joined_table($6); add_join_natural($1,$6,NULL,Select); $6->outer_join|=JOIN_TYPE_LEFT; $$=$6; @@ -11032,6 +11445,8 @@ join_table: ON { MYSQL_YYABORT_UNLESS($1 && $5); + Select->add_joined_table($1); + Select->add_joined_table($5); /* Change the current name resolution context to a local context. */ if (push_new_name_resolution_context(thd, $1, $5)) MYSQL_YYABORT; @@ -11049,6 +11464,8 @@ join_table: | table_ref RIGHT opt_outer JOIN_SYM table_factor { MYSQL_YYABORT_UNLESS($1 && $5); + Select->add_joined_table($1); + Select->add_joined_table($5); } USING '(' using_list ')' { @@ -11060,6 +11477,8 @@ join_table: | table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor { MYSQL_YYABORT_UNLESS($1 && $6); + Select->add_joined_table($1); + Select->add_joined_table($6); add_join_natural($6,$1,NULL,Select); LEX *lex= Lex; if (!($$= lex->current_select->convert_right_join())) @@ -11101,33 +11520,77 @@ use_partition: I.e. <table factor> ::= <table primary> [ <sample clause> ] -*/ +*/ + /* Warning - may return NULL in case of incomplete SELECT */ +/* table_factor: table_primary_ident | table_primary_derived ; +*/ +table_factor: + table_primary_ident { $$= $1; } + | table_primary_derived { $$= $1; } + | join_table_parens { $$= $1; } + | table_reference_list_parens { $$= $1; } + ; + +table_reference_list_parens: + '(' table_reference_list_parens ')' { $$= $2; } + | '(' nested_table_reference_list ')' + { + if (!($$= Select->end_nested_join(thd))) + MYSQL_YYABORT; + } + ; + +nested_table_reference_list: + table_ref ',' table_ref + { + if (Select->init_nested_join(thd)) + MYSQL_YYABORT; + Select->add_joined_table($1); + Select->add_joined_table($3); + $$= $1->embedding; + } + | nested_table_reference_list ',' table_ref + { + Select->add_joined_table($3); + $$= $1; + } + ; + +join_table_parens: + '(' join_table_parens ')' { $$= $2; } + | '(' join_table ')' + { + LEX *lex= Lex; + if (!($$= lex->current_select->nest_last_join(thd))) + { + thd->parse_error(); + MYSQL_YYABORT; + } + } + ; + table_primary_ident: + table_ident opt_use_partition opt_table_alias_clause opt_key_definition { SELECT_LEX *sel= Select; sel->table_join_options= 0; - } - table_ident opt_use_partition opt_table_alias opt_key_definition - { - if (!($$= Select->add_table_to_list(thd, $2, $4, + if (!($$= Select->add_table_to_list(thd, $1, $3, Select->get_table_join_options(), YYPS->m_lock_type, YYPS->m_mdl_type, Select->pop_index_hints(), - $3))) + $2))) MYSQL_YYABORT; - Select->add_joined_table($$); } ; - /* Represents a flattening of the following rules from the SQL:2003 standard. This sub-rule corresponds to the sub-rule @@ -11145,243 +11608,58 @@ table_primary_ident: */ table_primary_derived: - '(' get_select_lex select_derived_union ')' opt_table_alias + query_primary_parens table_alias_clause { - /* Use $2 instead of Lex->current_select as derived table will - alter value of Lex->current_select. */ - if (!($3 || $5) && $2->embedding && - !$2->embedding->nested_join->join_list.elements) + LEX *lex=Lex; + lex->derived_tables|= DERIVED_SUBQUERY; + $1->linkage= DERIVED_TABLE_TYPE; + $1->braces= FALSE; + // 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); + SELECT_LEX_UNIT *unit= $1->master_unit(); + if (!unit) { - /* we have a derived table ($3 == NULL) but no alias, - Since we are nested in further parentheses so we - can pass NULL to the outer level parentheses - Permits parsing of "((((select ...))) as xyz)" */ - $$= 0; + unit= Lex->create_unit($1); + if (!unit) + YYABORT; } - else if (!$3) - { - /* Handle case of derived table, alias may be NULL if there - are no outer parentheses, add_table_to_list() will throw - error in this case */ - LEX *lex=Lex; - lex->check_automatic_up(UNSPECIFIED_TYPE); - SELECT_LEX *sel= lex->current_select; - SELECT_LEX_UNIT *unit= sel->master_unit(); - lex->current_select= sel= unit->outer_select(); - Table_ident *ti= new (thd->mem_root) Table_ident(unit); - if (ti == NULL) - MYSQL_YYABORT; - if (!($$= sel->add_table_to_list(thd, - ti, $5, 0, - TL_READ, MDL_SHARED_READ))) + curr_sel->register_unit(unit, &curr_sel->context); + curr_sel->add_statistics(unit); - MYSQL_YYABORT; - sel->add_joined_table($$); - lex->pop_context(); - lex->nest_level--; - } - else if ($5 != NULL) - { - /* - Tables with or without joins within parentheses cannot - have aliases, and we ruled out derived tables above. - */ - thd->parse_error(); - MYSQL_YYABORT; - } - else - { - /* nested join: FROM (t1 JOIN t2 ...), - nest_level is the same as in the outer query */ - $$= $3; - } - /* - Fields in derived table can be used in upper select in - case of merge. We do not add HAVING fields because we do - not merge such derived. We do not add union because - also do not merge them - */ - if ($$ && $$->derived && - !$$->derived->first_select()->next_select()) - $$->select_lex->add_where_field($$->derived->first_select()); - } - /* Represents derived table with WITH clause */ - | '(' get_select_lex subselect_start - with_clause query_expression_body - subselect_end ')' opt_table_alias - { - LEX *lex=Lex; - SELECT_LEX *sel= $2; - SELECT_LEX_UNIT *unit= $5->master_unit(); Table_ident *ti= new (thd->mem_root) Table_ident(unit); if (ti == NULL) MYSQL_YYABORT; - $5->set_with_clause($4); - lex->current_select= sel; - if (!($$= sel->add_table_to_list(lex->thd, - ti, $8, 0, - TL_READ, MDL_SHARED_READ))) + if (!($$= curr_sel->add_table_to_list(lex->thd, + ti, $2, 0, + TL_READ, MDL_SHARED_READ))) MYSQL_YYABORT; - sel->add_joined_table($$); - } - ; - -/* - This rule accepts just about anything. The reason is that we have - empty-producing rules in the beginning of rules, in this case - subselect_start. This forces bison to take a decision which rules to - reduce by long before it has seen any tokens. This approach ties us - to a very limited class of parseable languages, and unfortunately - SQL is not one of them. The chosen 'solution' was this rule, which - produces just about anything, even complete bogus statements, for - instance ( table UNION SELECT 1 ). - Fortunately, we know that the semantic value returned by - select_derived is NULL if it contained a derived table, and a pointer to - the base table's TABLE_LIST if it was a base table. So in the rule - regarding union's, we throw a parse error manually and pretend it - was bison that did it. - - Also worth noting is that this rule concerns query expressions in - the from clause only. Top level select statements and other types of - subqueries have their own union rules. -*/ -select_derived_union: - select_derived - | select_derived union_order_or_limit - { - if ($1) - { - thd->parse_error(); - MYSQL_YYABORT; - } } - | select_derived union_head_non_top - { - if ($1) - { - thd->parse_error(); - MYSQL_YYABORT; - } - } - union_list_derived_part2 - | derived_query_specification opt_select_lock_type - | derived_query_specification order_or_limit opt_select_lock_type - | derived_query_specification opt_select_lock_type union_list_derived - ; - -union_list_derived_part2: - query_term_union_not_ready { Lex->pop_context(); } - | query_term_union_ready { Lex->pop_context(); } - | query_term_union_ready { Lex->pop_context(); } union_list_derived - ; - -union_list_derived: - union_head_non_top union_list_derived_part2 - ; - - -/* The equivalent of select_init2 for nested queries. */ -select_init2_derived: - select_part2_derived - { - Select->set_braces(0); - } - ; - -/* The equivalent of select_part2 for nested queries. */ -select_part2_derived: - { - LEX *lex= Lex; - SELECT_LEX *sel= lex->current_select; - if (sel->linkage != UNION_TYPE) - mysql_init_select(lex); - lex->current_select->parsing_place= SELECT_LIST; - } - opt_query_expression_options select_item_list - { - Select->parsing_place= NO_MATTER; - } - ; - -/* handle contents of parentheses in join expression */ -select_derived: - get_select_lex_derived derived_table_list + | '(' + query_expression + ')' table_alias_clause { - LEX *lex= Lex; - /* for normal joins, $2 != NULL and end_nested_join() != NULL, - for derived tables, both must equal NULL */ + LEX *lex=Lex; + lex->derived_tables|= DERIVED_SUBQUERY; + $2->first_select()->linkage= DERIVED_TABLE_TYPE; - if (!($$= $1->end_nested_join(lex->thd)) && $2) - MYSQL_YYABORT; - if (!$2 && $$) - { - thd->parse_error(); - MYSQL_YYABORT; - } - } - ; -/* - Similar to query_specification, but for derived tables. - Example: the inner parenthesized SELECT in this query: - SELECT * FROM (SELECT * FROM t1); -*/ -derived_query_specification: - SELECT_SYM select_derived_init select_derived2 - { - if ($2) - Select->set_braces(1); - $$= NULL; - } - ; + // 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); -select_derived2: - { - LEX *lex= Lex; - lex->derived_tables|= DERIVED_SUBQUERY; - if (!lex->expr_allows_subselect || - lex->sql_command == (int)SQLCOM_PURGE) - { - thd->parse_error(); + Table_ident *ti= new (thd->mem_root) Table_ident($2); + if (ti == NULL) MYSQL_YYABORT; - } - if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE || - mysql_new_select(lex, 1, NULL)) + if (!($$= curr_sel->add_table_to_list(lex->thd, + ti, $4, 0, + TL_READ, MDL_SHARED_READ))) MYSQL_YYABORT; - mysql_init_select(lex); - lex->current_select->linkage= DERIVED_TABLE_TYPE; - lex->current_select->parsing_place= SELECT_LIST; } - select_options select_item_list - { - Select->parsing_place= NO_MATTER; - } - opt_table_expression ; -get_select_lex: - /* Empty */ { $$= Select; } - ; - -get_select_lex_derived: - get_select_lex - { - LEX *lex= Lex; - if ($1->init_nested_join(lex->thd)) - MYSQL_YYABORT; - } - ; - -select_derived_init: - { - LEX *lex= Lex; - - TABLE_LIST *embedding= lex->current_select->embedding; - $$= embedding && - !embedding->nested_join->join_list.elements; - /* return true if we are deeply nested */ - } - ; opt_outer: /* empty */ {} @@ -11512,9 +11790,13 @@ table_alias: | '=' ; -opt_table_alias: +opt_table_alias_clause: /* empty */ { $$=0; } - | table_alias ident + | table_alias_clause { $$= $1; } + ; + +table_alias_clause: + table_alias ident { $$= (LEX_CSTRING*) thd->memdup(&$2,sizeof(LEX_STRING)); if ($$ == NULL) @@ -11681,7 +11963,7 @@ opt_window_partition_clause: opt_window_order_clause: /* empty */ { } - | ORDER_SYM BY order_list + | ORDER_SYM BY order_list { Select->order_list= *($3); } ; opt_window_frame_clause: @@ -11805,64 +12087,35 @@ alter_order_item: opt_order_clause: /* empty */ + { $$= NULL; } | order_clause + { $$= $1; } ; order_clause: - ORDER_SYM BY - { - LEX *lex=Lex; - SELECT_LEX *sel= lex->current_select; - SELECT_LEX_UNIT *unit= sel-> master_unit(); - if (sel->linkage != GLOBAL_OPTIONS_TYPE && - sel->olap != UNSPECIFIED_OLAP_TYPE && - (sel->linkage != UNION_TYPE || sel->braces)) - { - my_error(ER_WRONG_USAGE, MYF(0), - "CUBE/ROLLUP", "ORDER BY"); - MYSQL_YYABORT; - } - if (lex->sql_command != SQLCOM_ALTER_TABLE && - !unit->fake_select_lex) - { - /* - A query of the of the form (SELECT ...) ORDER BY order_list is - executed in the same way as the query - SELECT ... ORDER BY order_list - unless the SELECT construct contains ORDER BY or LIMIT clauses. - Otherwise we create a fake SELECT_LEX if it has not been created - yet. - */ - SELECT_LEX *first_sl= unit->first_select(); - if (!unit->is_unit_op() && - (first_sl->order_list.elements || - first_sl->select_limit) && - unit->add_fake_select_lex(thd)) - MYSQL_YYABORT; - } - if (sel->master_unit()->is_unit_op() && !sel->braces) - { - /* - At this point we don't know yet whether this is the last - select in union or not, but we move ORDER BY to - fake_select_lex anyway. If there would be one more select - in union mysql_new_select will correctly throw error. - */ - DBUG_ASSERT(sel->master_unit()->fake_select_lex); - lex->current_select= sel->master_unit()->fake_select_lex; - } + ORDER_SYM BY + { + thd->where= "ORDER clause"; } order_list { - + $$= $4; } ; order_list: order_list ',' order_ident order_dir - { if (add_order_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; } + { + $$= $1; + if (add_to_list(thd, *$$, $3,(bool) $4)) + MYSQL_YYABORT; + } | order_ident order_dir - { if (add_order_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; } + { + $$= new (thd->mem_root) SQL_I_List<ORDER>(); + if (add_to_list(thd, *$$, $1, (bool) $2)) + MYSQL_YYABORT; + } ; order_dir: @@ -11872,63 +12125,61 @@ order_dir: ; opt_limit_clause: - /* empty */ {} - | limit_clause {} + /* empty */ + { $$.empty(); } + | limit_clause + { $$= $1; } ; -limit_clause_init: - LIMIT - { - SELECT_LEX *sel= Select; - if (sel->master_unit()->is_unit_op() && !sel->braces) - { - /* Move LIMIT that belongs to UNION to fake_select_lex */ - Lex->current_select= sel->master_unit()->fake_select_lex; - DBUG_ASSERT(Select); - } - } - ; - limit_clause: - limit_clause_init limit_options + LIMIT limit_options { - SELECT_LEX *sel= Select; - if (!sel->select_limit->basic_const_item() || - sel->select_limit->val_int() > 0) + $$= $2; + if (!$$.select_limit->basic_const_item() || + $$.select_limit->val_int() > 0) Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT); } - | limit_clause_init limit_options + | LIMIT limit_options ROWS_SYM EXAMINED_SYM limit_rows_option { + $$= $2; Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT); } - | limit_clause_init ROWS_SYM EXAMINED_SYM limit_rows_option + | LIMIT ROWS_SYM EXAMINED_SYM limit_rows_option { + $$.select_limit= 0; + $$.offset_limit= 0; + $$.explicit_limit= 1; Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT); } ; +opt_global_limit_clause: + opt_limit_clause + { + Select->explicit_limit= $1.explicit_limit; + Select->select_limit= $1.select_limit; + Select->offset_limit= $1.offset_limit; + } + limit_options: limit_option { - SELECT_LEX *sel= Select; - sel->select_limit= $1; - sel->offset_limit= 0; - sel->explicit_limit= 1; + $$.select_limit= $1; + $$.offset_limit= 0; + $$.explicit_limit= 1; } | limit_option ',' limit_option { - SELECT_LEX *sel= Select; - sel->select_limit= $3; - sel->offset_limit= $1; - sel->explicit_limit= 1; + $$.select_limit= $3; + $$.offset_limit= $1; + $$.explicit_limit= 1; } | limit_option OFFSET_SYM limit_option { - SELECT_LEX *sel= Select; - sel->select_limit= $1; - sel->offset_limit= $3; - sel->explicit_limit= 1; + $$.select_limit= $1; + $$.offset_limit= $3; + $$.explicit_limit= 1; } ; @@ -12001,6 +12252,66 @@ delete_limit_clause: | LIMIT limit_option ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; } ; +query_expression_tail: + /* empty */ { $$= NULL; } + | order_or_limit opt_select_lock_type + { + $$= $1; + $$->lock= $2; + } + | order_or_limit procedure_or_into opt_select_lock_type + { + $$= $1; + $$->lock= $3; + } + | procedure_or_into opt_select_lock_type + { + $$= new(thd->mem_root) Lex_order_limit_lock; + if (!$$) + YYABORT; + $$->order_list= NULL; + $$->limit.empty(); + $$->lock= $2; + } + | select_lock_type + { + $$= new(thd->mem_root) Lex_order_limit_lock; + if (!$$) + YYABORT; + $$->order_list= NULL; + $$->limit.empty(); + $$->lock= $1; + } + ; + +procedure_or_into: + procedure_clause + | into + | procedure_clause into + ; + +order_or_limit: + order_clause opt_limit_clause + { + $$= new(thd->mem_root) Lex_order_limit_lock; + if (!$$) + YYABORT; + $$->order_list= $1; + $$->limit= $2; + } + | limit_clause + { + Lex_order_limit_lock *op= $$= new(thd->mem_root) Lex_order_limit_lock; + if (!$$) + YYABORT; + op->order_list= NULL; + op->limit= $1; + $$->order_list= NULL; + $$->limit= $1; + } + ; + + opt_plus: /* empty */ | '+' @@ -12070,13 +12381,12 @@ bool: | TRUE_SYM { $$= 1; } | FALSE_SYM { $$= 0; } - procedure_clause: PROCEDURE_SYM ident /* Procedure name */ { LEX *lex=Lex; - DBUG_ASSERT(&lex->select_lex == lex->current_select); + //DBUG_ASSERT(&lex->select_lex == lex->current_select); lex->proc_list.elements=0; lex->proc_list.first=0; @@ -12097,6 +12407,7 @@ procedure_clause: parameters are reduced. */ Lex->expr_allows_subselect= false; + Select->options|= OPTION_PROCEDURE_CLAUSE; } '(' procedure_list ')' { @@ -12183,8 +12494,21 @@ select_outvar: } ; +opt_into: + /* empty */ + | into + ; into: INTO into_destination + { + if (!(Select->options & OPTION_INTO_CLAUSE)) + Select->options|= OPTION_INTO_CLAUSE; + else + { + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "INTO"); + MYSQL_YYABORT; + } + } ; into_destination: @@ -12230,10 +12554,15 @@ 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; } ; @@ -12450,16 +12779,23 @@ insert: LEX *lex= Lex; lex->sql_command= SQLCOM_INSERT; lex->duplicates= DUP_ERROR; + if (Lex->main_select_push()) + MYSQL_YYABORT; mysql_init_select(lex); + lex->current_select->parsing_place= BEFORE_OPT_FIELD_LIST; } insert_lock_option opt_ignore insert2 { Select->set_lock_for_tables($3); - Lex->current_select= &Lex->select_lex; + Lex->current_select= Lex->first_select_lex(); } insert_field_spec opt_insert_update - {} + { + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; + } ; replace: @@ -12468,15 +12804,22 @@ replace: LEX *lex=Lex; lex->sql_command = SQLCOM_REPLACE; lex->duplicates= DUP_REPLACE; + if (Lex->main_select_push()) + MYSQL_YYABORT; mysql_init_select(lex); + lex->current_select->parsing_place= BEFORE_OPT_FIELD_LIST; } replace_lock_option insert2 { Select->set_lock_for_tables($3); - Lex->current_select= &Lex->select_lex; + Lex->current_select= Lex->first_select_lex(); } insert_field_spec - {} + { + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; + } ; insert_lock_option: @@ -12529,27 +12872,42 @@ insert_table: insert_field_spec: insert_values {} - | '(' ')' insert_values {} - | '(' fields ')' insert_values {} + | insert_field_list insert_values {} | SET { LEX *lex=Lex; if (!(lex->insert_list= new (thd->mem_root) List_item) || lex->many_values.push_back(lex->insert_list, thd->mem_root)) MYSQL_YYABORT; + lex->current_select->parsing_place= NO_MATTER; } ident_eq_list ; +insert_field_list: + LEFT_PAREN_ALT opt_fields ')' + ; + +opt_fields: + /* empty */ + | fields + ; + fields: fields ',' insert_ident { Lex->field_list.push_back($3, thd->mem_root); } | insert_ident { Lex->field_list.push_back($1, thd->mem_root); } ; + + insert_values: - VALUES values_list {} - | VALUE_SYM values_list {} + VALUES + { Lex->current_select->parsing_place= NO_MATTER; } + values_list {} + | VALUE_SYM + { Lex->current_select->parsing_place= NO_MATTER; } + values_list {} | create_select_query_expression {} ; @@ -12653,6 +13011,8 @@ update: UPDATE_SYM { LEX *lex= Lex; + if (Lex->main_select_push()) + MYSQL_YYABORT; mysql_init_select(lex); lex->sql_command= SQLCOM_UPDATE; lex->duplicates= DUP_ERROR; @@ -12661,13 +13021,13 @@ update: SET update_list { LEX *lex= Lex; - if (lex->select_lex.table_list.elements > 1) + if (lex->builtin_select.table_list.elements > 1) lex->sql_command= SQLCOM_UPDATE_MULTI; - else if (lex->select_lex.get_table_list()->derived) + else if (lex->builtin_select.get_table_list()->derived) { /* it is single table update and it is update of derived table */ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), - lex->select_lex.get_table_list()->alias, "UPDATE"); + lex->builtin_select.get_table_list()->alias, "UPDATE"); MYSQL_YYABORT; } /* @@ -12677,7 +13037,14 @@ update: */ Select->set_lock_for_tables($3); } - opt_where_clause opt_order_clause delete_limit_clause {} + opt_where_clause opt_order_clause delete_limit_clause + { + if ($10) + Select->order_list= *($10); + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; + } ; update_list: @@ -12723,9 +13090,11 @@ delete: mysql_init_select(lex); YYPS->m_lock_type= TL_WRITE_DEFAULT; YYPS->m_mdl_type= MDL_SHARED_WRITE; + if (Lex->main_select_push()) + MYSQL_YYABORT; lex->ignore= 0; - lex->select_lex.init_order(); + lex->builtin_select.init_order(); } opt_delete_options single_multi ; @@ -12744,9 +13113,16 @@ single_multi: } opt_where_clause opt_order_clause delete_limit_clause {} - opt_select_expressions {} + opt_select_expressions + { + if ($6) + Select->order_list= *($6); + Lex->pop_select(); //main select + } | table_wild_list { + if (Lex->main_select_push()) + MYSQL_YYABORT; mysql_init_multi_delete(Lex); YYPS->m_lock_type= TL_READ_DEFAULT; YYPS->m_mdl_type= MDL_SHARED_READ; @@ -12755,9 +13131,14 @@ single_multi: { if (multi_delete_set_locks_and_link_aux_tables(Lex)) MYSQL_YYABORT; + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; } | FROM table_alias_ref_list { + if (Lex->main_select_push()) + MYSQL_YYABORT; mysql_init_multi_delete(Lex); YYPS->m_lock_type= TL_READ_DEFAULT; YYPS->m_mdl_type= MDL_SHARED_READ; @@ -12766,6 +13147,9 @@ single_multi: { if (multi_delete_set_locks_and_link_aux_tables(Lex)) MYSQL_YYABORT; + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; } ; @@ -12829,10 +13213,12 @@ truncate: { LEX* lex= Lex; lex->sql_command= SQLCOM_TRUNCATE; + if (Lex->main_select_push()) + MYSQL_YYABORT; lex->alter_info.reset(); - lex->select_lex.options= 0; - lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED; - lex->select_lex.init_order(); + lex->builtin_select.options= 0; + lex->builtin_select.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED; + lex->builtin_select.init_order(); YYPS->m_lock_type= TL_WRITE; YYPS->m_mdl_type= MDL_EXCLUSIVE; } @@ -12843,6 +13229,7 @@ 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 } ; @@ -12917,6 +13304,8 @@ show: LEX *lex=Lex; lex->wild=0; lex->ident= null_clex_str; + if (Lex->main_select_push()) + MYSQL_YYABORT; mysql_init_select(lex); lex->current_select->parsing_place= SELECT_LIST; lex->create_info.init(); @@ -12924,6 +13313,7 @@ show: show_param { Select->parsing_place= NO_MATTER; + Lex->pop_select(); //main select } ; @@ -12939,7 +13329,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLES; - lex->select_lex.db= $3.str; + lex->builtin_select.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES)) MYSQL_YYABORT; } @@ -12947,7 +13337,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TRIGGERS; - lex->select_lex.db= $3.str; + lex->builtin_select.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS)) MYSQL_YYABORT; } @@ -12955,7 +13345,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_EVENTS; - lex->select_lex.db= $2.str; + lex->builtin_select.db= $2.str; if (prepare_schema_table(thd, lex, 0, SCH_EVENTS)) MYSQL_YYABORT; } @@ -12963,7 +13353,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLE_STATUS; - lex->select_lex.db= $3.str; + lex->builtin_select.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_TABLES)) MYSQL_YYABORT; } @@ -12971,7 +13361,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_OPEN_TABLES; - lex->select_lex.db= $3.str; + lex->builtin_select.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES)) MYSQL_YYABORT; } @@ -13021,12 +13411,13 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS; } - opt_limit_clause + opt_global_limit_clause | RELAYLOG_SYM optional_connection_name EVENTS_SYM binlog_in binlog_from { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_RELAYLOG_EVENTS; - } opt_limit_clause + } + opt_global_limit_clause | keys_or_index from_or_in table_ident opt_db opt_where_clause { LEX *lex= Lex; @@ -13068,13 +13459,17 @@ show_param: LEX_CSTRING var= {STRING_WITH_LEN("error_count")}; (void) create_select_for_variable(thd, &var); } - | WARNINGS opt_limit_clause - { Lex->sql_command = SQLCOM_SHOW_WARNS;} - | ERRORS opt_limit_clause - { Lex->sql_command = SQLCOM_SHOW_ERRORS;} + | WARNINGS opt_global_limit_clause + { + Lex->sql_command = SQLCOM_SHOW_WARNS; + } + | ERRORS opt_global_limit_clause + { + Lex->sql_command = SQLCOM_SHOW_ERRORS; + } | PROFILES_SYM { Lex->sql_command = SQLCOM_SHOW_PROFILES; } - | PROFILE_SYM opt_profile_defs opt_profile_args opt_limit_clause + | PROFILE_SYM opt_profile_defs opt_profile_args opt_global_limit_clause { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_PROFILE; @@ -13135,7 +13530,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL,0)) + if (!lex->builtin_select.add_table_to_list(thd, $3, NULL,0)) MYSQL_YYABORT; lex->create_info.storage_media= HA_SM_DEFAULT; } @@ -13143,7 +13538,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0)) + if (!lex->builtin_select.add_table_to_list(thd, $3, NULL, 0)) MYSQL_YYABORT; lex->table_type= TABLE_TYPE_VIEW; } @@ -13151,7 +13546,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0)) + if (!lex->builtin_select.add_table_to_list(thd, $3, NULL, 0)) MYSQL_YYABORT; lex->table_type= TABLE_TYPE_SEQUENCE; } @@ -13336,7 +13731,7 @@ describe: mysql_init_select(lex); lex->current_select->parsing_place= SELECT_LIST; lex->sql_command= SQLCOM_SHOW_FIELDS; - lex->select_lex.db= 0; + lex->builtin_select.db= 0; lex->verbose= 0; if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS)) MYSQL_YYABORT; @@ -13350,12 +13745,12 @@ describe: explainable_command { LEX *lex=Lex; - lex->select_lex.options|= SELECT_DESCRIBE; + lex->first_select_lex()->options|= SELECT_DESCRIBE; } ; explainable_command: - select + select_new | insert | replace | update @@ -13376,6 +13771,8 @@ analyze_stmt_command: opt_extended_describe: EXTENDED_SYM { Lex->describe|= DESCRIBE_EXTENDED; } + | EXTENDED_SYM ALL + { Lex->describe|= DESCRIBE_EXTENDED | DESCRIBE_EXTENDED2; } | PARTITIONS_SYM { Lex->describe|= DESCRIBE_PARTITIONS; } | opt_format_json {} ; @@ -13418,7 +13815,6 @@ flush: lex->no_write_to_binlog= $2; } flush_options - {} ; flush_options: @@ -13590,9 +13986,13 @@ 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: @@ -13610,6 +14010,8 @@ 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; } ; @@ -13619,6 +14021,8 @@ 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; @@ -13627,6 +14031,7 @@ kill: kill_type kill_option kill_expr { Lex->kill_signal= (killed_state) ($3 | $4); + Lex->pop_select(); //main select } ; @@ -13670,7 +14075,7 @@ use: { LEX *lex=Lex; lex->sql_command=SQLCOM_CHANGE_DB; - lex->select_lex.db= $2.str; + lex->builtin_select.db= $2.str; } ; @@ -13687,6 +14092,8 @@ load: $2 == FILETYPE_CSV ? "LOAD DATA" : "LOAD XML"); MYSQL_YYABORT; } + if (Lex->main_select_push()) + MYSQL_YYABORT; } load_data_lock opt_local INFILE TEXT_STRING_filesystem { @@ -13713,7 +14120,11 @@ load: opt_xml_rows_identified_by opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec opt_load_data_set_spec - {} + { + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; + } ; data_or_xml: @@ -14123,17 +14534,21 @@ opt_with_clause: with_clause: - WITH opt_recursive + WITH opt_recursive { + LEX *lex= Lex; With_clause *with_clause= new With_clause($2, Lex->curr_with_clause); if (with_clause == NULL) MYSQL_YYABORT; - Lex->derived_tables|= DERIVED_WITH; - Lex->curr_with_clause= with_clause; + lex->derived_tables|= DERIVED_WITH; + lex->curr_with_clause= with_clause; with_clause->add_to_list(Lex->with_clauses_list_last_next); + if (lex->current_select && + lex->current_select->parsing_place == BEFORE_OPT_FIELD_LIST) + lex->current_select->parsing_place= NO_MATTER; } - with_list + with_list { $$= Lex->curr_with_clause; Lex->curr_with_clause= Lex->curr_with_clause->pop(); @@ -14162,9 +14577,9 @@ with_list_element: MYSQL_YYABORT; Lex->with_column_list.empty(); } - AS '(' remember_name subselect remember_end ')' + AS '(' remember_name query_expression remember_end ')' { - With_element *elem= new With_element($1, *$2, $7->master_unit()); + With_element *elem= new With_element($1, *$2, $7); if (elem == NULL || Lex->curr_with_clause->add_with_element(elem)) MYSQL_YYABORT; if (elem->set_unparsed_spec(thd, $6+1, $8)) @@ -15021,14 +15436,22 @@ set: SET { LEX *lex=Lex; + if (lex->main_select_push()) + MYSQL_YYABORT; lex->set_stmt_init(); lex->var_list.empty(); sp_create_assignment_lex(thd, yychar == YYEMPTY); } start_option_value_list - {} + { + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; + } | SET STATEMENT_SYM { + if (Lex->main_select_push()) + MYSQL_YYABORT; Lex->set_stmt_init(); } set_stmt_option_value_following_option_type_list @@ -15038,6 +15461,9 @@ set: my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT")); lex->stmt_var_list= lex->var_list; lex->var_list.empty(); + Lex->pop_select(); //main select + if (Lex->check_main_unit_semantics()) + MYSQL_YYABORT; } FOR_SYM verb_clause {} @@ -15445,9 +15871,13 @@ 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: @@ -15478,7 +15908,7 @@ table_lock_list: ; table_lock: - table_ident opt_table_alias lock_option + table_ident opt_table_alias_clause lock_option { thr_lock_type lock_type= (thr_lock_type) $3; bool lock_for_write= (lock_type >= TL_WRITE_ALLOW_WRITE); @@ -15512,9 +15942,13 @@ 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 + } ; /* @@ -15522,25 +15956,36 @@ unlock: */ handler: - HANDLER_SYM table_ident OPEN_SYM opt_table_alias + HANDLER_SYM + { + if (Lex->main_select_push()) + MYSQL_YYABORT; + } + handler_tail + { + Lex->pop_select(); //main select + } + +handler_tail: + table_ident OPEN_SYM opt_table_alias_clause { LEX *lex= Lex; if (lex->sphead) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER")); lex->sql_command = SQLCOM_HA_OPEN; - if (!lex->current_select->add_table_to_list(thd, $2, $4, 0)) + if (!lex->current_select->add_table_to_list(thd, $1, $3, 0)) MYSQL_YYABORT; } - | HANDLER_SYM table_ident_nodb CLOSE_SYM + | table_ident_nodb CLOSE_SYM { LEX *lex= Lex; if (lex->sphead) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER")); lex->sql_command = SQLCOM_HA_CLOSE; - if (!lex->current_select->add_table_to_list(thd, $2, 0, 0)) + if (!lex->current_select->add_table_to_list(thd, $1, 0, 0)) MYSQL_YYABORT; } - | HANDLER_SYM table_ident_nodb READ_SYM + | table_ident_nodb READ_SYM { LEX *lex=Lex; if (lex->sphead) @@ -15548,20 +15993,24 @@ handler: lex->expr_allows_subselect= FALSE; lex->sql_command = SQLCOM_HA_READ; lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */ - Item *one= new (thd->mem_root) Item_int(thd, (int32) 1); - if (one == NULL) - MYSQL_YYABORT; - lex->current_select->select_limit= one; - lex->current_select->offset_limit= 0; - lex->limit_rows_examined= 0; - if (!lex->current_select->add_table_to_list(thd, $2, 0, 0)) + if (!lex->current_select->add_table_to_list(thd, $1, 0, 0)) MYSQL_YYABORT; } - handler_read_or_scan opt_where_clause opt_limit_clause + handler_read_or_scan opt_where_clause opt_global_limit_clause { - Lex->expr_allows_subselect= TRUE; + LEX *lex=Lex; + lex->expr_allows_subselect= TRUE; + if (!lex->current_select->explicit_limit) + { + Item *one= new (thd->mem_root) Item_int(thd, (int32) 1); + if (one == NULL) + MYSQL_YYABORT; + lex->current_select->select_limit= one; + lex->current_select->offset_limit= 0; + lex->limit_rows_examined= 0; + } /* Stored functions are not supported for HANDLER READ. */ - if (Lex->uses_stored_routines()) + if (lex->uses_stored_routines()) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), "stored functions in HANDLER ... READ"); @@ -16192,194 +16641,27 @@ release: */ unit_type_decl: - UNION_SYM - { $$= UNION_TYPE; } + UNION_SYM union_option + { $$.unit_type= UNION_TYPE; $$.distinct= $2; } | INTERSECT_SYM - { $$= INTERSECT_TYPE; } + { $$.unit_type= INTERSECT_TYPE; $$.distinct= 1; } | EXCEPT_SYM - { $$= EXCEPT_TYPE; } - - -union_clause: - /* empty */ {} - | union_list - ; - -union_list: - unit_type_decl union_option - { - if (Lex->add_select_to_union_list((bool)$2, $1, TRUE)) - MYSQL_YYABORT; - } - union_list_part2 - { - /* - Remove from the name resolution context stack the context of the - last select in the union. - */ - Lex->pop_context(); - } - ; - -union_list_view: - unit_type_decl union_option - { - if (Lex->add_select_to_union_list((bool)$2, $1, TRUE)) - MYSQL_YYABORT; - } - query_expression_body_view - { - Lex->pop_context(); - } - ; - -union_order_or_limit: - { - LEX *lex= thd->lex; - DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE); - SELECT_LEX *sel= lex->current_select; - SELECT_LEX_UNIT *unit= sel->master_unit(); - SELECT_LEX *fake= unit->fake_select_lex; - if (fake) - { - fake->no_table_names_allowed= 1; - lex->current_select= fake; - } - thd->where= "global ORDER clause"; - } - order_or_limit - { - thd->lex->current_select->no_table_names_allowed= 0; - thd->where= ""; - } - ; + { $$.unit_type= EXCEPT_TYPE; $$.distinct= 1; } -order_or_limit: - order_clause opt_limit_clause - | limit_clause - ; /* Start a UNION, for non-top level query expressions. */ -union_head_non_top: - unit_type_decl union_option - { - if (Lex->add_select_to_union_list((bool)$2, $1, FALSE)) - MYSQL_YYABORT; - } - ; - union_option: /* empty */ { $$=1; } | DISTINCT { $$=1; } | ALL { $$=0; } ; -/* - Corresponds to the SQL Standard - <query specification> ::= - SELECT [ <set quantifier> ] <select list> <table expression> - - Notes: - - We allow more options in addition to <set quantifier> - - <table expression> is optional in MariaDB -*/ -query_specification: - SELECT_SYM select_init2_derived opt_table_expression - { - $$= Lex->current_select->master_unit()->first_select(); - } - ; - -query_term_union_not_ready: - query_specification order_or_limit opt_select_lock_type { $$= $1; } - | '(' select_paren_derived ')' union_order_or_limit { $$= $2; } - ; - -query_term_union_ready: - query_specification opt_select_lock_type { $$= $1; } - | '(' select_paren_derived ')' { $$= $2; } - ; - -query_expression_body: - query_term_union_not_ready { $$= $1; } - | query_term_union_ready { $$= $1; } - | query_term_union_ready union_list_derived { $$= $1; } - ; - -/* Corresponds to <query expression> in the SQL:2003 standard. */ -subselect: - subselect_start opt_with_clause query_expression_body subselect_end - { - $3->set_with_clause($2); - $$= $3; - } - ; - -subselect_start: - { - LEX *lex=Lex; - if (!lex->expr_allows_subselect || - lex->sql_command == (int)SQLCOM_PURGE) - { - thd->parse_error(); - MYSQL_YYABORT; - } - /* - we are making a "derived table" for the parenthesis - as we need to have a lex level to fit the union - after the parenthesis, e.g. - (SELECT .. ) UNION ... becomes - SELECT * FROM ((SELECT ...) UNION ...) - */ - if (mysql_new_select(Lex, 1, NULL)) - MYSQL_YYABORT; - } - ; - -subselect_end: - { - LEX *lex=Lex; - - lex->check_automatic_up(UNSPECIFIED_TYPE); - lex->pop_context(); - SELECT_LEX *child= lex->current_select; - lex->current_select = lex->current_select->return_after_parsing(); - lex->nest_level--; - lex->current_select->n_child_sum_items += child->n_sum_items; - /* - A subselect can add fields to an outer select. Reserve space for - them. - */ - lex->current_select->select_n_where_fields+= - child->select_n_where_fields; - - /* - Aggregate functions in having clause may add fields to an outer - select. Count them also. - */ - lex->current_select->select_n_having_items+= - child->select_n_having_items; - } - ; - -opt_query_expression_options: - /* empty */ - | query_expression_option_list - ; - -query_expression_option_list: - query_expression_option_list query_expression_option - | query_expression_option - ; - query_expression_option: STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; } | HIGH_PRIORITY { - if (check_simple_select()) - MYSQL_YYABORT; YYPS->m_lock_type= TL_READ_HIGH_PRIORITY; YYPS->m_mdl_type= MDL_SHARED_READ; Select->options|= SELECT_HIGH_PRIORITY; @@ -16387,18 +16669,8 @@ query_expression_option: | DISTINCT { Select->options|= SELECT_DISTINCT; } | SQL_SMALL_RESULT { Select->options|= SELECT_SMALL_RESULT; } | SQL_BIG_RESULT { Select->options|= SELECT_BIG_RESULT; } - | SQL_BUFFER_RESULT - { - if (check_simple_select()) - MYSQL_YYABORT; - Select->options|= OPTION_BUFFER_RESULT; - } - | SQL_CALC_FOUND_ROWS - { - if (check_simple_select()) - MYSQL_YYABORT; - Select->options|= OPTION_FOUND_ROWS; - } + | SQL_BUFFER_RESULT { Select->options|= OPTION_BUFFER_RESULT; } + | SQL_CALC_FOUND_ROWS { Select->options|= OPTION_FOUND_ROWS; } | ALL { Select->options|= SELECT_ALL; } ; @@ -16486,20 +16758,25 @@ view_select: lex->parsing_options.allows_variable= FALSE; lex->create_view->select.str= (char *) YYLIP->get_cpp_ptr(); } - opt_with_clause query_expression_body_view view_check_option + query_expression + view_check_option { - LEX *lex= Lex; - uint len= YYLIP->get_cpp_ptr() - lex->create_view->select.str; - uint not_used; + LEX *lex= Lex; + SQL_I_List<TABLE_LIST> *save= &lex->first_select_lex()->table_list; + lex->set_main_unit($2); + if (lex->check_main_unit_semantics()) + MYSQL_YYABORT; + lex->first_select_lex()->table_list.push_front(save); + lex->current_select= Lex->first_select_lex(); + size_t len= YYLIP->get_cpp_ptr() - lex->create_view->select.str; void *create_view_select= thd->memdup(lex->create_view->select.str, len); lex->create_view->select.length= len; lex->create_view->select.str= (char *) create_view_select; + uint not_used; trim_whitespace(thd->charset(), - &lex->create_view->select, - ¬_used); - lex->create_view->check= $4; + &lex->create_view->select, ¬_used); + lex->create_view->check= $3; lex->parsing_options.allows_variable= TRUE; - lex->current_select->set_with_clause($2); } ; @@ -16507,13 +16784,6 @@ view_select: SQL Standard <query expression body> for VIEWs. Does not include INTO and PROCEDURE clauses. */ -query_expression_body_view: - SELECT_SYM select_options_and_item_list select_init3_view - | '(' select_paren_view ')' - | '(' select_paren_view ')' union_order_or_limit - | '(' select_paren_view ')' union_list_view - ; - view_check_option: /* empty */ { $$= VIEW_CHECK_NONE; } | WITH CHECK_SYM OPTION { $$= VIEW_CHECK_CASCADED; } @@ -16612,11 +16882,11 @@ trigger_tail: sp_proc_stmt alternatives are not saving/restoring LEX, so lex->query_tables can be wiped out. */ - if (!lex->select_lex.add_table_to_list(thd, $10, - (LEX_CSTRING*) 0, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_NO_WRITE)) + if (!lex->builtin_select.add_table_to_list(thd, $10, + (LEX_CSTRING*) 0, + TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_NO_WRITE)) MYSQL_YYABORT; } ; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index a430512f3a1..4404204b9af 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -1440,7 +1440,7 @@ query: END_OF_INPUT { if (!thd->bootstrap && - (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) + (!(thd->lex->builtin_select.options & OPTION_FOUND_COMMENT))) my_yyabort_error((ER_EMPTY_QUERY, MYF(0))); thd->lex->sql_command= SQLCOM_EMPTY_QUERY; @@ -1893,9 +1893,9 @@ create: lex->create_info.init(); if (lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2, $1 | $4)) MYSQL_YYABORT; - if (!lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - TL_WRITE, MDL_EXCLUSIVE)) + if (!lex->builtin_select.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + TL_WRITE, MDL_EXCLUSIVE)) MYSQL_YYABORT; lex->alter_info.reset(); /* @@ -1910,7 +1910,7 @@ create: create_body { LEX *lex= thd->lex; - lex->current_select= &lex->select_lex; + lex->current_select= &lex->builtin_select; if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) && !lex->create_info.db_type) { @@ -1930,9 +1930,9 @@ create: if (lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2, $1 | $4)) MYSQL_YYABORT; - if (!lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - TL_WRITE, MDL_EXCLUSIVE)) + if (!lex->builtin_select.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + TL_WRITE, MDL_EXCLUSIVE)) MYSQL_YYABORT; /* @@ -1955,8 +1955,8 @@ create: if (lex->create_info.seq_create_info->check_and_adjust(1)) { my_error(ER_SEQUENCE_INVALID_DATA, MYF(0), - lex->select_lex.table_list.first->db, - lex->select_lex.table_list.first->table_name); + lex->builtin_select.table_list.first->db, + lex->builtin_select.table_list.first->table_name); MYSQL_YYABORT; } @@ -1968,7 +1968,7 @@ create: Lex->create_info.used_fields|= HA_CREATE_USED_SEQUENCE; Lex->create_info.sequence= 1; - lex->current_select= &lex->select_lex; + lex->current_select= &lex->builtin_select; if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) && !lex->create_info.db_type) { @@ -2414,7 +2414,7 @@ clear_privileges: lex->columns.empty(); lex->grant= lex->grant_tot_col= 0; lex->all_privileges= 0; - lex->select_lex.db= 0; + lex->builtin_select.db= 0; lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0; bzero((char *)&(lex->mqh),sizeof(lex->mqh)); @@ -4680,7 +4680,7 @@ create_body: { Lex->create_info.add(DDL_options_st::OPT_LIKE); - TABLE_LIST *src_table= Lex->select_lex.add_table_to_list(thd, + TABLE_LIST *src_table= Lex->builtin_select.add_table_to_list(thd, $1, NULL, 0, TL_READ, MDL_SHARED_READ); if (! src_table) MYSQL_YYABORT; @@ -5683,7 +5683,7 @@ create_table_option: } | UNION_SYM opt_equal { - Lex->select_lex.table_list.save_and_clear(&Lex->save_list); + Lex->builtin_select.table_list.save_and_clear(&Lex->save_list); } '(' opt_table_list ')' { @@ -5692,8 +5692,8 @@ create_table_option: from the global list. */ LEX *lex=Lex; - lex->create_info.merge_list= lex->select_lex.table_list; - lex->select_lex.table_list= lex->save_list; + lex->create_info.merge_list= lex->builtin_select.table_list; + lex->builtin_select.table_list= lex->save_list; /* When excluding union list from the global list we assume that elements of the former immediately follow elements which represent @@ -7136,7 +7136,7 @@ alter: Lex->table_type= TABLE_TYPE_UNKNOWN; Lex->sql_command= SQLCOM_ALTER_TABLE; Lex->duplicates= DUP_ERROR; - Lex->select_lex.init_order(); + Lex->builtin_select.init_order(); Lex->create_info.init(); Lex->create_info.row_type= ROW_TYPE_NOT_USED; Lex->alter_info.reset(); @@ -7146,12 +7146,12 @@ alter: } alter_options TABLE_SYM table_ident opt_lock_wait_timeout { - if (!Lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_UPGRADABLE)) + if (!Lex->builtin_select.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_UPGRADABLE)) MYSQL_YYABORT; - Lex->select_lex.db= (Lex->select_lex.table_list.first)->db; + Lex->builtin_select.db= (Lex->builtin_select.table_list.first)->db; Lex->create_last_non_select_table= Lex->last_table(); } alter_commands @@ -7318,9 +7318,9 @@ alter: LEX *lex= Lex; if (!(lex->create_info.seq_create_info= new (thd->mem_root) sequence_definition()) || - !lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_SEQUENCE, - TL_WRITE, MDL_EXCLUSIVE)) + !lex->builtin_select.add_table_to_list(thd, $5, NULL, + TL_OPTION_SEQUENCE, + TL_WRITE, MDL_EXCLUSIVE)) MYSQL_YYABORT; } sequence_defs @@ -7479,18 +7479,18 @@ alter_commands: { LEX *lex= thd->lex; size_t dummy; - lex->select_lex.db=$6->db.str; - if (lex->select_lex.db == NULL && - lex->copy_db_to(&lex->select_lex.db, &dummy)) + lex->builtin_select.db=$6->db.str; + if (lex->builtin_select.db == NULL && + lex->copy_db_to(&lex->builtin_select.db, &dummy)) { MYSQL_YYABORT; } lex->name= $6->table; lex->alter_info.flags|= Alter_info::ALTER_EXCHANGE_PARTITION; - if (!lex->select_lex.add_table_to_list(thd, $6, NULL, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_NO_WRITE)) + if (!lex->builtin_select.add_table_to_list(thd, $6, NULL, + TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_NO_WRITE)) MYSQL_YYABORT; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) @@ -7741,9 +7741,9 @@ alter_list_item: { LEX *lex=Lex; size_t dummy; - lex->select_lex.db=$3->db.str; - if (lex->select_lex.db == NULL && - lex->copy_db_to(&lex->select_lex.db, &dummy)) + lex->builtin_select.db=$3->db.str; + if (lex->builtin_select.db == NULL && + lex->copy_db_to(&lex->builtin_select.db, &dummy)) { MYSQL_YYABORT; } @@ -8420,8 +8420,8 @@ adm_partition: cache_keys_spec: { - Lex->select_lex.alloc_index_hints(thd); - Select->set_index_hint_type(INDEX_HINT_USE, + Lex->builtin_select.alloc_index_hints(thd); + Select->set_index_hint_type(INDEX_HINT_USE, INDEX_HINT_MASK_ALL); } cache_key_list_or_empty @@ -8690,16 +8690,16 @@ select_option: Allow this flag only on the first top-level SELECT statement, if SQL_CACHE wasn't specified, and only once per query. */ - if (Lex->current_select != &Lex->select_lex) + if (Lex->current_select != &Lex->builtin_select) my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_NO_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE) + if (Lex->builtin_select.sql_cache == SELECT_LEX::SQL_CACHE) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_CACHE", "SQL_NO_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE) + if (Lex->builtin_select.sql_cache == SELECT_LEX::SQL_NO_CACHE) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_NO_CACHE")); Lex->safe_to_cache_query=0; - Lex->select_lex.options&= ~OPTION_TO_QUERY_CACHE; - Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE; + Lex->builtin_select.options&= ~OPTION_TO_QUERY_CACHE; + Lex->builtin_select.sql_cache= SELECT_LEX::SQL_NO_CACHE; } | SQL_CACHE_SYM { @@ -8707,16 +8707,16 @@ select_option: Allow this flag only on the first top-level SELECT statement, if SQL_NO_CACHE wasn't specified, and only once per query. */ - if (Lex->current_select != &Lex->select_lex) + if (Lex->current_select != &Lex->builtin_select) my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE) + if (Lex->builtin_select.sql_cache == SELECT_LEX::SQL_NO_CACHE) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_NO_CACHE", "SQL_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE) + if (Lex->builtin_select.sql_cache == SELECT_LEX::SQL_CACHE) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_CACHE")); Lex->safe_to_cache_query=1; - Lex->select_lex.options|= OPTION_TO_QUERY_CACHE; - Lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE; + Lex->builtin_select.options|= OPTION_TO_QUERY_CACHE; + Lex->builtin_select.sql_cache= SELECT_LEX::SQL_CACHE; } ; @@ -11223,7 +11223,7 @@ table_primary_derived: MYSQL_YYABORT; sel->add_joined_table($$); - lex->pop_context(); + //lex->pop_context("derived"); lex->nest_level--; } else if ($5 != NULL) @@ -11395,7 +11395,7 @@ select_derived2: mysql_new_select(lex, 1, NULL)) MYSQL_YYABORT; mysql_init_select(lex); - lex->current_select->linkage= DERIVED_TABLE_TYPE; + lex->current_select->set_linkage(DERIVED_TABLE_TYPE); lex->current_select->parsing_place= SELECT_LIST; } select_options select_item_list @@ -12122,7 +12122,7 @@ procedure_clause: { LEX *lex=Lex; - DBUG_ASSERT(&lex->select_lex == lex->current_select); + DBUG_ASSERT(&lex->builtin_select == lex->current_select); lex->proc_list.elements=0; lex->proc_list.first=0; @@ -12502,7 +12502,7 @@ insert: opt_ignore insert2 { Select->set_lock_for_tables($3); - Lex->current_select= &Lex->select_lex; + Lex->current_select= &Lex->builtin_select; } insert_field_spec opt_insert_update {} @@ -12519,7 +12519,7 @@ replace: replace_lock_option insert2 { Select->set_lock_for_tables($3); - Lex->current_select= &Lex->select_lex; + Lex->current_select= &Lex->builtin_select; } insert_field_spec {} @@ -12707,13 +12707,13 @@ update: SET update_list { LEX *lex= Lex; - if (lex->select_lex.table_list.elements > 1) + if (lex->builtin_select.table_list.elements > 1) lex->sql_command= SQLCOM_UPDATE_MULTI; - else if (lex->select_lex.get_table_list()->derived) + else if (lex->builtin_select.get_table_list()->derived) { /* it is single table update and it is update of derived table */ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), - lex->select_lex.get_table_list()->alias, "UPDATE"); + lex->builtin_select.get_table_list()->alias, "UPDATE"); MYSQL_YYABORT; } /* @@ -12771,7 +12771,7 @@ delete: YYPS->m_mdl_type= MDL_SHARED_WRITE; lex->ignore= 0; - lex->select_lex.init_order(); + lex->builtin_select.init_order(); } opt_delete_options single_multi ; @@ -12876,9 +12876,9 @@ truncate: LEX* lex= Lex; lex->sql_command= SQLCOM_TRUNCATE; lex->alter_info.reset(); - lex->select_lex.options= 0; - lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED; - lex->select_lex.init_order(); + lex->builtin_select.options= 0; + lex->builtin_select.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED; + lex->builtin_select.init_order(); YYPS->m_lock_type= TL_WRITE; YYPS->m_mdl_type= MDL_EXCLUSIVE; } @@ -12992,7 +12992,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLES; - lex->select_lex.db= $3.str; + lex->builtin_select.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES)) MYSQL_YYABORT; } @@ -13000,7 +13000,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TRIGGERS; - lex->select_lex.db= $3.str; + lex->builtin_select.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS)) MYSQL_YYABORT; } @@ -13008,7 +13008,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_EVENTS; - lex->select_lex.db= $2.str; + lex->builtin_select.db= $2.str; if (prepare_schema_table(thd, lex, 0, SCH_EVENTS)) MYSQL_YYABORT; } @@ -13016,7 +13016,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLE_STATUS; - lex->select_lex.db= $3.str; + lex->builtin_select.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_TABLES)) MYSQL_YYABORT; } @@ -13024,7 +13024,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_OPEN_TABLES; - lex->select_lex.db= $3.str; + lex->builtin_select.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES)) MYSQL_YYABORT; } @@ -13188,7 +13188,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL,0)) + if (!lex->builtin_select.add_table_to_list(thd, $3, NULL,0)) MYSQL_YYABORT; lex->create_info.storage_media= HA_SM_DEFAULT; } @@ -13196,7 +13196,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0)) + if (!lex->builtin_select.add_table_to_list(thd, $3, NULL, 0)) MYSQL_YYABORT; lex->table_type= TABLE_TYPE_VIEW; } @@ -13204,7 +13204,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0)) + if (!lex->builtin_select.add_table_to_list(thd, $3, NULL, 0)) MYSQL_YYABORT; lex->table_type= TABLE_TYPE_SEQUENCE; } @@ -13389,7 +13389,7 @@ describe: mysql_init_select(lex); lex->current_select->parsing_place= SELECT_LIST; lex->sql_command= SQLCOM_SHOW_FIELDS; - lex->select_lex.db= 0; + lex->builtin_select.db= 0; lex->verbose= 0; if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS)) MYSQL_YYABORT; @@ -13403,7 +13403,7 @@ describe: explainable_command { LEX *lex=Lex; - lex->select_lex.options|= SELECT_DESCRIBE; + lex->builtin_select.options|= SELECT_DESCRIBE; } ; @@ -13723,7 +13723,7 @@ use: { LEX *lex=Lex; lex->sql_command=SQLCOM_CHANGE_DB; - lex->select_lex.db= $2.str; + lex->builtin_select.db= $2.str; } ; @@ -16818,11 +16818,11 @@ trigger_tail: sp_proc_stmt alternatives are not saving/restoring LEX, so lex->query_tables can be wiped out. */ - if (!lex->select_lex.add_table_to_list(thd, $10, - (LEX_CSTRING*) 0, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_NO_WRITE)) + if (!lex->builtin_select.add_table_to_list(thd, $10, + (LEX_CSTRING*) 0, + TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_NO_WRITE)) MYSQL_YYABORT; } ; diff --git a/sql/structs.h b/sql/structs.h index 793be462b26..1d9bedd80c9 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -728,5 +728,58 @@ struct Lex_string_with_pos_st: public LEX_CSTRING const char *m_pos; }; +class Lex_select_lock +{ +public: + struct + { + uint defined_lock:1; + uint update_lock:1; + uint defined_timeout:1; + }; + ulong timeout; + + + void empty() + { + defined_lock= update_lock= defined_timeout= FALSE; + timeout= 0; + } +}; + +class Lex_select_limit +{ +public: + bool explicit_limit; + Item *select_limit, *offset_limit; + + void empty() + { + explicit_limit= FALSE; + select_limit= offset_limit= NULL; + } +}; + +struct st_order; +class st_select_lex; + +/** + ORDER BY ... LIMIT parameters; +*/ +class Lex_order_limit_lock +{ +public: + SQL_I_List<st_order> *order_list; /* ORDER clause */ + Lex_select_lock lock; + Lex_select_limit limit; + + static void *operator new(size_t size, MEM_ROOT *mem_root) throw () + { return alloc_root(mem_root, size); } + Lex_order_limit_lock() :order_list(NULL) + {} + + bool set_to(st_select_lex *sel); +}; + #endif /* STRUCTS_INCLUDED */ diff --git a/sql/table.cc b/sql/table.cc index 7dd93d5107d..9e6ede0dd3f 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2594,7 +2594,7 @@ static bool sql_unusable_for_discovery(THD *thd, handlerton *engine, if (lex->create_info.like()) return 1; // ... create select - if (lex->select_lex.item_list.elements) + if (lex->first_select_lex()->item_list.elements) return 1; // ... temporary if (create_info->tmp_table()) @@ -4813,13 +4813,13 @@ bool TABLE_LIST::single_table_updatable() { if (!updatable) return false; - if (view && view->select_lex.table_list.elements == 1) + if (view && view->first_select_lex()->table_list.elements == 1) { /* We need to check deeply only single table views. Multi-table views will be turned to multi-table updates and then checked by leaf tables */ - return (((TABLE_LIST *)view->select_lex.table_list.first)-> + return (((TABLE_LIST *)view->first_select_lex()->table_list.first)-> single_table_updatable()); } return true; @@ -4856,7 +4856,8 @@ merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded) cond= table->on_expr->copy_andor_structure(thd); if (!table->view) DBUG_RETURN(cond); - for (TABLE_LIST *tbl= (TABLE_LIST*)table->view->select_lex.table_list.first; + for (TABLE_LIST *tbl= + (TABLE_LIST*)table->view->first_select_lex()->table_list.first; tbl; tbl= tbl->next_local) { @@ -4898,7 +4899,7 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type) { DBUG_ENTER("TABLE_LIST::prep_check_option"); bool is_cascaded= check_opt_type == VIEW_CHECK_CASCADED; - TABLE_LIST *merge_underlying_list= view->select_lex.get_table_list(); + TABLE_LIST *merge_underlying_list= view->first_select_lex()->get_table_list(); for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local) { /* see comment of check_opt_type parameter */ @@ -5020,7 +5021,7 @@ TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find) if (!view) return 0; - for (TABLE_LIST *tbl= view->select_lex.get_table_list(); + for (TABLE_LIST *tbl= view->first_select_lex()->get_table_list(); tbl; tbl= tbl->next_local) { @@ -5192,7 +5193,8 @@ bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root) { DBUG_PRINT("info", ("setting insert_value for view")); DBUG_ASSERT(is_view_or_derived() && is_merged_derived()); - for (TABLE_LIST *tbl= (TABLE_LIST*)view->select_lex.table_list.first; + for (TABLE_LIST *tbl= + (TABLE_LIST*)view->first_select_lex()->table_list.first; tbl; tbl= tbl->next_local) if (tbl->set_insert_values(mem_root)) @@ -5359,7 +5361,7 @@ void TABLE_LIST::register_want_access(ulong want_access) } if (!view) return; - for (TABLE_LIST *tbl= view->select_lex.get_table_list(); + for (TABLE_LIST *tbl= view->first_select_lex()->get_table_list(); tbl; tbl= tbl->next_local) tbl->register_want_access(want_access); @@ -5551,6 +5553,7 @@ void TABLE_LIST::set_check_materialized() The subtree should be already excluded */ DBUG_ASSERT(!derived->first_select()->first_inner_unit() || + derived->first_select()->first_inner_unit()->with_element || derived->first_select()->first_inner_unit()->first_select()-> exclude_from_table_unique_test); } @@ -5567,14 +5570,14 @@ TABLE *TABLE_LIST::get_real_join_table() break; /* we do not support merging of union yet */ DBUG_ASSERT(tbl->view == NULL || - tbl->view->select_lex.next_select() == NULL); + tbl->view->first_select_lex()->next_select() == NULL); DBUG_ASSERT(tbl->derived == NULL || tbl->derived->first_select()->next_select() == NULL); { List_iterator_fast<TABLE_LIST> ti(tbl->view != NULL ? - tbl->view->select_lex.top_join_list : + tbl->view->first_select_lex()->top_join_list : tbl->derived->first_select()->top_join_list); for (;;) { @@ -5745,7 +5748,7 @@ Item *Field_iterator_view::create_item(THD *thd) Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref, LEX_CSTRING *name) { - bool save_wrapper= thd->lex->select_lex.no_wrap_view_item; + bool save_wrapper= thd->lex->first_select_lex()->no_wrap_view_item; Item *field= *field_ref; DBUG_ENTER("create_view_field"); @@ -5776,8 +5779,9 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref, { DBUG_RETURN(field); } - Name_resolution_context *context= view->view ? &view->view->select_lex.context : - &thd->lex->select_lex.context; + Name_resolution_context *context= (view->view ? + &view->view->first_select_lex()->context: + &thd->lex->first_select_lex()->context); Item *item= (new (thd->mem_root) Item_direct_view_ref(thd, context, field_ref, view->alias, name, view)); diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 63d153a7af4..68bd8f41796 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1319,7 +1319,7 @@ static int create_view_query(THD *thd, uchar** buf, size_t* buf_len) { LEX *lex= thd->lex; - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= lex->first_select_lex(); TABLE_LIST *first_table= select_lex->table_list.first; TABLE_LIST *views = first_table; LEX_USER *definer; @@ -1413,7 +1413,7 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, DBUG_ASSERT(table_list || db); LEX* lex= thd->lex; - SELECT_LEX* select_lex= &lex->select_lex; + SELECT_LEX* select_lex= lex->first_select_lex(); TABLE_LIST* first_table= select_lex->table_list.first; switch (lex->sql_command) diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index 963f657d735..9b1e5bce412 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -182,7 +182,7 @@ static mysql_mutex_t *mrn_LOCK_open; #if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P) # define MRN_LEX_GET_TABLE_LIST(lex) (lex)->select_lex->table_list.first #else -# define MRN_LEX_GET_TABLE_LIST(lex) (lex)->select_lex.table_list.first +# define MRN_LEX_GET_TABLE_LIST(lex) (lex)->first_select_lex()->table_list.first #endif #if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P) diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 4e2a41e9fa6..7d6d895b514 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -6438,7 +6438,7 @@ int spider_mysql_handler::append_select( if (result_list->lock_type != F_WRLCK && spider->lock_mode < 1) { /* no lock */ - st_select_lex *select_lex = &spider->trx->thd->lex->select_lex; + st_select_lex *select_lex = spider->trx->thd->lex->first_select_lex(); if ( select_lex->sql_cache == SELECT_LEX::SQL_CACHE && (spider->share->query_cache_sync & 1) diff --git a/storage/tokudb/tokudb_dir_cmd.cc b/storage/tokudb/tokudb_dir_cmd.cc index 5431cbab7aa..d0da92eab27 100644 --- a/storage/tokudb/tokudb_dir_cmd.cc +++ b/storage/tokudb/tokudb_dir_cmd.cc @@ -50,11 +50,11 @@ static int MDL_and_TDC(THD *thd, table_arg.str = const_cast<char *>(table); table_arg.length = strlen(table); Table_ident table_ident(thd, &db_arg, &table_arg, true);; - thd->lex->select_lex.add_table_to_list( + thd->lex->first_select_lex()->add_table_to_list( thd, &table_ident, NULL, 1, TL_UNLOCK, MDL_EXCLUSIVE, 0, 0, 0); /* The lock will be released at the end of mysq_execute_command() */ error = lock_table_names(thd, - thd->lex->select_lex.table_list.first, + thd->lex->first_select_lex()->table_list.first, NULL, thd->variables.lock_wait_timeout, 0);
participants (1)
-
Oleksandr Byelkin