summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhalfspawn <j.brauge@qualiac.com>2018-03-30 11:23:28 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2018-04-11 09:59:13 +0200
commit73f3842bf7cea9b9d56badaf2b400c513cf578cb (patch)
treea4befe1fba1e8de5d76c755077d992eaceb00ba3
parentdd127799bc179da10cc24c5d5cd105c9a5584730 (diff)
downloadmariadb-git-10.3-MDEV-11953.tar.gz
MDEV-15739 sql_mode=ORACLE: Make LPAD and RPAD return NULL instead of empty string10.3-MDEV-11953
-rw-r--r--mysql-test/include/deadlock.inc2
-rw-r--r--mysql-test/main/brackets.result184
-rw-r--r--mysql-test/main/brackets.test69
-rw-r--r--mysql-test/main/cte_nonrecursive.result40
-rw-r--r--mysql-test/main/deadlock_innodb.result2
-rw-r--r--mysql-test/main/derived_cond_pushdown.result6
-rw-r--r--mysql-test/main/except.result8
-rw-r--r--mysql-test/main/except.test4
-rw-r--r--mysql-test/main/fulltext_order_by.result4
-rw-r--r--mysql-test/main/func_analyse.result22
-rw-r--r--mysql-test/main/func_analyse.test17
-rw-r--r--mysql-test/main/intersect.result22
-rw-r--r--mysql-test/main/intersect.test4
-rw-r--r--mysql-test/main/join.result2
-rw-r--r--mysql-test/main/join_nested.result2
-rw-r--r--mysql-test/main/join_nested.test2
-rw-r--r--mysql-test/main/join_nested_jcl6.result2
-rw-r--r--mysql-test/main/parser.result55
-rw-r--r--mysql-test/main/parser.test55
-rw-r--r--mysql-test/main/query_cache.result26
-rw-r--r--mysql-test/main/query_cache.test27
-rw-r--r--mysql-test/main/show_check.result4
-rw-r--r--mysql-test/main/show_check.test2
-rw-r--r--mysql-test/main/sp-error.result10
-rw-r--r--mysql-test/main/sp-error.test10
-rw-r--r--mysql-test/main/sp.result2
-rw-r--r--mysql-test/main/sp.test2
-rw-r--r--mysql-test/main/subselect.result141
-rw-r--r--mysql-test/main/subselect.test94
-rw-r--r--mysql-test/main/subselect_mat.result4
-rw-r--r--mysql-test/main/subselect_no_exists_to_in.result141
-rw-r--r--mysql-test/main/subselect_no_mat.result141
-rw-r--r--mysql-test/main/subselect_no_opts.result141
-rw-r--r--mysql-test/main/subselect_no_scache.result141
-rw-r--r--mysql-test/main/subselect_no_semijoin.result141
-rw-r--r--mysql-test/main/subselect_sj.result2
-rw-r--r--mysql-test/main/subselect_sj.test2
-rw-r--r--mysql-test/main/subselect_sj_jcl6.result2
-rw-r--r--mysql-test/main/subselect_sj_mat.result4
-rw-r--r--mysql-test/main/subselect_sj_mat.test4
-rw-r--r--mysql-test/main/table_value_constr.result1
-rw-r--r--mysql-test/main/union.result21
-rw-r--r--mysql-test/main/union.test18
-rw-r--r--mysql-test/main/view.result56
-rw-r--r--mysql-test/main/view.test56
-rw-r--r--mysql-test/r/sp-error.result2876
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_views.result2
-rw-r--r--mysql-test/suite/funcs_1/r/memory_views.result2
-rw-r--r--mysql-test/suite/funcs_1/views/views_master.inc2
-rw-r--r--mysql-test/suite/innodb/r/innodb.result2
-rw-r--r--mysql-test/suite/innodb/t/innodb.test2
-rw-r--r--mysql-test/suite/innodb_fts/r/fulltext_order_by.result4
-rw-r--r--mysql-test/suite/versioning/r/select2.result2
-rw-r--r--sql/events.cc9
-rw-r--r--sql/item.cc8
-rw-r--r--sql/item_subselect.cc20
-rw-r--r--sql/log_event.cc7
-rw-r--r--sql/opt_range.cc2
-rw-r--r--sql/opt_table_elimination.cc4
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/sp_head.cc13
-rw-r--r--sql/sp_head.h5
-rw-r--r--sql/sp_rcontext.cc14
-rw-r--r--sql/sql_admin.cc18
-rw-r--r--sql/sql_alter.cc4
-rw-r--r--sql/sql_base.cc8
-rw-r--r--sql/sql_base.h6
-rw-r--r--sql/sql_cache.cc8
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_class.h8
-rw-r--r--sql/sql_cte.cc16
-rw-r--r--sql/sql_cte.h26
-rw-r--r--sql/sql_delete.cc32
-rw-r--r--sql/sql_derived.cc3
-rw-r--r--sql/sql_do.cc2
-rw-r--r--sql/sql_error.cc2
-rw-r--r--sql/sql_help.cc11
-rw-r--r--sql/sql_insert.cc40
-rw-r--r--sql/sql_lex.cc953
-rw-r--r--sql/sql_lex.h234
-rw-r--r--sql/sql_load.cc9
-rw-r--r--sql/sql_parse.cc109
-rw-r--r--sql/sql_partition.cc3
-rw-r--r--sql/sql_partition_admin.cc4
-rw-r--r--sql/sql_prepare.cc50
-rw-r--r--sql/sql_priv.h5
-rw-r--r--sql/sql_profile.cc4
-rw-r--r--sql/sql_select.cc50
-rw-r--r--sql/sql_sequence.cc4
-rw-r--r--sql/sql_show.cc28
-rw-r--r--sql/sql_table.cc6
-rw-r--r--sql/sql_truncate.cc2
-rw-r--r--sql/sql_union.cc2
-rw-r--r--sql/sql_update.cc30
-rw-r--r--sql/sql_view.cc49
-rw-r--r--sql/sql_yacc.yy2315
-rw-r--r--sql/sql_yacc_ora.yy2205
-rw-r--r--sql/structs.h53
-rw-r--r--sql/table.cc34
-rw-r--r--sql/wsrep_mysqld.cc4
-rw-r--r--storage/mroonga/ha_mroonga.cpp2
-rw-r--r--storage/spider/spd_db_mysql.cc2
-rw-r--r--storage/spider/spd_table.cc8
-rw-r--r--storage/tokudb/tokudb_dir_cmd.cc4
104 files changed, 7858 insertions, 3170 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/main/brackets.result b/mysql-test/main/brackets.result
new file mode 100644
index 00000000000..a943dafecf7
--- /dev/null
+++ b/mysql-test/main/brackets.result
@@ -0,0 +1,184 @@
+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/0 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#8/0 */ select `__8`.`1` AS `1` from (/* select#2/1 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#7/1 */ select `__7`.`1` AS `1` from (/* select#3/2 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#6/2 */ select `__6`.`1` AS `1` from (/* select#4/3 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#5/3 */ select 1 AS `1`) `__6`) `__7`) `__8`
+#
+# MDEV-6341: INSERT ... SELECT UNION with parenthesis
+#
+create table t1 (a int, b int);
+insert into t1 (select 1,1 union select 2,2);
+select * from t1 order by 1;
+a b
+1 1
+2 2
+delete from t1;
+insert into t1 select 1,1 union select 2,2;
+select * from t1 order by 1;
+a b
+1 1
+2 2
+drop table t1;
+CREATE OR REPLACE TABLE t1 AS SELECT 1 AS a UNION SELECT 2;
+select * from t1 order by 1;
+a
+1
+2
+drop table t1;
+CREATE OR REPLACE TABLE t1 AS (SELECT 1 AS a UNION SELECT 2);
+select * from t1 order by 1;
+a
+1
+2
+drop table t1;
+CREATE OR REPLACE VIEW v1 AS (SELECT 1 AS a);
+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 1 AS `a`) latin1 latin1_swedish_ci
+drop view v1;
+CREATE OR REPLACE VIEW v1 AS SELECT 1 AS a UNION SELECT 2;
+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 1 AS `a` union select 2 AS `2` latin1 latin1_swedish_ci
+drop view v1;
+CREATE OR REPLACE VIEW v1 AS (SELECT 1 AS a UNION SELECT 2);
+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 1 AS `a` union select 2 AS `2` latin1 latin1_swedish_ci
+drop view v1;
+#
+# MDEV-10028: Syntax error on ((SELECT ...) UNION (SELECT ...))
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (10);
+INSERT INTO t1 VALUES (20);
+INSERT INTO t1 VALUES (30);
+((SELECT a FROM t1) UNION (SELECT a FROM t1));
+a
+10
+20
+30
+(SELECT * FROM t1 UNION SELECT * FROM t1);
+a
+10
+20
+30
+((SELECT a FROM t1) LIMIT 1);
+a
+10
+SELECT * FROM (SELECT 1 UNION (SELECT 2 UNION SELECT 3)) t1;
+1
+1
+2
+3
+DROP TABLE t1;
+# End of 10.4 tests
diff --git a/mysql-test/main/brackets.test b/mysql-test/main/brackets.test
new file mode 100644
index 00000000000..d3477f501a1
--- /dev/null
+++ b/mysql-test/main/brackets.test
@@ -0,0 +1,69 @@
+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)));
+
+--echo #
+--echo # MDEV-6341: INSERT ... SELECT UNION with parenthesis
+--echo #
+create table t1 (a int, b int);
+insert into t1 (select 1,1 union select 2,2);
+select * from t1 order by 1;
+delete from t1;
+insert into t1 select 1,1 union select 2,2;
+select * from t1 order by 1;
+drop table t1;
+CREATE OR REPLACE TABLE t1 AS SELECT 1 AS a UNION SELECT 2;
+select * from t1 order by 1;
+drop table t1;
+CREATE OR REPLACE TABLE t1 AS (SELECT 1 AS a UNION SELECT 2);
+select * from t1 order by 1;
+drop table t1;
+CREATE OR REPLACE VIEW v1 AS (SELECT 1 AS a);
+show create view v1;
+drop view v1;
+CREATE OR REPLACE VIEW v1 AS SELECT 1 AS a UNION SELECT 2;
+show create view v1;
+drop view v1;
+CREATE OR REPLACE VIEW v1 AS (SELECT 1 AS a UNION SELECT 2);
+show create view v1;
+drop view v1;
+
+
+--echo #
+--echo # MDEV-10028: Syntax error on ((SELECT ...) UNION (SELECT ...))
+--echo #
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (10);
+INSERT INTO t1 VALUES (20);
+INSERT INTO t1 VALUES (30);
+
+((SELECT a FROM t1) UNION (SELECT a FROM t1));
+(SELECT * FROM t1 UNION SELECT * FROM t1);
+((SELECT a FROM t1) LIMIT 1);
+SELECT * FROM (SELECT 1 UNION (SELECT 2 UNION SELECT 3)) t1;
+DROP TABLE t1;
+
+--echo # End of 10.4 tests
diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result
index 534a386fe12..89ffd94f9f7 100644
--- a/mysql-test/main/cte_nonrecursive.result
+++ b/mysql-test/main/cte_nonrecursive.result
@@ -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
@@ -461,10 +461,10 @@ t.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 Using where
-1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY <subquery4> 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)
-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)
+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 t1.a,t1.b from t1, (select c from t2 where c >= 4) as t
where t1.a=t.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 DERIVED 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 DERIVED 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
@@ -1116,17 +1116,17 @@ select * from cte_e as cte_e1 where a > 1
union
select * from cte_e as cte_e2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 14 100.00 Using where
-2 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+1 PRIMARY <derived4> ALL NULL NULL NULL NULL 14 100.00 Using where
+4 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
5 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
-NULL UNION RESULT <union2,5> ALL NULL NULL NULL NULL NULL NULL
-6 UNION <derived9> ALL NULL NULL NULL NULL 14 100.00
-9 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL NULL
+6 UNION <derived11> ALL NULL NULL NULL NULL 14 100.00
+11 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
12 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
-NULL UNION RESULT <union9,12> ALL NULL NULL NULL NULL NULL NULL
+NULL UNION RESULT <union11,12> ALL NULL NULL NULL NULL NULL NULL
NULL UNION RESULT <union1,6> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 with cte_e as (with cte_o as (with cte_i as (/* select#4 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)/* select#3 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union /* select#5 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)/* select#1 */ select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union /* select#6 */ select `cte_e2`.`a` AS `a` from (with cte_o as (with cte_i as (/* select#11 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)/* select#10 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)/* select#9 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 union /* select#12 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7) `cte_e2`
+Note 1003 with cte_e as (with cte_o as (with cte_i as (select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union select `cte_e2`.`a` AS `a` from (with cte_o as (with cte_i as (select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 union select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7) `cte_e2`
drop table t1;
#
# MDEV-13753: embedded CTE in a VIEW created in prepared statement
diff --git a/mysql-test/main/deadlock_innodb.result b/mysql-test/main/deadlock_innodb.result
index af78a6aa9d5..fca0ff6be0c 100644
--- a/mysql-test/main/deadlock_innodb.result
+++ b/mysql-test/main/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/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result
index 5edd91faf16..e6984b13294 100644
--- a/mysql-test/main/derived_cond_pushdown.result
+++ b/mysql-test/main/derived_cond_pushdown.result
@@ -8935,7 +8935,7 @@ EXPLAIN
"access_type": "ALL",
"rows": 18,
"filtered": 100,
- "attached_condition": "__3.a > 5 and __3.c > 200",
+ "attached_condition": "__5.a > 5 and __5.c > 200",
"materialized": {
"query_block": {
"union_result": {
@@ -9561,7 +9561,7 @@ EXPLAIN
"access_type": "ALL",
"rows": 18,
"filtered": 100,
- "attached_condition": "__3.a > 4 and __3.c < 130",
+ "attached_condition": "__5.a > 4 and __5.c < 130",
"materialized": {
"query_block": {
"union_result": {
@@ -9707,7 +9707,7 @@ EXPLAIN
"access_type": "ALL",
"rows": 18,
"filtered": 100,
- "attached_condition": "__3.a > 4 and __3.c < 130",
+ "attached_condition": "__6.a > 4 and __6.c < 130",
"materialized": {
"query_block": {
"union_result": {
diff --git a/mysql-test/main/except.result b/mysql-test/main/except.result
index 594bb7118eb..23da19d46e3 100644
--- a/mysql-test/main/except.result
+++ b/mysql-test/main/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/main/except.test b/mysql-test/main/except.test
index f88d9b29e35..cd672ae6fbd 100644
--- a/mysql-test/main/except.test
+++ b/mysql-test/main/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/main/fulltext_order_by.result b/mysql-test/main/fulltext_order_by.result
index c2f57c6f9c2..a350a55c75d 100644
--- a/mysql-test/main/fulltext_order_by.result
+++ b/mysql-test/main/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/main/func_analyse.result b/mysql-test/main/func_analyse.result
index 1e78e603bca..68ceb8aed02 100644
--- a/mysql-test/main/func_analyse.result
+++ b/mysql-test/main/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/main/func_analyse.test b/mysql-test/main/func_analyse.test
index d99f5c0fa9a..24fdd9a10e2 100644
--- a/mysql-test/main/func_analyse.test
+++ b/mysql-test/main/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/main/intersect.result b/mysql-test/main/intersect.result
index b589e8bd17e..b74c7ecbe0c 100644
--- a/mysql-test/main/intersect.result
+++ b/mysql-test/main/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,7 +686,7 @@ 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/main/intersect.test b/mysql-test/main/intersect.test
index d9d420c786b..72e6c3d632f 100644
--- a/mysql-test/main/intersect.test
+++ b/mysql-test/main/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/main/join.result b/mysql-test/main/join.result
index 046674d5569..5978b261b3a 100644
--- a/mysql-test/main/join.result
+++ b/mysql-test/main/join.result
@@ -1484,7 +1484,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/main/join_nested.result b/mysql-test/main/join_nested.result
index 708c72fffb5..b6b4716d8b1 100644
--- a/mysql-test/main/join_nested.result
+++ b/mysql-test/main/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/main/join_nested.test b/mysql-test/main/join_nested.test
index e60b7827f75..77d0e4154c1 100644
--- a/mysql-test/main/join_nested.test
+++ b/mysql-test/main/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/main/join_nested_jcl6.result b/mysql-test/main/join_nested_jcl6.result
index eb59531b7d2..de5ebfbe989 100644
--- a/mysql-test/main/join_nested_jcl6.result
+++ b/mysql-test/main/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/main/parser.result b/mysql-test/main/parser.result
index a1c6e86a129..fd18b74be32 100644
--- a/mysql-test/main/parser.result
+++ b/mysql-test/main/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/main/parser.test b/mysql-test/main/parser.test
index 1f176c6afc5..e9c10159260 100644
--- a/mysql-test/main/parser.test
+++ b/mysql-test/main/parser.test
@@ -826,13 +826,16 @@ SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
--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;
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/main/query_cache.result b/mysql-test/main/query_cache.result
index 9c010cbffc7..fa198ee6e17 100644
--- a/mysql-test/main/query_cache.result
+++ b/mysql-test/main/query_cache.result
@@ -1858,17 +1858,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 +1878,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 +1902,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/main/query_cache.test b/mysql-test/main/query_cache.test
index 1b1e24bc6f4..389aa0de2fa 100644
--- a/mysql-test/main/query_cache.test
+++ b/mysql-test/main/query_cache.test
@@ -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/main/show_check.result b/mysql-test/main/show_check.result
index 5083f1e615b..f4e2047414c 100644
--- a/mysql-test/main/show_check.result
+++ b/mysql-test/main/show_check.result
@@ -757,11 +757,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/main/show_check.test b/mysql-test/main/show_check.test
index a24fa632ea5..b6885b1fcaf 100644
--- a/mysql-test/main/show_check.test
+++ b/mysql-test/main/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/main/sp-error.result b/mysql-test/main/sp-error.result
index fc43bdf17e9..de4c4cf3103 100644
--- a/mysql-test/main/sp-error.result
+++ b/mysql-test/main/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/main/sp-error.test b/mysql-test/main/sp-error.test
index 0e16948f438..88d9809265a 100644
--- a/mysql-test/main/sp-error.test
+++ b/mysql-test/main/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/main/sp.result b/mysql-test/main/sp.result
index 5e457fae1e0..e7b50c54c67 100644
--- a/mysql-test/main/sp.result
+++ b/mysql-test/main/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|
diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test
index c97f6dbba68..67363d57790 100644
--- a/mysql-test/main/sp.test
+++ b/mysql-test/main/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|
diff --git a/mysql-test/main/subselect.result b/mysql-test/main/subselect.result
index 1c087a3199c..ce03034e0c1 100644
--- a/mysql-test/main/subselect.result
+++ b/mysql-test/main/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
@@ -3726,7 +3727,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))
@@ -5094,34 +5095,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
@@ -5152,23 +5150,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
@@ -5186,35 +5184,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
@@ -5243,11 +5229,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
@@ -5255,29 +5241,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
@@ -5289,11 +5275,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 );
@@ -5303,9 +5292,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
@@ -5313,19 +5302,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 );
@@ -5341,18 +5336,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/main/subselect.test b/mysql-test/main/subselect.test
index c5cec99cebf..9af3727df21 100644
--- a/mysql-test/main/subselect.test
+++ b/mysql-test/main/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;
@@ -2604,8 +2605,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)));
@@ -4229,31 +4228,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
@@ -4281,25 +4280,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;
@@ -4313,7 +4312,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;
@@ -4324,10 +4323,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;
@@ -4345,41 +4348,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
@@ -4391,12 +4394,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;
@@ -4405,25 +4405,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 );
@@ -4433,17 +4427,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/main/subselect_mat.result b/mysql-test/main/subselect_mat.result
index 4d425d0fe5c..a570e74fc8c 100644
--- a/mysql-test/main/subselect_mat.result
+++ b/mysql-test/main/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/main/subselect_no_exists_to_in.result b/mysql-test/main/subselect_no_exists_to_in.result
index eb912d9e331..85b18c2ce9c 100644
--- a/mysql-test/main/subselect_no_exists_to_in.result
+++ b/mysql-test/main/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
@@ -3729,7 +3730,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/main/subselect_no_mat.result b/mysql-test/main/subselect_no_mat.result
index 72f30bbd21f..a2de845e5e4 100644
--- a/mysql-test/main/subselect_no_mat.result
+++ b/mysql-test/main/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
@@ -3729,7 +3730,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))
@@ -5094,34 +5095,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
@@ -5152,23 +5150,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
@@ -5186,35 +5184,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
@@ -5243,11 +5229,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
@@ -5255,29 +5241,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
@@ -5289,11 +5275,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 );
@@ -5303,9 +5292,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
@@ -5313,19 +5302,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 );
@@ -5341,18 +5336,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/main/subselect_no_opts.result b/mysql-test/main/subselect_no_opts.result
index de075d3245f..05cc0f44ff1 100644
--- a/mysql-test/main/subselect_no_opts.result
+++ b/mysql-test/main/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
@@ -3725,7 +3726,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))
@@ -5090,34 +5091,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
@@ -5148,23 +5146,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
@@ -5182,35 +5180,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
@@ -5239,11 +5225,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
@@ -5251,29 +5237,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
@@ -5285,11 +5271,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 );
@@ -5299,9 +5288,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
@@ -5309,19 +5298,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 );
@@ -5337,18 +5332,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/main/subselect_no_scache.result b/mysql-test/main/subselect_no_scache.result
index a594f5f85b9..1593ad50096 100644
--- a/mysql-test/main/subselect_no_scache.result
+++ b/mysql-test/main/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
@@ -3732,7 +3733,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))
@@ -5100,34 +5101,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
@@ -5158,23 +5156,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
@@ -5192,35 +5190,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
@@ -5249,11 +5235,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
@@ -5261,29 +5247,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
@@ -5295,11 +5281,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 );
@@ -5309,9 +5298,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
@@ -5319,19 +5308,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 );
@@ -5347,18 +5342,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/main/subselect_no_semijoin.result b/mysql-test/main/subselect_no_semijoin.result
index e068b28b017..2afc6dc8051 100644
--- a/mysql-test/main/subselect_no_semijoin.result
+++ b/mysql-test/main/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
@@ -3725,7 +3726,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))
@@ -5090,34 +5091,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
@@ -5148,23 +5146,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
@@ -5182,35 +5180,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
@@ -5239,11 +5225,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
@@ -5251,29 +5237,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
@@ -5285,11 +5271,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 );
@@ -5299,9 +5288,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
@@ -5309,19 +5298,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 );
@@ -5337,18 +5332,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/main/subselect_sj.result b/mysql-test/main/subselect_sj.result
index 9631192da33..fb286bc3d53 100644
--- a/mysql-test/main/subselect_sj.result
+++ b/mysql-test/main/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/main/subselect_sj.test b/mysql-test/main/subselect_sj.test
index 6fdccee339d..2eda8ee3e29 100644
--- a/mysql-test/main/subselect_sj.test
+++ b/mysql-test/main/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/main/subselect_sj_jcl6.result b/mysql-test/main/subselect_sj_jcl6.result
index 77a073ea2d3..4810d06f1c3 100644
--- a/mysql-test/main/subselect_sj_jcl6.result
+++ b/mysql-test/main/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/main/subselect_sj_mat.result b/mysql-test/main/subselect_sj_mat.result
index 9e1870875ce..579a9db0218 100644
--- a/mysql-test/main/subselect_sj_mat.result
+++ b/mysql-test/main/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/main/subselect_sj_mat.test b/mysql-test/main/subselect_sj_mat.test
index bfd3b28a5b2..66c11b61435 100644
--- a/mysql-test/main/subselect_sj_mat.test
+++ b/mysql-test/main/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/main/table_value_constr.result b/mysql-test/main/table_value_constr.result
index 39caba331ef..ed9c198197c 100644
--- a/mysql-test/main/table_value_constr.result
+++ b/mysql-test/main/table_value_constr.result
@@ -366,7 +366,6 @@ values (1,2);
1 2
1 2
3 4
-1 2
# combination of different structures that uses VALUES structures : UNION + UNION ALL
values (1,2),(3,4)
union all
diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result
index 4e5f9312e03..47ac8cf5319 100644
--- a/mysql-test/main/union.result
+++ b/mysql-test/main/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/main/union.test b/mysql-test/main/union.test
index f86cae87524..463eb609151 100644
--- a/mysql-test/main/union.test
+++ b/mysql-test/main/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/main/view.result b/mysql-test/main/view.result
index e61e2d2663d..0c8a3458170 100644
--- a/mysql-test/main/view.result
+++ b/mysql-test/main/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;
@@ -3153,7 +3153,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;
@@ -4093,7 +4093,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
@@ -4101,8 +4101,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
@@ -4110,8 +4110,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
@@ -4119,8 +4119,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
@@ -4128,8 +4128,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
@@ -4137,8 +4137,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
@@ -4146,8 +4146,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
@@ -4155,8 +4155,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
@@ -4164,18 +4164,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/main/view.test b/mysql-test/main/view.test
index f78ddd6f49e..fe7f22b1f89 100644
--- a/mysql-test/main/view.test
+++ b/mysql-test/main/view.test
@@ -833,12 +833,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;
@@ -3109,7 +3109,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;
@@ -4042,7 +4042,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
@@ -4050,8 +4050,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
@@ -4059,8 +4059,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
@@ -4068,8 +4068,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
@@ -4077,8 +4077,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
@@ -4086,8 +4086,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
@@ -4095,8 +4095,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
@@ -4104,8 +4104,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
@@ -4113,18 +4113,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/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
new file mode 100644
index 00000000000..874e930fb5b
--- /dev/null
+++ b/mysql-test/r/sp-error.result
@@ -0,0 +1,2876 @@
+drop table if exists t1, t2;
+SELECT * FROM mysql.proc INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/proc.txt';
+delete from mysql.proc;
+create procedure syntaxerror(t int)|
+ERROR 42000: You 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
+create procedure syntaxerror(t int)|
+ERROR 42000: You 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
+create procedure syntaxerror(t int)|
+ERROR 42000: You 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
+drop table if exists t3|
+create table t3 ( x int )|
+insert into t3 values (2), (3)|
+create procedure bad_into(out param int)
+select x from t3 into param|
+call bad_into(@x)|
+ERROR 42000: Result consisted of more than one row
+drop procedure bad_into|
+drop table t3|
+create procedure proc1()
+set @x = 42|
+create function func1() returns int
+return 42|
+create procedure foo()
+create procedure bar() set @x=3|
+ERROR 2F003: Can't create a PROCEDURE from within another stored routine
+create procedure foo()
+create function bar() returns double return 2.3|
+ERROR 2F003: Can't create a FUNCTION from within another stored routine
+create procedure proc1()
+set @x = 42|
+ERROR 42000: PROCEDURE proc1 already exists
+create function func1() returns int
+return 42|
+ERROR 42000: FUNCTION func1 already exists
+drop procedure proc1|
+drop function func1|
+alter procedure foo|
+ERROR 42000: PROCEDURE test.foo does not exist
+alter function foo|
+ERROR 42000: FUNCTION test.foo does not exist
+drop procedure foo|
+ERROR 42000: PROCEDURE test.foo does not exist
+drop function foo|
+ERROR 42000: FUNCTION test.foo does not exist
+call foo()|
+ERROR 42000: PROCEDURE test.foo does not exist
+drop procedure if exists foo|
+Warnings:
+Note 1305 PROCEDURE test.foo does not exist
+show create procedure foo|
+ERROR 42000: PROCEDURE foo does not exist
+show create function foo|
+ERROR 42000: FUNCTION foo does not exist
+create procedure foo()
+foo: loop
+leave bar;
+end loop|
+ERROR 42000: LEAVE with no matching label: bar
+create procedure foo()
+foo: loop
+iterate bar;
+end loop|
+ERROR 42000: ITERATE with no matching label: bar
+create procedure foo()
+foo: begin
+iterate foo;
+end|
+ERROR 42000: ITERATE with no matching label: foo
+create procedure foo()
+foo: loop
+foo: loop
+set @x=2;
+end loop foo;
+end loop foo|
+ERROR 42000: Redefining label foo
+create procedure foo()
+foo: loop
+set @x=2;
+end loop bar|
+ERROR 42000: End-label bar without match
+create procedure foo()
+return 42|
+ERROR 42000: RETURN is only allowed in a FUNCTION
+create procedure p(x int)
+set @x = x|
+create function f(x int) returns int
+return x+42|
+call p()|
+ERROR 42000: Incorrect number of arguments for PROCEDURE test.p; expected 1, got 0
+call p(1, 2)|
+ERROR 42000: Incorrect number of arguments for PROCEDURE test.p; expected 1, got 2
+select f()|
+ERROR 42000: Incorrect number of arguments for FUNCTION test.f; expected 1, got 0
+select f(1, 2)|
+ERROR 42000: Incorrect number of arguments for FUNCTION test.f; expected 1, got 2
+drop procedure p|
+drop function f|
+create procedure p(val int, out res int)
+begin
+declare x int default 0;
+declare continue handler for foo set x = 1;
+insert into test.t1 values (val);
+if (x) then
+set res = 0;
+else
+set res = 1;
+end if;
+end|
+ERROR 42000: Undefined CONDITION: foo
+create procedure p(val int, out res int)
+begin
+declare x int default 0;
+declare foo condition for 1146;
+declare continue handler for bar set x = 1;
+insert into test.t1 values (val);
+if (x) then
+set res = 0;
+else
+set res = 1;
+end if;
+end|
+ERROR 42000: Undefined CONDITION: bar
+create function f(val int) returns int
+begin
+declare x int;
+set x = val+3;
+end|
+ERROR 42000: No RETURN found in FUNCTION test.f
+create function f(val int) returns int
+begin
+declare x int;
+set x = val+3;
+if x < 4 then
+return x;
+end if;
+end|
+select f(10)|
+ERROR 2F005: FUNCTION f ended without RETURN
+drop function f|
+create procedure p()
+begin
+declare c cursor for insert into test.t1 values ("foo", 42);
+open c;
+close c;
+end|
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'insert into test.t1 values ("foo", 42);
+open c;
+close c;
+end' at line 3
+create procedure p()
+begin
+declare x int;
+declare c cursor for select * into x from test.t limit 1;
+open c;
+close c;
+end|
+ERROR 42000: Cursor SELECT must not have INTO
+create procedure p()
+begin
+declare c cursor for select * from test.t;
+open cc;
+close c;
+end|
+ERROR 42000: Undefined CURSOR: cc
+drop table if exists t1|
+create table t1 (val int)|
+create procedure p()
+begin
+declare c cursor for select * from test.t1;
+open c;
+open c;
+close c;
+end|
+call p()|
+ERROR 24000: Cursor is already open
+drop procedure p|
+create procedure p()
+begin
+declare c cursor for select * from test.t1;
+open c;
+close c;
+close c;
+end|
+call p()|
+ERROR 24000: Cursor is not open
+drop procedure p|
+alter procedure bar3 sql security invoker|
+ERROR 42000: PROCEDURE test.bar3 does not exist
+drop table t1|
+drop table if exists t1|
+create table t1 (val int, x float)|
+insert into t1 values (42, 3.1), (19, 1.2)|
+create procedure p()
+begin
+declare x int;
+declare c cursor for select * from t1;
+open c;
+fetch c into x, y;
+close c;
+end|
+ERROR 42000: Undeclared variable: y
+create procedure p()
+begin
+declare x int;
+declare c cursor for select * from t1;
+open c;
+fetch c into x;
+close c;
+end|
+call p()|
+ERROR HY000: Incorrect number of FETCH variables
+drop procedure p|
+create procedure p()
+begin
+declare x int;
+declare y float;
+declare z int;
+declare c cursor for select * from t1;
+open c;
+fetch c into x, y, z;
+close c;
+end|
+call p()|
+ERROR HY000: Incorrect number of FETCH variables
+drop procedure p|
+create procedure p(in x int, x char(10))
+begin
+end|
+ERROR 42000: Duplicate parameter: x
+create function p(x int, x char(10))
+begin
+end|
+ERROR 42000: Duplicate parameter: x
+create procedure p()
+begin
+declare x float;
+declare x int;
+end|
+ERROR 42000: Duplicate variable: x
+create procedure p()
+begin
+declare c condition for 1064;
+declare c condition for 1065;
+end|
+ERROR 42000: Duplicate condition: c
+create procedure p()
+begin
+declare c cursor for select * from t1;
+declare c cursor for select field from t1;
+end|
+ERROR 42000: Duplicate cursor: c
+create procedure u()
+use sptmp|
+ERROR 0A000: USE is not allowed in stored procedures
+create procedure p()
+begin
+declare c cursor for select * from t1;
+declare x int;
+end|
+ERROR 42000: Variable or condition declaration after cursor or handler declaration
+create procedure p()
+begin
+declare x int;
+declare continue handler for sqlstate '42S99' set x = 1;
+declare foo condition for sqlstate '42S99';
+end|
+ERROR 42000: Variable or condition declaration after cursor or handler declaration
+create procedure p()
+begin
+declare x int;
+declare continue handler for sqlstate '42S99' set x = 1;
+declare c cursor for select * from t1;
+end|
+ERROR 42000: Cursor declaration after handler declaration
+drop procedure if exists p|
+create procedure p(in x int, inout y int, out z int)
+begin
+set y = x+y;
+set z = x+y;
+end|
+set @tmp_x = 42|
+set @tmp_y = 3|
+set @tmp_z = 0|
+call p(@tmp_x, @tmp_y, @tmp_z)|
+select @tmp_x, @tmp_y, @tmp_z|
+@tmp_x @tmp_y @tmp_z
+42 45 87
+call p(42, 43, @tmp_z)|
+ERROR 42000: OUT or INOUT argument 2 for routine test.p is not a variable or NEW pseudo-variable in BEFORE trigger
+call p(42, @tmp_y, 43)|
+ERROR 42000: OUT or INOUT argument 3 for routine test.p is not a variable or NEW pseudo-variable in BEFORE trigger
+drop procedure p|
+create procedure p() begin end|
+lock table t1 read|
+call p()|
+unlock tables|
+drop procedure p|
+lock tables t1 read, mysql.proc write|
+ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
+lock tables mysql.proc write, mysql.user write|
+ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
+lock tables t1 read, mysql.proc read|
+unlock tables|
+lock tables mysql.proc write|
+unlock tables|
+drop function if exists f1|
+create function f1(i int) returns int
+begin
+insert into t1 (val) values (i);
+return 0;
+end|
+select val, f1(val) from t1|
+ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger
+select val, f1(val) from t1 as tab|
+ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger
+select * from t1|
+val x
+42 3.1
+19 1.2
+update t1 set val= f1(val)|
+ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger
+select * from t1|
+val x
+42 3.1
+19 1.2
+select f1(17)|
+f1(17)
+0
+select * from t1|
+val x
+42 3.1
+19 1.2
+17 NULL
+delete from t1 where val= 17|
+drop function f1|
+create procedure bug1965()
+begin
+declare c cursor for select val from t1 order by valname;
+open c;
+close c;
+end|
+call bug1965()|
+ERROR 42S22: Unknown column 'valname' in 'order clause'
+drop procedure bug1965|
+select 1 into a|
+ERROR 42000: Undeclared variable: a
+drop table if exists t3|
+create table t3 (column_1_0 int)|
+create procedure bug1653()
+update t3 set column_1 = 0|
+call bug1653()|
+ERROR 42S22: Unknown column 'column_1' in 'field list'
+drop table t3|
+create table t3 (column_1 int)|
+call bug1653()|
+drop procedure bug1653|
+drop table t3|
+create procedure bug2259()
+begin
+declare v1 int;
+declare c1 cursor for select s1 from t1;
+fetch c1 into v1;
+end|
+call bug2259()|
+ERROR 24000: Cursor is not open
+drop procedure bug2259|
+create procedure bug2272()
+begin
+declare v int;
+update t1 set v = 42;
+end|
+insert into t1 values (666, 51.3)|
+call bug2272()|
+ERROR 42S22: Unknown column 'v' in 'field list'
+truncate table t1|
+drop procedure bug2272|
+create procedure bug2329_1()
+begin
+declare v int;
+insert into t1 (v) values (5);
+end|
+create procedure bug2329_2()
+begin
+declare v int;
+replace t1 set v = 5;
+end|
+call bug2329_1()|
+ERROR 42S22: Unknown column 'v' in 'field list'
+call bug2329_2()|
+ERROR 42S22: Unknown column 'v' in 'field list'
+drop procedure bug2329_1|
+drop procedure bug2329_2|
+create function bug3287() returns int
+begin
+declare v int default null;
+case
+when v is not null then return 1;
+end case;
+return 2;
+end|
+select bug3287()|
+ERROR 20000: Case not found for CASE statement
+drop function bug3287|
+create procedure bug3287(x int)
+case x
+when 0 then
+insert into test.t1 values (x, 0.1);
+when 1 then
+insert into test.t1 values (x, 1.1);
+end case|
+call bug3287(2)|
+ERROR 20000: Case not found for CASE statement
+drop procedure bug3287|
+drop table if exists t3|
+create table t3 (s1 int, primary key (s1))|
+insert into t3 values (5),(6)|
+create procedure bug3279(out y int)
+begin
+declare x int default 0;
+begin
+declare exit handler for sqlexception set x = x+1;
+insert into t3 values (5);
+end;
+if x < 2 then
+set x = x+1;
+insert into t3 values (6);
+end if;
+set y = x;
+end|
+set @x = 0|
+call bug3279(@x)|
+ERROR 23000: Duplicate entry '6' for key 'PRIMARY'
+select @x|
+@x
+0
+drop procedure bug3279|
+drop table t3|
+create procedure nodb.bug3339() begin end|
+ERROR 42000: Unknown database 'nodb'
+create procedure bug2653_1(a int, out b int)
+set b = aa|
+create procedure bug2653_2(a int, out b int)
+begin
+if aa < 0 then
+set b = - a;
+else
+set b = a;
+end if;
+end|
+call bug2653_1(1, @b)|
+ERROR 42S22: Unknown column 'aa' in 'field list'
+call bug2653_2(2, @b)|
+ERROR 42S22: Unknown column 'aa' in 'field list'
+drop procedure bug2653_1|
+drop procedure bug2653_2|
+create procedure bug4344() drop procedure bug4344|
+ERROR HY000: Can't drop or alter a PROCEDURE from within another stored routine
+create procedure bug4344() drop function bug4344|
+ERROR HY000: Can't drop or alter a FUNCTION from within another stored routine
+drop procedure if exists bug3294|
+create procedure bug3294()
+begin
+declare continue handler for sqlexception drop table t5;
+drop table t5;
+drop table t5;
+end|
+create table t5 (x int)|
+call bug3294()|
+ERROR 42S02: Unknown table 'test.t5'
+drop procedure bug3294|
+drop procedure if exists bug8776_1|
+drop procedure if exists bug8776_2|
+drop procedure if exists bug8776_3|
+drop procedure if exists bug8776_4|
+create procedure bug8776_1()
+begin
+declare continue handler for sqlstate '42S0200test' begin end;
+begin end;
+end|
+ERROR 42000: Bad SQLSTATE: '42S0200test'
+create procedure bug8776_2()
+begin
+declare continue handler for sqlstate '4200' begin end;
+begin end;
+end|
+ERROR 42000: Bad SQLSTATE: '4200'
+create procedure bug8776_3()
+begin
+declare continue handler for sqlstate '420000' begin end;
+begin end;
+end|
+ERROR 42000: Bad SQLSTATE: '420000'
+create procedure bug8776_4()
+begin
+declare continue handler for sqlstate '42x00' begin end;
+begin end;
+end|
+ERROR 42000: Bad SQLSTATE: '42x00'
+create procedure bug6600()
+check table t1|
+ERROR 0A000: CHECK is not allowed in stored procedures
+create procedure bug6600()
+lock table t1 read|
+ERROR 0A000: LOCK is not allowed in stored procedures
+create procedure bug6600()
+unlock table t1|
+ERROR 0A000: UNLOCK is not allowed in stored procedures
+drop procedure if exists bug9566|
+create procedure bug9566()
+begin
+select * from t1;
+end|
+lock table t1 read|
+alter procedure bug9566 comment 'Some comment'|
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+unlock tables|
+drop procedure bug9566|
+drop procedure if exists bug7299|
+create procedure bug7299()
+begin
+declare v int;
+declare c cursor for select val from t1;
+declare exit handler for sqlexception select 'Error!';
+open c;
+fetch c into v;
+end|
+truncate table t1|
+call bug7299()|
+ERROR 02000: No data - zero rows fetched, selected, or processed
+drop procedure bug7299|
+create procedure bug9073()
+begin
+declare continue handler for sqlexception select 1;
+declare continue handler for sqlexception select 2;
+end|
+ERROR 42000: Duplicate handler declared in the same block
+create procedure bug9073()
+begin
+declare condname1 condition for 1234;
+declare continue handler for condname1 select 1;
+declare exit handler for condname1 select 2;
+end|
+ERROR 42000: Duplicate handler declared in the same block
+create procedure bug9073()
+begin
+declare condname1 condition for sqlstate '42000';
+declare condname2 condition for sqlstate '42000';
+declare exit handler for condname1 select 1;
+declare continue handler for condname2 select 2;
+end|
+ERROR 42000: Duplicate handler declared in the same block
+create procedure bug9073()
+begin
+declare condname1 condition for sqlstate '42000';
+declare exit handler for condname1 select 1;
+declare exit handler for sqlstate '42000' select 2;
+end|
+ERROR 42000: Duplicate handler declared in the same block
+drop procedure if exists bug9073|
+create procedure bug9073()
+begin
+declare condname1 condition for sqlstate '42000';
+declare continue handler for condname1 select 1;
+begin
+declare exit handler for sqlstate '42000' select 2;
+begin
+declare continue handler for sqlstate '42000' select 3;
+end;
+end;
+end|
+drop procedure bug9073|
+create procedure bug7047()
+alter procedure bug7047|
+ERROR HY000: Can't drop or alter a PROCEDURE from within another stored routine
+create function bug7047() returns int
+begin
+alter function bug7047;
+return 0;
+end|
+ERROR HY000: Can't drop or alter a FUNCTION from within another stored routine
+create function bug8408() returns int
+begin
+select * from t1;
+return 0;
+end|
+ERROR 0A000: Not allowed to return a result set from a function
+create function bug8408() returns int
+begin
+show warnings;
+return 0;
+end|
+ERROR 0A000: Not allowed to return a result set from a function
+create function bug8408(a int) returns int
+begin
+declare b int;
+select b;
+return b;
+end|
+ERROR 0A000: Not allowed to return a result set from a function
+drop function if exists bug8408_f|
+drop procedure if exists bug8408_p|
+create function bug8408_f() returns int
+begin
+call bug8408_p();
+return 0;
+end|
+create procedure bug8408_p()
+select * from t1|
+call bug8408_p()|
+val x
+select bug8408_f()|
+ERROR 0A000: Not allowed to return a result set from a function
+drop procedure bug8408_p|
+drop function bug8408_f|
+create function bug8408() returns int
+begin
+declare n int default 0;
+select count(*) into n from t1;
+return n;
+end|
+insert into t1 value (2, 2.7), (3, 3.14), (7, 7.0)|
+select *,bug8408() from t1|
+val x bug8408()
+2 2.7 3
+3 3.14 3
+7 7 3
+drop function bug8408|
+truncate table t1|
+drop procedure if exists bug10537|
+create procedure bug10537()
+load data local infile '/tmp/somefile' into table t1|
+ERROR 0A000: LOAD DATA is not allowed in stored procedures
+drop function if exists bug8409|
+create function bug8409()
+returns int
+begin
+flush tables;
+return 5;
+end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin reset query cache;
+return 1; end|
+ERROR 0A000: RESET is not allowed in stored function or trigger
+create function bug8409() returns int begin reset master;
+return 1; end|
+ERROR 0A000: RESET is not allowed in stored function or trigger
+create function bug8409() returns int begin reset slave;
+return 1; end|
+ERROR 0A000: RESET is not allowed in stored function or trigger
+create function bug8409() returns int begin flush hosts;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush privileges;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush tables with read lock;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush tables;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush logs;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush status;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush slave;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush master;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush des_key_file;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush user_resources;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create procedure bug9529_901234567890123456789012345678901234567890123456789012345()
+begin
+end|
+ERROR 42000: Identifier name 'bug9529_901234567890123456789012345678901234567890123456789012345' is too long
+drop procedure if exists bug17015_0123456789012345678901234567890123456789012345678901234|
+create procedure bug17015_0123456789012345678901234567890123456789012345678901234()
+begin
+end|
+show procedure status like 'bug17015%'|
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
+test bug17015_0123456789012345678901234567890123456789012345678901234 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
+drop procedure bug17015_0123456789012345678901234567890123456789012345678901234|
+drop procedure if exists bug10969|
+create procedure bug10969()
+begin
+declare s1 int default 0;
+select default(s1) from t30;
+end|
+ERROR 42000: Incorrect column name 's1'
+create procedure bug10969()
+begin
+declare s1 int default 0;
+select default(t30.s1) from t30;
+end|
+drop procedure bug10969|
+drop table t1|
+create table t1(f1 int);
+create table t2(f1 int);
+CREATE PROCEDURE SP001()
+P1: BEGIN
+DECLARE ENDTABLE INT DEFAULT 0;
+DECLARE TEMP_NUM INT;
+DECLARE TEMP_SUM INT;
+DECLARE C1 CURSOR FOR SELECT F1 FROM t1;
+DECLARE C2 CURSOR FOR SELECT F1 FROM t2;
+DECLARE CONTINUE HANDLER FOR NOT FOUND SET ENDTABLE = 1;
+SET ENDTABLE=0;
+SET TEMP_SUM=0;
+SET TEMP_NUM=0;
+OPEN C1;
+FETCH C1 INTO TEMP_NUM;
+WHILE ENDTABLE = 0 DO
+SET TEMP_SUM=TEMP_NUM+TEMP_SUM;
+FETCH C1 INTO TEMP_NUM;
+END WHILE;
+SELECT TEMP_SUM;
+CLOSE C1;
+CLOSE C1;
+SELECT 'end of proc';
+END P1|
+call SP001();
+TEMP_SUM
+0
+ERROR 24000: Cursor is not open
+drop procedure SP001;
+drop table t1, t2;
+drop function if exists bug11394|
+drop function if exists bug11394_1|
+drop function if exists bug11394_2|
+drop procedure if exists bug11394|
+create function bug11394(i int) returns int
+begin
+if i <= 0 then
+return 0;
+else
+return (i in (100, 200, bug11394(i-1), 400));
+end if;
+end|
+select bug11394(2)|
+ERROR HY000: Recursive stored functions and triggers are not allowed
+drop function bug11394|
+create function bug11394_1(i int) returns int
+begin
+if i <= 0 then
+return 0;
+else
+return (select bug11394_1(i-1));
+end if;
+end|
+select bug11394_1(2)|
+ERROR HY000: Recursive stored functions and triggers are not allowed
+drop function bug11394_1|
+create function bug11394_2(i int) returns int return i|
+select bug11394_2(bug11394_2(10))|
+bug11394_2(bug11394_2(10))
+10
+drop function bug11394_2|
+create procedure bug11394(i int, j int)
+begin
+if i > 0 then
+call bug11394(i - 1,(select 1));
+end if;
+end|
+call bug11394(2, 1)|
+ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine bug11394
+set @@max_sp_recursion_depth=10|
+call bug11394(2, 1)|
+set @@max_sp_recursion_depth=default|
+drop procedure bug11394|
+CREATE PROCEDURE BUG_12490() HELP CONTENTS;
+ERROR 0A000: HELP is not allowed in stored procedures
+CREATE FUNCTION BUG_12490() RETURNS INT HELP CONTENTS;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'HELP CONTENTS' at line 1
+CREATE TABLE t_bug_12490(a int);
+CREATE TRIGGER BUG_12490 BEFORE UPDATE ON t_bug_12490 FOR EACH ROW HELP CONTENTS;
+ERROR 0A000: HELP is not allowed in stored procedures
+DROP TABLE t_bug_12490;
+drop function if exists bug11834_1;
+drop function if exists bug11834_2;
+create function bug11834_1() returns int return 10;
+create function bug11834_2() returns int return bug11834_1();
+prepare stmt from "select bug11834_2()";
+execute stmt;
+bug11834_2()
+10
+execute stmt;
+bug11834_2()
+10
+drop function bug11834_1;
+execute stmt;
+ERROR 42000: FUNCTION test.bug11834_1 does not exist
+deallocate prepare stmt;
+drop function bug11834_2;
+DROP FUNCTION IF EXISTS bug12953|
+CREATE FUNCTION bug12953() RETURNS INT
+BEGIN
+OPTIMIZE TABLE t1;
+RETURN 1;
+END|
+ERROR 0A000: Not allowed to return a result set from a function
+DROP FUNCTION IF EXISTS bug12995|
+CREATE FUNCTION bug12995() RETURNS INT
+BEGIN
+HANDLER t1 OPEN;
+RETURN 1;
+END|
+ERROR 0A000: HANDLER is not allowed in stored procedures
+CREATE FUNCTION bug12995() RETURNS INT
+BEGIN
+HANDLER t1 READ FIRST;
+RETURN 1;
+END|
+ERROR 0A000: HANDLER is not allowed in stored procedures
+CREATE FUNCTION bug12995() RETURNS INT
+BEGIN
+HANDLER t1 CLOSE;
+RETURN 1;
+END|
+ERROR 0A000: HANDLER is not allowed in stored procedures
+SELECT bug12995()|
+ERROR 42000: FUNCTION test.bug12995 does not exist
+drop procedure if exists bug12712;
+drop function if exists bug12712;
+create procedure bug12712()
+set session autocommit = 0;
+select @@autocommit;
+@@autocommit
+1
+set @au = @@autocommit;
+call bug12712();
+select @@autocommit;
+@@autocommit
+0
+set session autocommit = @au;
+create function bug12712()
+returns int
+begin
+call bug12712();
+return 0;
+end|
+set @x = bug12712()|
+ERROR HY000: Not allowed to set autocommit from a stored function or trigger
+drop procedure bug12712|
+drop function bug12712|
+create function bug12712()
+returns int
+begin
+set session autocommit = 0;
+return 0;
+end|
+ERROR HY000: Not allowed to set autocommit from a stored function or trigger
+create function bug12712()
+returns int
+begin
+set @@autocommit = 0;
+return 0;
+end|
+ERROR HY000: Not allowed to set autocommit from a stored function or trigger
+create function bug12712()
+returns int
+begin
+set local autocommit = 0;
+return 0;
+end|
+ERROR HY000: Not allowed to set autocommit from a stored function or trigger
+create trigger bug12712
+before insert on t1 for each row set session autocommit = 0;
+ERROR HY000: Not allowed to set autocommit from a stored function or trigger
+drop procedure if exists bug13510_1|
+drop procedure if exists bug13510_2|
+drop procedure if exists bug13510_3|
+drop procedure if exists bug13510_4|
+create procedure bug13510_1()
+begin
+declare password varchar(10);
+set password = 'foo1';
+select password;
+end|
+ERROR 42000: Variable 'password' must be quoted with `...`, or renamed
+set names='foo2'|
+ERROR 42000: You 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
+create procedure bug13510_2()
+begin
+declare names varchar(10);
+set names = 'foo2';
+select names;
+end|
+ERROR 42000: Variable 'names' must be quoted with `...`, or renamed
+create procedure bug13510_3()
+begin
+declare password varchar(10);
+set `password` = 'foo3';
+select password;
+end|
+create procedure bug13510_4()
+begin
+declare names varchar(10);
+set `names` = 'foo4';
+select names;
+end|
+call bug13510_3()|
+password
+foo3
+call bug13510_4()|
+names
+foo4
+drop procedure bug13510_3|
+drop procedure bug13510_4|
+drop function if exists bug_13627_f|
+CREATE TABLE t1 (a int)|
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN DROP TRIGGER test1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN DROP TRIGGER test1; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create table t2 (a int); END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN create table t2 (a int); return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create index t1_i on t1 (a); END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN create index t1_i on t1 (a); return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN alter table t1 add column b int; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN alter table t1 add column b int; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN rename table t1 to t2; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN rename table t1 to t2; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN truncate table t1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN truncate table t1; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop table t1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN drop table t1; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop index t1_i on t1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN drop index t1_i on t1; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN unlock tables; END |
+ERROR 0A000: UNLOCK is not allowed in stored procedures
+CREATE FUNCTION bug_13627_f() returns int BEGIN unlock tables; return 1; END |
+ERROR 0A000: UNLOCK is not allowed in stored procedures
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN LOCK TABLE t1 READ; END |
+ERROR 0A000: LOCK is not allowed in stored procedures
+CREATE FUNCTION bug_13627_f() returns int BEGIN LOCK TABLE t1 READ; return 1; END |
+ERROR 0A000: LOCK is not allowed in stored procedures
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create database mysqltest; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN create database mysqltest; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop database mysqltest; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN drop database mysqltest; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create user 'mysqltest_1'; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN create user 'mysqltest_1'; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN grant select on t1 to 'mysqltest_1'; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug21975() returns int BEGIN grant select on t1 to 'mysqltest_1'; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN revoke select on t1 from 'mysqltest_1'; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug21975() returns int BEGIN revoke select on t1 from 'mysqltest_1'; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN revoke all privileges on *.* from 'mysqltest_1'; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug21975() returns int BEGIN revoke all privileges on *.* from 'mysqltest_1'; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop user 'mysqltest_1'; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN drop user 'mysqltest_1'; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN rename user 'mysqltest_2' to 'mysqltest_1'; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN rename user 'mysqltest_2' to 'mysqltest_1'; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create view v1 as select 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN create view v1 as select 1; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN alter view v1 as select 1; END |
+ERROR 0A000: ALTER VIEW is not allowed in stored procedures
+CREATE FUNCTION bug_13627_f() returns int BEGIN alter view v1 as select 1; return 1; END |
+ERROR 0A000: ALTER VIEW is not allowed in stored procedures
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop view v1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE FUNCTION bug_13627_f() returns int BEGIN drop view v1; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create trigger tr2 before insert on t1 for each row do select 1; END |
+ERROR 2F003: Can't create a TRIGGER from within another stored routine
+CREATE FUNCTION bug_13627_f() returns int BEGIN create trigger tr2 before insert on t1 for each row do select 1; return 1; END |
+ERROR 2F003: Can't create a TRIGGER from within another stored routine
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop function bug_13627_f; END |
+ERROR HY000: Can't drop or alter a FUNCTION from within another stored routine
+CREATE FUNCTION bug_13627_f() returns int BEGIN drop function bug_13627_f; return 1; END |
+ERROR HY000: Can't drop or alter a FUNCTION from within another stored routine
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN create function f2 () returns int return 1; END |
+ERROR 2F003: Can't create a FUNCTION from within another stored routine
+CREATE FUNCTION bug_13627_f() returns int BEGIN create function f2 () returns int return 1; return 1; END |
+ERROR 2F003: Can't create a FUNCTION from within another stored routine
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW
+BEGIN
+CREATE TEMPORARY TABLE t2 (a int);
+DROP TEMPORARY TABLE t2;
+END |
+CREATE FUNCTION bug_13627_f() returns int
+BEGIN
+CREATE TEMPORARY TABLE t2 (a int);
+DROP TEMPORARY TABLE t2;
+return 1;
+END |
+drop table t1|
+drop function bug_13627_f|
+drop function if exists bug12329;
+Warnings:
+Note 1305 FUNCTION test.bug12329 does not exist
+create table t1 as select 1 a;
+create table t2 as select 1 a;
+create function bug12329() returns int return (select a from t1);
+prepare stmt1 from 'select bug12329()';
+execute stmt1;
+bug12329()
+1
+drop function bug12329;
+create function bug12329() returns int return (select a+100 from t2);
+select bug12329();
+bug12329()
+101
+execute stmt1;
+bug12329()
+101
+deallocate prepare stmt1;
+drop function bug12329;
+drop table t1, t2;
+create database mysqltest1;
+use mysqltest1;
+drop database mysqltest1;
+create function f1() returns int return 1;
+ERROR 3D000: No database selected
+create procedure p1(out param1 int)
+begin
+select count(*) into param1 from t3;
+end|
+ERROR 3D000: No database selected
+use test;
+DROP PROCEDURE IF EXISTS bug13037_p1;
+DROP PROCEDURE IF EXISTS bug13037_p2;
+DROP PROCEDURE IF EXISTS bug13037_p3;
+CREATE PROCEDURE bug13037_p1()
+BEGIN
+IF bug13037_foo THEN
+SELECT 1;
+END IF;
+END|
+CREATE PROCEDURE bug13037_p2()
+BEGIN
+SET @bug13037_foo = bug13037_bar;
+END|
+CREATE PROCEDURE bug13037_p3()
+BEGIN
+SELECT bug13037_foo;
+END|
+
+CALL bug13037_p1();
+ERROR 42S22: Unknown column 'bug13037_foo' in 'field list'
+CALL bug13037_p2();
+ERROR 42S22: Unknown column 'bug13037_bar' in 'field list'
+CALL bug13037_p3();
+ERROR 42S22: Unknown column 'bug13037_foo' in 'field list'
+CALL bug13037_p1();
+ERROR 42S22: Unknown column 'bug13037_foo' in 'field list'
+CALL bug13037_p2();
+ERROR 42S22: Unknown column 'bug13037_bar' in 'field list'
+CALL bug13037_p3();
+ERROR 42S22: Unknown column 'bug13037_foo' in 'field list'
+DROP PROCEDURE bug13037_p1;
+DROP PROCEDURE bug13037_p2;
+DROP PROCEDURE bug13037_p3;
+create database mysqltest1;
+create database mysqltest2;
+use mysqltest1;
+drop database mysqltest1;
+create procedure mysqltest2.p1() select version();
+create procedure p2() select version();
+ERROR 3D000: No database selected
+use mysqltest2;
+show procedure status;
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
+mysqltest2 p1 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
+drop database mysqltest2;
+use test;
+DROP FUNCTION IF EXISTS bug13012|
+CREATE FUNCTION bug13012() RETURNS INT
+BEGIN
+REPAIR TABLE t1;
+RETURN 1;
+END|
+ERROR 0A000: Not allowed to return a result set from a function
+create table t1 (a int)|
+CREATE PROCEDURE bug13012_1() REPAIR TABLE t1|
+CREATE FUNCTION bug13012_2() RETURNS INT
+BEGIN
+CALL bug13012_1();
+RETURN 1;
+END|
+SELECT bug13012_2()|
+ERROR 0A000: Not allowed to return a result set from a function
+drop table t1|
+drop procedure bug13012_1|
+drop function bug13012_2|
+drop function if exists bug11555_1;
+drop function if exists bug11555_2;
+drop view if exists v1, v2, v3, v4;
+create function bug11555_1() returns int return (select max(i) from t1);
+create function bug11555_2() returns int return bug11555_1();
+create view v1 as select bug11555_1();
+drop view v1;
+create view v2 as select bug11555_2();
+drop view v2;
+create table t1 (i int);
+create view v1 as select bug11555_1();
+create view v2 as select bug11555_2();
+create view v3 as select * from v1;
+drop table t1;
+select * from v1;
+ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+select * from v2;
+ERROR HY000: View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+select * from v3;
+ERROR HY000: View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+create view v4 as select * from v1;
+drop view v1, v2, v3, v4;
+drop function bug11555_1;
+drop function bug11555_2;
+create table t1 (i int);
+create table t2 (i int);
+create trigger t1_ai after insert on t1 for each row insert into t2 values (new.i);
+create view v1 as select * from t1;
+drop table t2;
+insert into v1 values (1);
+ERROR 42S02: Table 'test.t2' doesn't exist
+drop trigger t1_ai;
+create function bug11555_1() returns int return (select max(i) from t2);
+create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1();
+insert into v1 values (2);
+ERROR 42S02: Table 'test.t2' doesn't exist
+drop function bug11555_1;
+drop table t1;
+drop view v1;
+drop procedure if exists ` bug15658`;
+create procedure ``() select 1;
+ERROR 42000: Incorrect routine name ''
+create procedure ` `() select 1;
+ERROR 42000: Incorrect routine name ' '
+create procedure `bug15658 `() select 1;
+ERROR 42000: Incorrect routine name 'bug15658 '
+create procedure ``.bug15658() select 1;
+ERROR 42000: Incorrect database name ''
+create procedure `x `.bug15658() select 1;
+ERROR 42000: Incorrect database name 'x '
+create procedure ` bug15658`() select 1;
+call ` bug15658`();
+1
+1
+show procedure status;
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
+test bug15658 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
+drop procedure ` bug15658`;
+drop function if exists bug14270;
+drop table if exists t1;
+create table t1 (s1 int primary key);
+create function bug14270() returns int
+begin
+load index into cache t1;
+return 1;
+end|
+ERROR 0A000: Not allowed to return a result set from a function
+create function bug14270() returns int
+begin
+cache index t1 key (`primary`) in keycache1;
+return 1;
+end|
+ERROR 0A000: Not allowed to return a result set from a function
+drop table t1;
+drop procedure if exists bug15091;
+create procedure bug15091()
+begin
+declare selectstr varchar(6000) default ' ';
+declare conditionstr varchar(5000) default '';
+set selectstr = concat(selectstr,
+' and ',
+c.operatorid,
+'in (',conditionstr, ')');
+end|
+call bug15091();
+ERROR 42S02: Unknown table 'c' in field list
+drop procedure bug15091;
+drop function if exists bug16896;
+create aggregate function bug16896() returns int return 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 '() returns int return 1' at line 1
+DROP PROCEDURE IF EXISTS bug14702;
+CREATE IF NOT EXISTS PROCEDURE bug14702()
+BEGIN
+END;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'IF NOT EXISTS PROCEDURE bug14702()
+BEGIN
+END' at line 1
+CREATE PROCEDURE IF NOT EXISTS bug14702()
+BEGIN
+END;
+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: Incorrect usage/placement of 'INTO'
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file";
+ERROR 42000: Incorrect usage/placement of 'INTO'
+CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file";
+ERROR 42000: Incorrect usage/placement of 'INTO'
+CREATE PROCEDURE bug20953()
+CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE();
+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: 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()
+BEGIN
+DECLARE i INT;
+CREATE VIEW v AS SELECT i;
+END |
+ERROR HY000: View's SELECT contains a variable or parameter
+PREPARE stmt FROM "CREATE VIEW v AS SELECT ?";
+ERROR HY000: View's SELECT contains a variable or parameter
+DROP TABLE t1;
+drop tables if exists t1;
+drop procedure if exists bug24491;
+create table t1 (id int primary key auto_increment, value varchar(10));
+insert into t1 (id, value) values (1, 'FIRST'), (2, 'SECOND'), (3, 'THIRD');
+create procedure bug24491()
+insert into t1 (id, value) select * from (select 4 as i, 'FOURTH' as v) as y on duplicate key update v = 'DUP';
+call bug24491();
+ERROR 42S22: Unknown column 'v' in 'field list'
+call bug24491();
+ERROR 42S22: Unknown column 'v' in 'field list'
+drop procedure bug24491;
+create procedure bug24491()
+insert into t1 (id, value) select * from (select 4 as id, 'FOURTH' as value) as y on duplicate key update y.value = 'DUP';
+call bug24491();
+ERROR 42S22: Unknown column 'y.value' in 'field list'
+call bug24491();
+ERROR 42S22: Unknown column 'y.value' in 'field list'
+drop procedure bug24491;
+drop tables t1;
+DROP FUNCTION IF EXISTS bug18914_f1;
+DROP FUNCTION IF EXISTS bug18914_f2;
+DROP PROCEDURE IF EXISTS bug18914_p1;
+DROP PROCEDURE IF EXISTS bug18914_p2;
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (i INT);
+CREATE PROCEDURE bug18914_p1() CREATE TABLE t2 (i INT);
+CREATE PROCEDURE bug18914_p2() DROP TABLE IF EXISTS no_such_table;
+CREATE FUNCTION bug18914_f1() RETURNS INT
+BEGIN
+CALL bug18914_p1();
+RETURN 1;
+END |
+CREATE FUNCTION bug18914_f2() RETURNS INT
+BEGIN
+CALL bug18914_p2();
+RETURN 1;
+END |
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+CALL bug18914_p1();
+INSERT INTO t1 VALUES (1);
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+SELECT bug18914_f1();
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+SELECT bug18914_f2();
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger
+SELECT * FROM t2;
+ERROR 42S02: Table 'test.t2' doesn't exist
+DROP FUNCTION bug18914_f1;
+DROP FUNCTION bug18914_f2;
+DROP PROCEDURE bug18914_p1;
+DROP PROCEDURE bug18914_p2;
+DROP TABLE t1;
+drop table if exists bogus_table_20713;
+drop function if exists func_20713_a;
+drop function if exists func_20713_b;
+create table bogus_table_20713( id int(10) not null primary key);
+insert into bogus_table_20713 values (1), (2), (3);
+create function func_20713_a() returns int(11)
+begin
+declare id int;
+declare continue handler for sqlexception set id=null;
+set @in_func := 1;
+set id = (select id from bogus_table_20713 where id = 3);
+set @in_func := 2;
+return id;
+end//
+create function func_20713_b() returns int(11)
+begin
+declare id int;
+declare continue handler for sqlstate value '42S02' set id=null;
+set @in_func := 1;
+set id = (select id from bogus_table_20713 where id = 3);
+set @in_func := 2;
+return id;
+end//
+set @in_func := 0;
+select func_20713_a();
+func_20713_a()
+NULL
+select @in_func;
+@in_func
+2
+set @in_func := 0;
+select func_20713_b();
+func_20713_b()
+NULL
+select @in_func;
+@in_func
+2
+drop table bogus_table_20713;
+set @in_func := 0;
+select func_20713_a();
+func_20713_a()
+NULL
+select @in_func;
+@in_func
+2
+set @in_func := 0;
+select func_20713_b();
+func_20713_b()
+NULL
+select @in_func;
+@in_func
+2
+drop function if exists func_20713_a;
+drop function if exists func_20713_b;
+drop table if exists table_25345_a;
+drop table if exists table_25345_b;
+drop procedure if exists proc_25345;
+drop function if exists func_25345;
+drop function if exists func_25345_b;
+create table table_25345_a (a int);
+create table table_25345_b (b int);
+create procedure proc_25345()
+begin
+declare c1 cursor for select a from table_25345_a;
+declare c2 cursor for select b from table_25345_b;
+select 1 as result;
+end ||
+create function func_25345() returns int(11)
+begin
+call proc_25345();
+return 1;
+end ||
+create function func_25345_b() returns int(11)
+begin
+declare c1 cursor for select a from table_25345_a;
+declare c2 cursor for select b from table_25345_b;
+return 1;
+end ||
+call proc_25345();
+result
+1
+select func_25345();
+ERROR 0A000: Not allowed to return a result set from a function
+select func_25345_b();
+func_25345_b()
+1
+drop table table_25345_a;
+call proc_25345();
+result
+1
+select func_25345();
+ERROR 0A000: Not allowed to return a result set from a function
+select func_25345_b();
+func_25345_b()
+1
+drop table table_25345_b;
+drop procedure proc_25345;
+drop function func_25345;
+drop function func_25345_b;
+End of 5.0 tests
+drop function if exists bug16164;
+create function bug16164() returns int
+begin
+show authors;
+return 42;
+end|
+ERROR 0A000: Not allowed to return a result set from a function
+drop function if exists bug20701;
+create function bug20701() returns varchar(25) binary return "test";
+drop function bug20701;
+create function bug20701() returns varchar(25) return "test";
+drop function bug20701;
+create procedure proc_26503_error_1()
+begin
+retry:
+repeat
+begin
+declare continue handler for sqlexception
+begin
+iterate retry;
+end
+select "do something";
+end
+until true end repeat retry;
+end//
+ERROR 42000: ITERATE with no matching label: retry
+create procedure proc_26503_error_2()
+begin
+retry:
+repeat
+begin
+declare continue handler for sqlexception
+iterate retry;
+select "do something";
+end
+until true end repeat retry;
+end//
+ERROR 42000: ITERATE with no matching label: retry
+create procedure proc_26503_error_3()
+begin
+retry:
+repeat
+begin
+declare continue handler for sqlexception
+begin
+leave retry;
+end
+select "do something";
+end
+until true end repeat retry;
+end//
+ERROR 42000: LEAVE with no matching label: retry
+create procedure proc_26503_error_4()
+begin
+retry:
+repeat
+begin
+declare continue handler for sqlexception
+leave retry;
+select "do something";
+end
+until true end repeat retry;
+end//
+ERROR 42000: LEAVE with no matching label: retry
+drop procedure if exists proc_28360;
+drop function if exists func_28360;
+CREATE PROCEDURE proc_28360()
+BEGIN
+ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
+END//
+ERROR HY000: Can't drop or alter a DATABASE from within another stored routine
+CREATE FUNCTION func_28360() RETURNS int
+BEGIN
+ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
+RETURN 0;
+END//
+ERROR HY000: Can't drop or alter a DATABASE from within another stored routine
+DROP PROCEDURE IF EXISTS p1;
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE c char(100);
+DECLARE cur1 CURSOR FOR SHOW TABLES;
+OPEN cur1;
+FETCH cur1 INTO c;
+select c;
+CLOSE cur1;
+END|
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SHOW TABLES;
+OPEN cur1;
+FETCH cur1 INTO c;
+select c;
+CLOSE cur1;
+END' at line 4
+DROP DATABASE IF EXISTS mysqltest;
+CREATE DATABASE mysqltest;
+USE mysqltest;
+DROP DATABASE mysqltest;
+SELECT inexistent(), 1 + ,;
+ERROR 42000: FUNCTION inexistent does not exist
+SELECT inexistent();
+ERROR 42000: FUNCTION inexistent does not exist
+SELECT .inexistent();
+ERROR 42000: You 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 ..inexistent();
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '..inexistent()' at line 1
+USE test;
+create function f1() returns int
+begin
+set @test = 1, password = password('foo');
+return 1;
+end|
+ERROR HY000: Not allowed to set autocommit from a stored function or trigger
+create trigger t1
+before insert on t2 for each row set password = password('foo');|
+ERROR HY000: Not allowed to set autocommit from a stored function or trigger
+drop function if exists f1;
+drop function if exists f2;
+drop table if exists t1, t2;
+create function f1() returns int
+begin
+drop temporary table t1;
+return 1;
+end|
+create temporary table t1 as select f1();
+ERROR 42S02: Unknown table 'test.t1'
+create function f2() returns int
+begin
+create temporary table t2 as select f1();
+return 1;
+end|
+create temporary table t1 as select f2();
+ERROR 42S02: Unknown table 'test.t1'
+drop function f1;
+drop function f2;
+create function f1() returns int
+begin
+drop temporary table t2,t1;
+return 1;
+end|
+create function f2() returns int
+begin
+create temporary table t2 as select f1();
+return 1;
+end|
+create temporary table t1 as select f2();
+ERROR 42S02: Unknown table 'test.t2,test.t1'
+drop function f1;
+drop function f2;
+create temporary table t2(a int);
+select * from t2;
+a
+create function f2() returns int
+begin
+drop temporary table t2;
+return 1;
+end|
+select f2();
+f2()
+1
+drop function f2;
+drop table t2;
+ERROR 42S02: Unknown table 'test.t2'
+End of 5.1 tests
+drop procedure if exists proc_33983_a;
+drop procedure if exists proc_33983_b;
+drop procedure if exists proc_33983_c;
+drop procedure if exists proc_33983_d;
+create procedure proc_33983_a()
+begin
+label1:
+begin
+label2:
+begin
+select 1;
+end label1;
+end;
+end|
+ERROR 42000: End-label label1 without match
+create procedure proc_33983_b()
+begin
+label1:
+repeat
+label2:
+repeat
+select 1;
+until FALSE end repeat label1;
+until FALSE end repeat;
+end|
+ERROR 42000: End-label label1 without match
+create procedure proc_33983_c()
+begin
+label1:
+while TRUE do
+label2:
+while TRUE do
+select 1;
+end while label1;
+end while;
+end|
+ERROR 42000: End-label label1 without match
+create procedure proc_33983_d()
+begin
+label1:
+loop
+label2:
+loop
+select 1;
+end loop label1;
+end loop;
+end|
+ERROR 42000: End-label label1 without match
+CREATE TABLE t1 (a INT)|
+INSERT INTO t1 VALUES (1),(2)|
+CREATE PROCEDURE p1(a INT) BEGIN END|
+CALL p1((SELECT * FROM t1))|
+ERROR 21000: Subquery returns more than 1 row
+DROP PROCEDURE IF EXISTS p1|
+DROP TABLE t1|
+drop procedure if exists p1;
+create procedure p1()
+begin
+create table t1 (a int) engine=MyISAM;
+drop table t1;
+end|
+call p1();
+call p1();
+drop procedure p1;
+drop procedure if exists proc_8759;
+create procedure proc_8759()
+begin
+declare should_be_illegal condition for sqlstate '00000';
+declare continue handler for should_be_illegal set @x=0;
+end$$
+ERROR 42000: Bad SQLSTATE: '00000'
+create procedure proc_8759()
+begin
+declare continue handler for sqlstate '00000' set @x=0;
+end$$
+ERROR 42000: Bad SQLSTATE: '00000'
+drop procedure if exists proc_36510;
+create procedure proc_36510()
+begin
+declare should_be_illegal condition for sqlstate '00123';
+declare continue handler for should_be_illegal set @x=0;
+end$$
+ERROR 42000: Bad SQLSTATE: '00123'
+create procedure proc_36510()
+begin
+declare continue handler for sqlstate '00123' set @x=0;
+end$$
+ERROR 42000: Bad SQLSTATE: '00123'
+create procedure proc_36510()
+begin
+declare should_be_illegal condition for 0;
+declare continue handler for should_be_illegal set @x=0;
+end$$
+ERROR HY000: Incorrect CONDITION value: '0'
+create procedure proc_36510()
+begin
+declare continue handler for 0 set @x=0;
+end$$
+ERROR HY000: Incorrect CONDITION value: '0'
+drop procedure if exists p1;
+set @old_recursion_depth = @@max_sp_recursion_depth;
+set @@max_sp_recursion_depth = 255;
+create procedure p1(a int)
+begin
+declare continue handler for 1436 -- ER_STACK_OVERRUN_NEED_MORE
+select 'exception';
+call p1(a+1);
+end|
+call p1(1);
+set @@max_sp_recursion_depth = @old_recursion_depth;
+drop procedure p1;
+LOAD DATA INFILE '../../tmp/proc.txt' INTO TABLE mysql.proc;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1,1), (2,2);
+SELECT MAX (a) FROM t1 WHERE b = 999999;
+ERROR 42000: FUNCTION test.MAX does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual
+SELECT AVG (a) FROM t1 WHERE b = 999999;
+AVG (a)
+NULL
+SELECT non_existent (a) FROM t1 WHERE b = 999999;
+ERROR 42000: FUNCTION test.non_existent does not exist
+DROP TABLE t1;
+CREATE TABLE t1 ( f2 INTEGER, f3 INTEGER );
+INSERT INTO t1 VALUES ( 1, 1 );
+CREATE FUNCTION func_1 () RETURNS INTEGER
+BEGIN
+INSERT INTO t1 SELECT * FROM t1 ;
+RETURN 1 ;
+END|
+INSERT INTO t1 SELECT * FROM (SELECT 2 AS f1, 2 AS f2) AS A WHERE func_1() = 5;
+ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger
+DROP FUNCTION func_1;
+DROP TABLE t1;
+#
+# Bug #47788: Crash in TABLE_LIST::hide_view_error on UPDATE + VIEW +
+# SP + MERGE + ALTER
+#
+CREATE TABLE t1 (pk INT, b INT, KEY (b));
+CREATE ALGORITHM = TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+CREATE PROCEDURE p1 (a int) UPDATE IGNORE v1 SET b = a;
+CALL p1(5);
+ERROR HY000: The target table v1 of the UPDATE is not updatable
+ALTER TABLE t1 CHANGE COLUMN b b2 INT;
+CALL p1(7);
+ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# Bug#12428824 - PARSER STACK OVERFLOW AND CRASH IN SP_ADD_USED_ROUTINE
+# WITH OBSCURE QUERY
+#
+SELECT very_long_fn_name_1111111111111111111111111111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222225555555555555555555555555577777777777777777777777777777777777777777777777777777777777777777777777788888888999999999999999999999();
+ERROR 42000: Identifier name 'very_long_fn_name_1111111111111111111111111111111111111111111111111111111111111111111111111222222222' is too long
+CALL very_long_pr_name_1111111111111111111111111111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222225555555555555555555555555577777777777777777777777777777777777777777777777777777777777777777777777788888888999999999999999999999();
+ERROR 42000: Identifier name 'very_long_pr_name_1111111111111111111111111111111111111111111111111111111111111111111111111222222222' is too long
+SELECT very_long_db_name_1111111111111111111111111111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222225555555555555555555555555577777777777777777777777777777777777777777777777777777777777777777777777788888888999999999999999999999.simple_func();
+ERROR 42000: Incorrect database name 'very_long_db_name_1111111111111111111111111111111111111111111111111111111111111111111111111222222222'
+CALL very_long_db_name_1111111111111111111111111111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222225555555555555555555555555577777777777777777777777777777777777777777777777777777777777777777777777788888888999999999999999999999.simple_proc();
+ERROR 42000: Incorrect database name 'very_long_db_name_1111111111111111111111111111111111111111111111111111111111111111111111111222222222'
+SELECT db_name.very_long_fn_name_111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222999999999999999999999();
+ERROR 42000: Identifier name 'very_long_fn_name_1111111111111111111111111111111111111111111111111111111111111111111111111222222222' is too long
+CALL db_name.very_long_pr_name_111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222999999999999999999999();
+ERROR 42000: Identifier name 'very_long_pr_name_1111111111111111111111111111111111111111111111111111111111111111111111111222222222' is too long
+End of 5.1 tests
+#
+# Bug#23032: Handlers declared in a SP do not handle warnings generated in sub-SP
+#
+
+# - Case 1
+
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+DROP PROCEDURE IF EXISTS p4;
+DROP PROCEDURE IF EXISTS p5;
+DROP PROCEDURE IF EXISTS p6;
+CREATE PROCEDURE p1()
+BEGIN
+SELECT CAST('10 ' as unsigned integer);
+SELECT 1;
+CALL p2();
+END|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT CAST('10 ' as unsigned integer);
+END|
+CALL p1();
+CAST('10 ' as unsigned integer)
+10
+1
+1
+CAST('10 ' as unsigned integer)
+10
+Warnings:
+Note 1292 Truncated incorrect INTEGER value: '10 '
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+
+# - Case 2
+
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE c INT DEFAULT 0;
+DECLARE CONTINUE HANDLER FOR SQLSTATE '22007' SET c = c + 1;
+CALL p2();
+CALL p3();
+CALL p4();
+SELECT c;
+SELECT @@warning_count;
+SHOW WARNINGS;
+END|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT CAST('10 ' as unsigned integer);
+END|
+CREATE PROCEDURE p3()
+BEGIN
+SELECT CAST('10 ' as unsigned integer);
+SELECT 1;
+END|
+CREATE PROCEDURE p4()
+BEGIN
+SELECT CAST('10 ' as unsigned integer);
+CALL p2();
+END|
+CREATE PROCEDURE p5()
+BEGIN
+SELECT CAST('10 ' as unsigned integer);
+SHOW WARNINGS;
+END|
+CREATE PROCEDURE P6()
+BEGIN
+DECLARE c INT DEFAULT 0;
+DECLARE CONTINUE HANDLER FOR SQLSTATE '22007' SET c = c + 1;
+CALL p5();
+SELECT c;
+END|
+CALL p1();
+CAST('10 ' as unsigned integer)
+10
+CAST('10 ' as unsigned integer)
+10
+1
+1
+CAST('10 ' as unsigned integer)
+10
+CAST('10 ' as unsigned integer)
+10
+c
+3
+@@warning_count
+0
+Level Code Message
+CALL p6();
+CAST('10 ' as unsigned integer)
+10
+Level Code Message
+Note 1292 Truncated incorrect INTEGER value: '10 '
+c
+1
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
+DROP PROCEDURE p5;
+DROP PROCEDURE p6;
+
+# - Case 3: check that "Exception trumps No Data".
+
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1), (2), (3);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE c CURSOR FOR SELECT a FROM t1;
+OPEN c;
+BEGIN
+DECLARE v1 INT;
+DECLARE v2 INT;
+DECLARE EXIT HANDLER FOR SQLEXCEPTION
+SELECT "Error caught (expected)";
+DECLARE EXIT HANDLER FOR NOT FOUND
+SELECT "End of Result Set found!";
+WHILE TRUE DO
+FETCH c INTO v1, v2;
+END WHILE;
+END;
+CLOSE c;
+SELECT a INTO @foo FROM t1 LIMIT 1; # Clear warning stack
+END|
+CALL p1();
+Error caught (expected)
+Error caught (expected)
+DROP PROCEDURE p1;
+DROP TABLE t1;
+#
+# Bug#36185: Incorrect precedence for warning and exception handlers
+#
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
+CREATE TABLE t1 (a INT, b INT NOT NULL);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING SELECT 'warning';
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'exception';
+INSERT INTO t1 VALUES (CAST('10 ' AS SIGNED), NULL);
+END|
+CALL p1();
+exception
+exception
+DROP TABLE t1;
+DROP PROCEDURE p1;
+#
+# Bug#5889: Exit handler for a warning doesn't hide the warning in trigger
+#
+SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+BEGIN
+DECLARE EXIT HANDLER FOR SQLWARNING
+SET NEW.a = 10;
+SET NEW.a = 99999999999;
+END|
+UPDATE t1 SET b = 20;
+SHOW WARNINGS;
+Level Code Message
+SELECT * FROM t1;
+a b
+10 20
+DROP TRIGGER t1_bu;
+DROP TABLE t1;
+SET sql_mode = DEFAULT;
+#
+# Bug#9857: Stored procedures: handler for sqlwarning ignored
+#
+SET @sql_mode_saved = @@sql_mode;
+SET sql_mode = traditional;
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'warning caught (expected)';
+SELECT 5 / 0;
+END|
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+SELECT 'error caught (unexpected)';
+SELECT 5 / 0;
+END|
+CALL p1();
+5 / 0
+NULL
+warning caught (expected)
+warning caught (expected)
+SHOW WARNINGS;
+Level Code Message
+CALL p2();
+5 / 0
+NULL
+Warnings:
+Warning 1365 Division by 0
+SHOW WARNINGS;
+Level Code Message
+Warning 1365 Division by 0
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+SET sql_mode = @sql_mode_saved;
+#
+# Bug#55850: Trigger warnings not cleared.
+#
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP PROCEDURE IF EXISTS p1;
+CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT);
+CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT,
+d SMALLINT, e SMALLINT, f SMALLINT);
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+INSERT IGNORE INTO t2(a, b, c) VALUES(99999, 99999, 99999);
+CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
+INSERT IGNORE INTO t2(d, e, f) VALUES(99999, 99999, 99999);
+CREATE PROCEDURE p1()
+INSERT IGNORE INTO t1 VALUES(99999, 99999, 99999);
+
+CALL p1();
+Warnings:
+Warning 1264 Out of range value for column 'x' at row 1
+Warning 1264 Out of range value for column 'y' at row 1
+Warning 1264 Out of range value for column 'z' at row 1
+
+SHOW WARNINGS;
+Level Code Message
+Warning 1264 Out of range value for column 'x' at row 1
+Warning 1264 Out of range value for column 'y' at row 1
+Warning 1264 Out of range value for column 'z' at row 1
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP PROCEDURE p1;
+# ----------------------------------------------------------------------
+SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
+CREATE TABLE t1(x SMALLINT, y SMALLINT, z SMALLINT);
+CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT NOT NULL);
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+BEGIN
+INSERT INTO t2 VALUES(
+CAST('111111 ' AS SIGNED),
+CAST('222222 ' AS SIGNED),
+NULL);
+END|
+CREATE PROCEDURE p1()
+INSERT INTO t1 VALUES(99999, 99999, 99999);
+
+CALL p1();
+ERROR 23000: Column 'c' cannot be null
+
+SHOW WARNINGS;
+Level Code Message
+Warning 1264 Out of range value for column 'x' at row 1
+Warning 1264 Out of range value for column 'y' at row 1
+Warning 1264 Out of range value for column 'z' at row 1
+Note 1292 Truncated incorrect INTEGER value: '111111 '
+Warning 1264 Out of range value for column 'a' at row 1
+Note 1292 Truncated incorrect INTEGER value: '222222 '
+Warning 1264 Out of range value for column 'b' at row 1
+Error 1048 Column 'c' cannot be null
+Note 4092 At line 6 in test.t1_bi
+Note 4092 At line 2 in test.p1
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP PROCEDURE p1;
+SET sql_mode = DEFAULT;
+
+###################################################################
+# Tests for the following bugs:
+# - Bug#11763171: 55852 - Possibly inappropriate handler activation.
+# - Bug#11749343: 38806 - Wrong scope for SQL HANDLERS in SP.
+###################################################################
+
+
+# -- Check that SQL-conditions thrown by Statement-blocks are
+# -- handled by Handler-decl blocks properly.
+
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+SELECT 'H1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'H2' AS HandlerId;
+SIGNAL SQLSTATE '01000'; # Should be handled by H2.
+END|
+
+CALL p1()|
+HandlerId
+H2
+
+# -- Check that SQL-conditions thrown by Statement-blocks are
+# -- handled by Handler-decl blocks properly in case of nested
+# -- SQL-blocks.
+
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+SELECT 'H1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'H2' AS HandlerId;
+BEGIN
+SELECT 'B1' AS BlockId;
+BEGIN
+SELECT 'B2' AS BlockId;
+BEGIN
+SELECT 'B3' AS BlockId;
+SIGNAL SQLSTATE '01000'; # Should be handled by H2.
+END;
+END;
+END;
+END|
+
+CALL p2()|
+BlockId
+B1
+BlockId
+B2
+BlockId
+B3
+HandlerId
+H2
+
+# -- Check SQL-handler resolution rules.
+
+CREATE PROCEDURE p3()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+SELECT 'H1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'H2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'H3' AS HandlerId;
+SIGNAL SQLSTATE '01000'; # Should be handled by H3.
+END|
+
+CALL p3()|
+HandlerId
+H3
+
+CREATE PROCEDURE p4()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+SELECT 'H1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'H2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'H3' AS HandlerId;
+SIGNAL SQLSTATE '01000'; # Should be handled by H2.
+END|
+
+CALL p4()|
+HandlerId
+H2
+
+CREATE PROCEDURE p5()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+SELECT 'H1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'H2' AS HandlerId;
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'H3' AS HandlerId;
+SIGNAL SQLSTATE '01000'; # Should be handled by H3.
+END;
+END|
+
+CALL p5()|
+HandlerId
+H3
+
+# -- Check that handlers don't handle its own exceptions.
+
+CREATE PROCEDURE p6()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+SELECT 'H1' AS HandlerId;
+SIGNAL SQLSTATE 'HY000'; # Should *not* be handled by H1.
+END;
+SELECT 'S1' AS SignalId;
+SIGNAL SQLSTATE 'HY000'; # Should be handled by H1.
+END|
+
+CALL p6()|
+SignalId
+S1
+HandlerId
+H1
+ERROR HY000: Unhandled user-defined exception condition
+
+# -- Check that handlers don't handle its own warnings.
+
+CREATE PROCEDURE p7()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+BEGIN
+SELECT 'H1' AS HandlerId;
+SIGNAL SQLSTATE '01000'; # Should *not* be handled by H1.
+END;
+SELECT 'S1' AS SignalId;
+SIGNAL SQLSTATE '01000'; # Should be handled by H1.
+END|
+
+CALL p7()|
+SignalId
+S1
+HandlerId
+H1
+Warnings:
+Warning 1642 Unhandled user-defined warning condition
+
+# -- Check that conditions for handlers are not handled by the handlers
+# -- from the same block.
+
+CREATE PROCEDURE p8()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'H1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+SELECT 'H2' AS HandlerId;
+SIGNAL SQLSTATE '01000'; # Should *not* be handled by H1.
+END;
+SELECT 'S1' AS SignalId;
+SIGNAL SQLSTATE 'HY000'; # Should be handled by H2.
+END|
+
+CALL p8()|
+SignalId
+S1
+HandlerId
+H2
+Warnings:
+Warning 1642 Unhandled user-defined warning condition
+
+# -- Check that conditions for handlers are not handled by the handlers
+# -- from the same block even if they are thrown deep down the stack.
+
+CREATE PROCEDURE p9()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H1:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H1:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H2:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H2:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H3:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H3:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H4:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H4:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H5:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H5:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H6:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H6:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+SELECT 'H2' AS HandlerId;
+SIGNAL SQLSTATE '01000'; # Should *not* be handled by H1.
+END;
+SELECT 'S6' AS SignalId;
+SIGNAL SQLSTATE 'HY000';
+END;
+SELECT 'S5' AS SignalId;
+SIGNAL SQLSTATE 'HY000';
+END;
+SELECT 'S4' AS SignalId;
+SIGNAL SQLSTATE 'HY000';
+END;
+SELECT 'S3' AS SignalId;
+SIGNAL SQLSTATE 'HY000';
+END;
+SELECT 'S2' AS SignalId;
+SIGNAL SQLSTATE 'HY000';
+END;
+SELECT 'S1' AS SignalId;
+SIGNAL SQLSTATE 'HY000'; # Should be handled by H2.
+END|
+
+CALL p9()|
+SignalId
+S1
+SignalId
+S2
+SignalId
+S3
+SignalId
+S4
+SignalId
+S5
+SignalId
+S6
+HandlerId
+H2
+Warnings:
+Warning 1642 Unhandled user-defined warning condition
+
+# -- Check that handlers are choosen properly in case of deep stack and
+# -- nested SQL-blocks.
+
+CREATE PROCEDURE p10()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'H1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'H2' AS HandlerId;
+BEGIN
+BEGIN
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H1:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H1:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H2:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H2:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H3:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H3:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H4:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H4:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H5:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H5:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000'
+ SELECT 'Wrong:H6:1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'Wrong:H6:2' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+SELECT 'H2' AS HandlerId;
+SIGNAL SQLSTATE '01000'; # Should be handled by H1.
+END;
+SELECT 'S6' AS SignalId;
+SIGNAL SQLSTATE 'HY000';
+END;
+SELECT 'S5' AS SignalId;
+SIGNAL SQLSTATE 'HY000';
+END;
+SELECT 'S4' AS SignalId;
+SIGNAL SQLSTATE 'HY000';
+END;
+SELECT 'S3' AS SignalId;
+SIGNAL SQLSTATE 'HY000';
+END;
+SELECT 'S2' AS SignalId;
+SIGNAL SQLSTATE 'HY000';
+END;
+SELECT 'S1' AS SignalId;
+SIGNAL SQLSTATE 'HY000'; # Should be handled by H2.
+END;
+END;
+END;
+END|
+
+CALL p10()|
+SignalId
+S1
+SignalId
+S2
+SignalId
+S3
+SignalId
+S4
+SignalId
+S5
+SignalId
+S6
+HandlerId
+H2
+HandlerId
+H1
+
+# -- Test stored procedure from Peter's mail.
+
+CREATE PROCEDURE p11()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+SELECT 'H1' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'H2' AS HandlerId;
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01000', 1249
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+SELECT 'H3' AS HandlerId;
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+SELECT 'H4' AS HandlerId;
+BEGIN
+SELECT 'H5' AS HandlerId;
+SELECT 'S3' AS SignalId;
+SIGNAL SQLSTATE 'HY000'; # H3
+SELECT 'S4' AS SignalId;
+SIGNAL SQLSTATE '22003'; # H3
+SELECT 'S5' AS SignalId;
+SIGNAL SQLSTATE '01000' SET MYSQL_ERRNO = 1249; # H4
+END;
+END;
+SELECT 'S6' AS SignalId;
+SIGNAL SQLSTATE 'HY000'; # H1
+SELECT 'S7' AS SignalId;
+SIGNAL SQLSTATE '22003'; # H1
+SELECT 'S8' AS SignalId;
+SIGNAL SQLSTATE '01000' SET MYSQL_ERRNO = 1249; # H5
+END;
+SELECT 'S1' AS SignalId;
+SIGNAL SQLSTATE 'HY000'; # H1
+SELECT 'S2' AS SignalId;
+SIGNAL SQLSTATE '01000' SET MYSQL_ERRNO = 1249; # H2
+END|
+
+CALL p11()|
+SignalId
+S6
+HandlerId
+H1
+SignalId
+S7
+HandlerId
+H1
+SignalId
+S8
+HandlerId
+H5
+SignalId
+S3
+HandlerId
+H3
+SignalId
+S4
+HandlerId
+H3
+SignalId
+S5
+HandlerId
+H4
+SignalId
+S1
+HandlerId
+H1
+SignalId
+S2
+HandlerId
+H2
+
+# -- Check that runtime stack-trace can be deeper than parsing-time one.
+
+CREATE PROCEDURE p12()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01001'
+ BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01001'
+ BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01001'
+ BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01001'
+ BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01001'
+ BEGIN
+SELECT 'H1:5' AS HandlerId;
+SIGNAL SQLSTATE '01002';
+END;
+SELECT 'H1:4' AS HandlerId;
+SIGNAL SQLSTATE '01001';
+END;
+SELECT 'H1:3' AS HandlerId;
+SIGNAL SQLSTATE '01001';
+END;
+SELECT 'H1:2' AS HandlerId;
+SIGNAL SQLSTATE '01001';
+END;
+SELECT 'H1:1' AS HandlerId;
+SIGNAL SQLSTATE '01001';
+END;
+#########################################################
+DECLARE CONTINUE HANDLER FOR SQLSTATE '01002'
+ SELECT 'OK' AS Msg;
+#########################################################
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+BEGIN
+SELECT 'H2:5' AS HandlerId;
+SIGNAL SQLSTATE '01001';
+END;
+SELECT 'H2:4' AS HandlerId;
+SIGNAL SQLSTATE '01000';
+END;
+SELECT 'H2:3' AS HandlerId;
+SIGNAL SQLSTATE '01000';
+END;
+SELECT 'H2:2' AS HandlerId;
+SIGNAL SQLSTATE '01000';
+END;
+SELECT 'H2:1' AS HandlerId;
+SIGNAL SQLSTATE '01000';
+END;
+#######################################################
+SELECT 'Throw 01000' AS Msg;
+SIGNAL SQLSTATE '01000';
+END;
+END|
+
+CALL p12()|
+Msg
+Throw 01000
+HandlerId
+H2:1
+HandlerId
+H2:2
+HandlerId
+H2:3
+HandlerId
+H2:4
+HandlerId
+H2:5
+HandlerId
+H1:1
+HandlerId
+H1:2
+HandlerId
+H1:3
+HandlerId
+H1:4
+HandlerId
+H1:5
+Warnings:
+Warning 1642 Unhandled user-defined warning condition
+
+# -- Check that handler-call-frames are removed properly for EXIT
+# -- handlers.
+
+CREATE PROCEDURE p13()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING
+BEGIN
+DECLARE EXIT HANDLER FOR SQLWARNING
+BEGIN
+SELECT 'EXIT handler 3' AS Msg;
+END;
+SELECT 'CONTINUE handler 2: 1' AS Msg;
+SIGNAL SQLSTATE '01000';
+SELECT 'CONTINUE handler 2: 2' AS Msg;
+END;
+SELECT 'CONTINUE handler 1: 1' AS Msg;
+SIGNAL SQLSTATE '01000';
+SELECT 'CONTINUE handler 1: 2' AS Msg;
+END;
+SELECT 'Throw 01000' AS Msg;
+SIGNAL SQLSTATE '01000';
+END|
+
+CALL p13()|
+Msg
+Throw 01000
+Msg
+CONTINUE handler 1: 1
+Msg
+CONTINUE handler 2: 1
+Msg
+EXIT handler 3
+Msg
+CONTINUE handler 1: 2
+
+# That's it. Cleanup.
+
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
+DROP PROCEDURE p5;
+DROP PROCEDURE p6;
+DROP PROCEDURE p7;
+DROP PROCEDURE p8;
+DROP PROCEDURE p9;
+DROP PROCEDURE p10;
+DROP PROCEDURE p11;
+DROP PROCEDURE p12;
+DROP PROCEDURE p13;
+
+# Bug#12731619: NESTED SP HANDLERS CAN TRIGGER ASSERTION
+
+DROP FUNCTION IF EXISTS f1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(msg VARCHAR(255));
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION # handler 1
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION # handler 2
+BEGIN
+INSERT INTO t1 VALUE('WRONG: Inside H2');
+RETURN 2;
+END;
+INSERT INTO t1 VALUE('CORRECT: Inside H1');
+RETURN 1;
+END;
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING # handler 3
+BEGIN
+INSERT INTO t1 VALUE('WRONG: Inside H3');
+RETURN 3;
+END;
+INSERT INTO t1 VALUE('CORRECT: Calling f1()');
+RETURN f1(); # -- exception here
+END;
+INSERT INTO t1 VALUE('WRONG: Returning 10');
+RETURN 10;
+END|
+
+SELECT f1();
+f1()
+1
+
+SELECT * FROM t1;
+msg
+CORRECT: Calling f1()
+CORRECT: Inside H1
+
+DROP FUNCTION f1;
+DROP TABLE t1;
+
+# Check that handled SQL-conditions are properly cleared from DA.
+
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+DROP PROCEDURE IF EXISTS p4;
+DROP PROCEDURE IF EXISTS p5;
+CREATE TABLE t1(a CHAR, b CHAR, c CHAR);
+CREATE TABLE t2(a SMALLINT, b SMALLINT, c SMALLINT);
+
+# Check that SQL-conditions for which SQL-handler has been invoked,
+# are cleared from the Diagnostics Area. Note, there might be several
+# SQL-conditions, but SQL-handler must be invoked only once.
+
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE EXIT HANDLER FOR SQLWARNING
+SELECT 'Warning caught' AS msg;
+# The INSERT below raises 3 SQL-conditions (warnings). The EXIT HANDLER
+# above must be invoked once (for one condition), but all three conditions
+# must be cleared from the Diagnostics Area.
+INSERT IGNORE INTO t1 VALUES('qqqq', 'ww', 'eee');
+# The following INSERT will not be executed, because of the EXIT HANDLER.
+INSERT INTO t1 VALUES('zzz', 'xx', 'yyyy');
+END|
+
+CALL p1()|
+msg
+Warning caught
+
+SELECT * FROM t1|
+a b c
+q w e
+
+# Check that SQL-conditions for which SQL-handler has *not* been
+# invoked, are *still* cleared from the Diagnostics Area.
+
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE CONTINUE HANDLER FOR 1292
+SELECT 'Warning 1292 caught' AS msg;
+# The following INSERT raises 6 SQL-warnings with code 1292,
+# and 3 SQL-warnings with code 1264. The CONTINUE HANDLER above must be
+# invoked once, and all nine SQL-warnings must be cleared from
+# the Diagnostics Area.
+INSERT IGNORE INTO t2
+SELECT
+CAST(CONCAT(CAST('1 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER),
+CAST(CONCAT(CAST('2 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER),
+CAST(CONCAT(CAST('3 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER);
+END|
+
+CALL p2()|
+msg
+Warning 1292 caught
+
+# Check that if there are two equally ranked SQL-handlers to handle
+# SQL-conditions from SQL-statement, only one of them will be invoked.
+
+CREATE PROCEDURE p3()
+BEGIN
+DECLARE CONTINUE HANDLER FOR 1292
+SELECT 'Warning 1292 caught' AS msg;
+DECLARE CONTINUE HANDLER FOR 1264
+SELECT 'Warning 1264 caught' AS msg;
+# The following INSERT raises 6 SQL-warnings with code 1292,
+# and 3 SQL-warnings with code 1264. Only one of the CONTINUE HANDLERs above
+# must be called, and only once. The SQL Standard does not define, which one
+# should be invoked.
+INSERT INTO t2
+SELECT
+CAST(CONCAT(CAST('1 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER),
+CAST(CONCAT(CAST('2 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER),
+CAST(CONCAT(CAST('3 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER);
+END|
+
+CALL p3()|
+msg
+Warning 1264 caught
+
+# The same as p3, but 1264 comes first.
+
+CREATE PROCEDURE p4()
+BEGIN
+DECLARE CONTINUE HANDLER FOR 1292
+SELECT 'Warning 1292 caught' AS msg;
+DECLARE CONTINUE HANDLER FOR 1264
+SELECT 'Warning 1264 caught' AS msg;
+# The following INSERT raises 4 SQL-warnings with code 1292,
+# and 3 SQL-warnings with code 1264. Only one of the CONTINUE HANDLERs above
+# must be called, and only once. The SQL Standard does not define, which one
+# should be invoked.
+INSERT INTO t2
+SELECT
+CAST(999999 AS SIGNED INTEGER),
+CAST(CONCAT(CAST('2 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER),
+CAST(CONCAT(CAST('3 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER);
+END|
+
+CALL p4()|
+msg
+Warning 1264 caught
+
+# Check that if a SQL-handler raised its own SQL-conditions, there are
+# preserved after handler exit.
+
+CREATE PROCEDURE p5()
+BEGIN
+DECLARE EXIT HANDLER FOR 1292
+BEGIN
+SELECT 'Handler for 1292 (1)' AS Msg;
+SIGNAL SQLSTATE '01000' SET MYSQL_ERRNO = 1234;
+SHOW WARNINGS;
+SELECT 'Handler for 1292 (2)' AS Msg;
+END;
+INSERT IGNORE INTO t2
+SELECT
+CAST(999999 AS SIGNED INTEGER),
+CAST(CONCAT(CAST('2 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER),
+CAST(CONCAT(CAST('3 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER);
+END|
+
+CALL p5()|
+Msg
+Handler for 1292 (1)
+Level Code Message
+Warning 1234 Unhandled user-defined warning condition
+Msg
+Handler for 1292 (2)
+Warnings:
+Warning 1234 Unhandled user-defined warning condition
+
+# Check that SQL-conditions are available inside the handler, but
+# cleared after the handler exits.
+
+CREATE PROCEDURE p6()
+BEGIN
+DECLARE CONTINUE HANDLER FOR 1292
+BEGIN
+SHOW WARNINGS;
+SELECT 'Handler for 1292' Msg;
+END;
+INSERT IGNORE INTO t2
+SELECT
+CAST(CONCAT(CAST('1 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER),
+CAST(CONCAT(CAST('2 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER),
+CAST(CONCAT(CAST('3 ' AS UNSIGNED INTEGER), '999999 ') AS SIGNED INTEGER);
+END|
+
+CALL p6()|
+Level Code Message
+Note 1292 Truncated incorrect INTEGER value: '1 '
+Note 1292 Truncated incorrect INTEGER value: '1999999 '
+Warning 1264 Out of range value for column 'a' at row 1
+Note 1292 Truncated incorrect INTEGER value: '2 '
+Note 1292 Truncated incorrect INTEGER value: '2999999 '
+Warning 1264 Out of range value for column 'b' at row 1
+Note 1292 Truncated incorrect INTEGER value: '3 '
+Note 1292 Truncated incorrect INTEGER value: '3999999 '
+Warning 1264 Out of range value for column 'c' at row 1
+Msg
+Handler for 1292
+
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
+DROP PROCEDURE p5;
+DROP PROCEDURE p6;
+DROP TABLE t1;
+DROP TABLE t2;
+
+# Bug#13059316: ASSERTION FAILURE IN SP_RCONTEXT.CC
+# Check DECLARE statements that raise conditions before handlers
+# are declared.
+
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+SET sql_mode = '';
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE var1 INTEGER DEFAULT 'string';
+DECLARE EXIT HANDLER FOR SQLWARNING SELECT 'H1';
+END|
+
+CALL p1()|
+Warnings:
+Warning 1366 Incorrect integer value: 'string' for column 'var1' at row 1
+
+SET sql_mode = DEFAULT;
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE EXIT HANDLER FOR SQLWARNING SELECT 'H2';
+CALL p1();
+END|
+
+CALL p2()|
+H2
+H2
+
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+#
+# Bug#13113222 RQG_SIGNAL_RESIGNAL FAILED WITH ASSERTION.
+#
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'triggered p1';
+# This will trigger an error.
+SIGNAL SQLSTATE 'HY000';
+END|
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLWARNING SELECT 'triggered p2';
+# This will trigger a warning.
+SIGNAL SQLSTATE '01000';
+END|
+SET @old_max_error_count= @@session.max_error_count;
+SET SESSION max_error_count= 0;
+CALL p1();
+triggered p1
+triggered p1
+CALL p2();
+SET SESSION max_error_count= @old_max_error_count;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+
+# Bug#12652873: 61392: Continue handler for NOT FOUND being triggered
+# from internal stored function.
+
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP TABLE IF EXISTS t1;
+
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+
+# f1() raises NOT_FOUND condition.
+# Raising NOT_FOUND can not be simulated by SIGNAL,
+# because SIGNAL would raise SQL-error in that case.
+
+CREATE FUNCTION f1() RETURNS INTEGER
+BEGIN
+DECLARE v VARCHAR(5) DEFAULT -1;
+SELECT b FROM t1 WHERE a = 2 INTO v;
+RETURN v;
+END|
+
+# Here we check that the NOT_FOUND condition raised in f1()
+# is not visible in the outer function (f2), i.e. the continue
+# handler in f2() will not be called.
+
+CREATE FUNCTION f2() RETURNS INTEGER
+BEGIN
+DECLARE v INTEGER;
+DECLARE CONTINUE HANDLER FOR NOT FOUND
+SET @msg = 'Handler activated.';
+SELECT f1() INTO v;
+RETURN v;
+END|
+SET @msg = '';
+
+SELECT f2();
+f2()
+-1
+
+SELECT @msg;
+@msg
+
+
+DROP FUNCTION f1;
+DROP FUNCTION f2;
+DROP TABLE t1;
diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result
index b00d1a56c90..bf523d47515 100644
--- a/mysql-test/suite/funcs_1/r/innodb_views.result
+++ b/mysql-test/suite/funcs_1/r/innodb_views.result
@@ -3497,7 +3497,7 @@ DROP VIEW IF EXISTS v2 ;
CREATE TABLE t1 (f1 BIGINT) ;
SET @x=0;
CREATE or REPLACE VIEW v1 AS Select 1 INTO @x;
-ERROR 42000: You 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 @x' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
Select @x;
@x
0
diff --git a/mysql-test/suite/funcs_1/r/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result
index 5ac5c838fb5..57a6813b2fb 100644
--- a/mysql-test/suite/funcs_1/r/memory_views.result
+++ b/mysql-test/suite/funcs_1/r/memory_views.result
@@ -3498,7 +3498,7 @@ DROP VIEW IF EXISTS v2 ;
CREATE TABLE t1 (f1 BIGINT) ;
SET @x=0;
CREATE or REPLACE VIEW v1 AS Select 1 INTO @x;
-ERROR 42000: You 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 @x' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
Select @x;
@x
0
diff --git a/mysql-test/suite/funcs_1/views/views_master.inc b/mysql-test/suite/funcs_1/views/views_master.inc
index 17f5c1e5529..e4b58111612 100644
--- a/mysql-test/suite/funcs_1/views/views_master.inc
+++ b/mysql-test/suite/funcs_1/views/views_master.inc
@@ -266,7 +266,7 @@ CREATE TABLE t1 (f1 BIGINT) ;
# SELECT INTO is illegal
SET @x=0;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
CREATE or REPLACE VIEW v1 AS Select 1 INTO @x;
Select @x;
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index aafd31ae6f1..005fd70534a 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -1608,7 +1608,7 @@ INSERT INTO t1 VALUES (1),(2),(3);
CREATE TABLE t2 (b_id tinyint(4) NOT NULL default '0',b_a tinyint(4) NOT NULL default '0', PRIMARY KEY (b_id), KEY (b_a),
CONSTRAINT fk_b_a FOREIGN KEY (b_a) REFERENCES t1 (a_id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t2 VALUES (1,1),(2,1),(3,1),(4,2),(5,2);
-SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN (t2) on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz;
+SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN t2 on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz;
a_id b_list
1 1,2,3
2 4,5
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index 472b47899db..dd8a67eeec2 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -1253,7 +1253,7 @@ CREATE TABLE t2 (b_id tinyint(4) NOT NULL default '0',b_a tinyint(4) NOT NULL de
CONSTRAINT fk_b_a FOREIGN KEY (b_a) REFERENCES t1 (a_id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--enable_warnings
INSERT INTO t2 VALUES (1,1),(2,1),(3,1),(4,2),(5,2);
-SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN (t2) on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz;
+SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN t2 on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz;
DROP TABLE t2;
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_fts/r/fulltext_order_by.result b/mysql-test/suite/innodb_fts/r/fulltext_order_by.result
index 503f117d02f..0d3a4a85b86 100644
--- a/mysql-test/suite/innodb_fts/r/fulltext_order_by.result
+++ b/mysql-test/suite/innodb_fts/r/fulltext_order_by.result
@@ -129,7 +129,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
@@ -145,7 +145,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/suite/versioning/r/select2.result b/mysql-test/suite/versioning/r/select2.result
index 9267ab8c913..3f29a958907 100644
--- a/mysql-test/suite/versioning/r/select2.result
+++ b/mysql-test/suite/versioning/r/select2.result
@@ -331,6 +331,6 @@ x y
select * from (select * from t1 for system_time all, t2 for system_time all) for system_time all as t;
ERROR HY000: Table `t` is not system-versioned
select * from (t1 for system_time all join t2 for system_time all) for system_time 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 '' 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 'system_time all' at line 1
drop view v1;
drop table t1, t2;
diff --git a/sql/events.cc b/sql/events.cc
index 2fbb16861f6..7568d03c0e0 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -826,12 +826,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.str);
- 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.str,
+ DBUG_ASSERT(thd->lex->first_select_lex()->db.str);
+ 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.str,
NULL, NULL, 0, 0))
DBUG_RETURN(1);
- db= normalize_db_name(thd->lex->select_lex.db.str, db_tmp, sizeof(db_tmp));
+ db= normalize_db_name(thd->lex->first_select_lex()->db.str,
+ 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 dd12d9a476f..b5acebedf7f 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -734,7 +734,8 @@ 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.str),
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.str),
field_name(*field_name_arg),
alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX),
@@ -3077,7 +3078,10 @@ Item_field::Item_field(THD *thd, Field *f)
have_privileges(0), any_privileges(0)
{
set_field(f);
-
+ /*
+ field_name and table_name should not point to garbage
+ if this item is to be reused
+ */
orig_table_name= table_name;
orig_field_name= field_name;
with_field= 1;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 6378e9b76bf..5a447cef23a 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -123,14 +123,7 @@ 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: %p", engine));
+ 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 cd47cbba9bd..2e342936893 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -4389,7 +4389,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, size_t que
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() &&
@@ -7339,8 +7339,9 @@ 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.str, field_list, &thd->lex->select_lex.context);
+ thd->lex->first_select_lex()->context.resolve_in_table_list_only(&tables);
+ set_fields(tables.db.str,
+ 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 38dbed92a22..39c36cdd529 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -4543,7 +4543,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 ef9b07cca47..95743ecaad4 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 bf373dde905..0923682a486 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -730,7 +730,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_head.cc b/sql/sp_head.cc
index f7847bae89d..7129f362fd2 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -317,7 +317,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
@@ -556,6 +556,7 @@ sp_head::sp_head(sp_package *parent, const Sp_handler *sph)
m_backpatch_goto.empty();
m_cont_backpatch.empty();
m_lex.empty();
+ m_stmt_lex.empty();
my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8, MYF(0));
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,
@@ -830,13 +831,15 @@ 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;
thd->lex->sphead= NULL;
lex_end(thd->lex);
delete thd->lex;
- thd->lex= thd->stmt_lex= lex;
+ thd->lex= lex;
+ thd->stmt_lex= m_stmt_lex.pop();
}
my_hash_free(&m_sptabs);
@@ -2285,6 +2288,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (!err_status)
{
err_status= execute(thd, TRUE);
+ DBUG_PRINT("info", ("execute returned %d", (int) err_status));
}
if (save_log_general)
@@ -2386,10 +2390,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));
}
diff --git a/sql/sp_head.h b/sql/sp_head.h
index f588f79b599..f28e1919959 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -589,10 +589,12 @@ public:
{
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)
{
@@ -858,6 +860,7 @@ protected:
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 2e9ae23d7f9..19b23cd59ee 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -227,9 +227,10 @@ bool Qualified_column_ident::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, this, NULL, 0,
- TL_READ_NO_INSERT,
- MDL_SHARED_READ)) &&
+ if ((table_list=
+ lex.first_select_lex()->add_table_to_list(thd, this, 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()))
@@ -285,9 +286,10 @@ bool Table_ident::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, this, NULL, 0,
- TL_READ_NO_INSERT,
- MDL_SHARED_READ)) &&
+ if ((table_list=
+ lex.first_select_lex()->add_table_to_list(thd, this, 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 82fc1cbfff7..610b1a9ffed 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;
@@ -1295,7 +1295,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");
@@ -1315,7 +1315,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:
@@ -1326,7 +1326,7 @@ error:
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");
@@ -1339,7 +1339,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:
@@ -1350,7 +1350,7 @@ error:
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");
@@ -1372,7 +1372,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:
@@ -1383,7 +1383,7 @@ error:
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");
@@ -1407,7 +1407,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 77e0c9d5298..e4c84c1c3cb 100644
--- a/sql/sql_alter.cc
+++ b/sql/sql_alter.cc
@@ -201,7 +201,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;
/*
@@ -345,7 +345,7 @@ error:
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 3354a2fdf1b..f26407eacff 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -7435,7 +7435,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)
{
@@ -7463,7 +7463,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)
@@ -8017,7 +8017,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;
@@ -8033,7 +8033,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 a6a85d47dc9..6cbf6005f04 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -358,10 +358,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, column_usage,
sum_func_list, NULL, 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 c8f18556d50..9aee9e14870 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -4130,13 +4130,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,
@@ -4157,7 +4157,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 7b7d34c6bc0..8f1deee3821 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1374,12 +1374,13 @@ void THD::init(bool skip_lock)
}
-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;
}
@@ -3798,6 +3799,7 @@ Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
id(id_arg),
column_usage(MARK_COLUMNS_READ),
lex(lex_arg),
+ stmt_lex(lex_arg),
db(null_clex_str)
{
name= null_clex_str;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index a7c33cbc504..b6476963727 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4547,6 +4547,7 @@ public:
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;
@@ -4724,7 +4725,7 @@ public:
/**
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= stmt_lex= sublex;
@@ -4743,7 +4744,7 @@ public:
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);
Item *sp_fix_func_item(Item **it_addr);
Item *sp_prepare_func_item(Item **it_addr, uint cols= 1);
@@ -6134,7 +6135,8 @@ public:
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 a58a9254a82..4a2ff42733e 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -55,6 +55,14 @@ bool With_clause::add_with_element(With_element *elem)
}
+void st_select_lex_unit::set_with_clause(With_clause *with_cl)
+{
+ with_clause= with_cl;
+ if (with_clause)
+ with_clause->set_owner(this);
+}
+
+
/**
@brief
Check dependencies between tables defined in a list of with clauses
@@ -683,7 +691,7 @@ void With_element::move_anchors_ahead()
st_select_lex *next_sl;
st_select_lex *new_pos= spec->first_select();
st_select_lex *UNINIT_VAR(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();
@@ -829,9 +837,8 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
if (parser_state.init(thd, (char*) unparsed_spec.str, (unsigned int)unparsed_spec.length))
goto err;
lex_start(thd);
- with_select= &lex->select_lex;
- with_select->select_number= ++thd->stmt_lex->current_select_number;
parse_status= parse_sql(thd, &parser_state, 0);
+ with_select= lex->first_select_lex();
if (parse_status)
goto err;
@@ -982,7 +989,7 @@ 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;
}
@@ -1094,6 +1101,7 @@ bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
return true;
}
derived->first_select()->linkage= DERIVED_TABLE_TYPE;
+ select_lex->add_statistics(derived);
with_elem->inc_references();
return false;
}
diff --git a/sql/sql_cte.h b/sql/sql_cte.h
index 16b473f0665..4a194b2a38f 100644
--- a/sql/sql_cte.h
+++ b/sql/sql_cte.h
@@ -279,8 +279,7 @@ private:
*/
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
@@ -304,9 +303,8 @@ public:
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)
{ }
@@ -320,8 +318,12 @@ public:
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();
@@ -354,7 +356,6 @@ bool With_element::is_unrestricted()
}
inline
-
bool With_element::is_with_prepared_anchor()
{
return owner->with_prepared_anchor & get_elem_map();
@@ -436,11 +437,14 @@ 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);
+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 0a12d01596b..4a8f4e71d1d 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -285,7 +285,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
bool has_triggers;
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 binlog_is_row;
@@ -350,7 +350,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_RETURN(TRUE);
}
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);
@@ -382,7 +382,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);
}
}
@@ -926,14 +926,16 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
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))
@@ -1015,21 +1017,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;
@@ -1071,8 +1075,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 ab66384c6cb..26b1fca473a 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 20a7aa75590..72acbd763e1 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 67440aeed33..160bf7469c5 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -781,7 +781,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_help.cc b/sql/sql_help.cc
index da38a2caf94..866bf86c733 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++)
@@ -719,10 +719,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 392aa52825e..aa51af80407 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;
@@ -273,7 +273,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);
@@ -657,7 +657,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())
{
@@ -783,7 +783,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
@@ -1073,7 +1073,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;
/*
@@ -1261,7 +1261,7 @@ abort:
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);
}
@@ -1291,7 +1291,7 @@ abort:
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;
@@ -1391,10 +1391,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);
@@ -1402,7 +1404,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),
@@ -1476,7 +1478,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);
@@ -3530,7 +3532,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");
@@ -3619,7 +3621,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, NULL, 0) ||
@@ -3636,7 +3638,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. */
@@ -3646,7 +3648,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,
@@ -3657,15 +3659,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 19e5acfa64c..92b5b6b5a21 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -176,7 +176,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
@@ -673,20 +673,26 @@ void LEX::start(THD *thd_arg)
this, thd_arg->lex, thd_arg->stmt_lex));
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();
- current_select_number= 1;
- select_lex.linkage= UNSPECIFIED_TYPE;
+ current_select_number= 0;
+ builtin_select.linkage= UNSPECIFIED_TYPE;
+ 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();
@@ -700,17 +706,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;
@@ -720,14 +726,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;
@@ -739,6 +745,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;
@@ -748,8 +756,8 @@ void LEX::start(THD *thd_arg)
name= null_clex_str;
event_parse_data= NULL;
profile_options= PROFILE_NONE;
- nest_level=0 ;
- select_lex.nest_level_base= &unit;
+ nest_level= 0;
+ builtin_select.nest_level_base= &unit;
allow_sum_func= 0;
in_sum_func= NULL;
@@ -773,6 +781,13 @@ void LEX::start(THD *thd_arg)
vers_conditions.empty();
is_lex_started= TRUE;
+
+ next_is_main= FALSE;
+ next_is_down= FALSE;
+
+ wild= 0;
+ exchange= 0;
+
DBUG_VOID_RETURN;
}
@@ -1308,7 +1323,8 @@ 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)
{
/*
@@ -1325,6 +1341,8 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd)
token= lex_one_token(yylval, thd);
lip->add_digest_token(token, yylval);
+ SELECT_LEX *curr_sel= thd->lex->current_select;
+
switch(token) {
case WITH:
/*
@@ -1375,8 +1393,16 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd)
}
break;
case VALUES:
- if (thd->lex->current_select->parsing_place == IN_UPDATE_ON_DUP_KEY ||
- thd->lex->current_select->parsing_place == IN_PART_FUNC)
+ if (curr_sel &&
+ (curr_sel->parsing_place == BEFORE_OPT_LIST ||
+ curr_sel->parsing_place == AFTER_LIST))
+ {
+ curr_sel->parsing_place= NO_MATTER;
+ break;
+ }
+ if (curr_sel &&
+ (curr_sel->parsing_place == IN_UPDATE_ON_DUP_KEY ||
+ curr_sel->parsing_place == IN_PART_FUNC))
return VALUE_SYM;
token= lex_one_token(yylval, thd);
lip->add_digest_token(token, yylval);
@@ -1391,6 +1417,43 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd)
lip->lookahead_token= token;
return VALUES;
}
+ case VALUE_SYM:
+ if (curr_sel &&
+ (curr_sel->parsing_place == BEFORE_OPT_LIST ||
+ curr_sel->parsing_place == AFTER_LIST))
+ {
+ curr_sel->parsing_place= NO_MATTER;
+ return VALUES;
+ }
+ break;
+ case PARTITION_SYM:
+ case SELECT_SYM:
+ case UNION_SYM:
+ if (curr_sel &&
+ (curr_sel->parsing_place == BEFORE_OPT_LIST ||
+ curr_sel->parsing_place == AFTER_LIST))
+ {
+ curr_sel->parsing_place= NO_MATTER;
+ }
+ break;
+ case left_paren:
+ if (!curr_sel ||
+ curr_sel->parsing_place != BEFORE_OPT_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;
+ curr_sel->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;
@@ -1888,7 +1951,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
@@ -1899,7 +1962,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();
@@ -2184,7 +2247,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;
}
@@ -2192,7 +2256,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;
@@ -2233,16 +2297,6 @@ void st_select_lex::init_query()
having_fix_field= 0;
context.select_lex= this;
context.init();
- /*
- Add the name resolution context of the current (sub)query to the
- stack of contexts for the whole query.
- TODO:
- push_context may return an error if there is no memory for a new
- element in the stack, however this method has no return value,
- 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);
cond_count= between_count= with_wild= 0;
max_equal_elems= 0;
ref_pointer_array.reset();
@@ -2297,6 +2351,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;
@@ -2357,6 +2412,23 @@ void st_select_lex_node::add_slave(st_select_lex_node *slave_arg)
}
}
+void st_select_lex_node::link_chain_down(st_select_lex_node *first)
+{
+ st_select_lex_node *last_node;
+ st_select_lex_node *node= first;
+ do
+ {
+ last_node= node;
+ node->master= this;
+ node= node->next;
+ } while (node);
+ if ((last_node->next= slave))
+ {
+ slave->prev= &last_node->next;
+ }
+ first->prev= &slave;
+ slave= first;
+}
/*
include on level down (but do not link)
@@ -2406,7 +2478,7 @@ void st_select_lex_node::fast_exclude()
// Remove slave structure
for (; slave; slave= slave->next)
slave->fast_exclude();
-
+
}
@@ -3083,6 +3155,7 @@ LEX::LEX()
gtid_domain_static_buffer,
initial_gtid_domain_buffer_size,
initial_gtid_domain_buffer_size, 0);
+ unit.slave= &builtin_select;
}
@@ -3109,12 +3182,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())
{
@@ -3131,12 +3204,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);
}
@@ -3489,7 +3562,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)
{
@@ -3545,12 +3618,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
@@ -3581,7 +3655,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;
@@ -3606,6 +3680,23 @@ 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++;
+ }
+ first->select_number= 1;
+ }
+}
+
/*
Link table back that was unlinked with unlink_first_table()
@@ -3631,10 +3722,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
}
}
}
@@ -3663,19 +3754,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();
}
}
@@ -4541,7 +4632,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";
}
@@ -4736,8 +4827,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);
@@ -5066,8 +5157,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);
@@ -5078,13 +5174,228 @@ 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_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
@@ -5107,13 +5418,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;// distinct 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;
@@ -5128,12 +5469,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);
@@ -5157,11 +5505,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);
+ sel->set_master_unit(last->master_unit());
+ DBUG_RETURN(sel);
+}
/**
Checks if we need finish "automatic brackets" mode
@@ -6559,7 +6959,6 @@ Item_param *LEX::add_placeholder(THD *thd, const LEX_CSTRING *name,
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
return NULL;
}
-
Query_fragment pos(thd, sphead, start, end);
Item_param *item= new (thd->mem_root) Item_param(thd, name,
pos.pos(), pos.length());
@@ -7416,6 +7815,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 != 0))
+ {
+ 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 != 0)
+ {
+ 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(0) ||
+ 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)
{
@@ -7469,10 +8018,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;
@@ -7757,3 +8306,221 @@ Item *Lex_trim_st::make_item_func_trim(THD *thd) const
make_item_func_trim_oracle(thd) :
make_item_func_trim_std(thd);
}
+
+
+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_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(builtin_select.first_inner_unit() == 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);
+
+ if (sel->tvc && !sel->next_select() &&
+ (sql_command == SQLCOM_INSERT_SELECT ||
+ sql_command == SQLCOM_REPLACE_SELECT))
+ {
+ DBUG_PRINT("info", ("'Usual' INSERT detected"));
+ many_values= sel->tvc->lists_of_values;
+ sel->options= sel->tvc->select_options;
+ sel->tvc= NULL;
+ if (sql_command == SQLCOM_INSERT_SELECT)
+ sql_command= SQLCOM_INSERT;
+ else
+ sql_command= SQLCOM_REPLACE;
+ }
+
+
+ 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 02c2ffb6a12..5c053022317 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -74,6 +74,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
@@ -193,6 +203,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
@@ -431,7 +442,7 @@ public:
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:
@@ -577,6 +588,7 @@ public:
{
return linkage == UNION_TYPE || linkage == INTERSECT_TYPE || linkage == EXCEPT_TYPE;
}
+ bool distinct;
bool no_table_names_allowed; /* used for global order by */
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
@@ -597,10 +609,29 @@ public:
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_chain_down(st_select_lex_node *first);
+ 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)
@@ -616,6 +647,22 @@ public:
st_select_lex_node *insert_chain_before(st_select_lex_node **ptr_pos_to_insert,
st_select_lex_node *end_chain_node);
void move_as_slave(st_select_lex_node *new_master);
+ 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,
@@ -625,6 +672,8 @@ public:
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();
};
@@ -670,9 +719,9 @@ public:
{
}
-
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,
@@ -759,7 +808,7 @@ public:
{
return reinterpret_cast<st_select_lex*>(slave);
}
- inline void set_with_clause(With_clause *with_cl);
+ void set_with_clause(With_clause *with_cl);
st_select_lex_unit* next_unit()
{
return reinterpret_cast<st_select_lex_unit*>(next);
@@ -801,6 +850,16 @@ public:
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;
@@ -922,6 +981,7 @@ public:
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;
@@ -1051,6 +1111,10 @@ public:
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;
@@ -1283,6 +1347,32 @@ public:
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;
@@ -2664,7 +2754,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 */
@@ -2774,6 +2865,9 @@ public:
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;
@@ -2813,6 +2907,8 @@ public:
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
@@ -2867,6 +2963,8 @@ public:
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;
/*
@@ -3068,20 +3166,24 @@ public:
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;
+ 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();
@@ -3119,14 +3221,90 @@ public:
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()
+ {
+ 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()
{
- context_stack.pop();
+ 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(LEX_CSTRING *to);
@@ -3160,9 +3338,8 @@ public:
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());
return TRUE;
}
return FALSE;
@@ -3731,6 +3908,7 @@ public:
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);
@@ -3739,7 +3917,6 @@ public:
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);
@@ -3748,6 +3925,31 @@ public:
return create_info.vers_info;
}
sp_package *get_sp_package() const;
+
+ bool make_select_in_brackets(SELECT_LEX* dummy_select,
+ SELECT_LEX *nselect, bool automatic);
+
+ 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 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 cfa92f170ab..c81a8203be9 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -390,10 +390,13 @@ int mysql_load(THD *thd, const 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 f85d25525d4..d2a4a7a1e9a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1999,10 +1999,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))
@@ -2565,23 +2565,24 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
DBUG_RETURN(1);
#else
{
- if (lex->select_lex.db.str == NULL &&
- lex->copy_db_to(&lex->select_lex.db))
+ if (lex->first_select_lex()->db.str == NULL &&
+ lex->copy_db_to(&lex->first_select_lex()->db))
{
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.str= thd->strdup(lex->select_lex.db.str);
- schema_select_lex->db= lex->select_lex.db;
+ lex->first_select_lex()->db.str=
+ thd->strdup(lex->first_select_lex()->db.str);
+ 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.
*/
- if (check_db_name((LEX_STRING*) &lex->select_lex.db))
+ if (check_db_name((LEX_STRING*) &lex->first_select_lex()->db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), lex->select_lex.db.str);
+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->first_select_lex()->db.str);
DBUG_RETURN(1);
}
break;
@@ -2620,7 +2621,8 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
default:
break;
}
-
+ if (schema_select_lex)
+ schema_select_lex->set_master_unit(&lex->unit);
SELECT_LEX *select_lex= lex->current_select;
if (make_schema_select(thd, select_lex, get_schema_table(schema_table_idx)))
DBUG_RETURN(1);
@@ -3217,7 +3219,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 */
@@ -3260,6 +3262,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 */
@@ -7530,7 +7533,7 @@ void THD::reset_for_next_command(bool do_clear_error)
We also assign stmt_lex in lex_start(), but during bootstrap this
code is executed first.
*/
- stmt_lex= &main_lex; stmt_lex->current_select_number= 1;
+ stmt_lex= &main_lex; stmt_lex->current_select_number= 0;
DBUG_PRINT("info", ("Lex %p stmt_lex: %p", lex, stmt_lex));
/*
Those two lines below are theoretically unneeded as
@@ -7617,11 +7620,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;
}
@@ -7642,6 +7641,7 @@ 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)
@@ -7653,27 +7653,19 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex)
select_lex->init_query();
select_lex->init_select();
}
- 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);
/*
@@ -7707,15 +7699,13 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex)
"SELECT ... PROCEDURE ANALYSE()");
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);
- // SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1; -- not possible
- 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=
@@ -7771,9 +7761,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;
}
@@ -8058,7 +8049,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();
}
@@ -8140,6 +8131,10 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
LEX_CSTRING alias_str;
LEX *lex= thd->lex;
DBUG_ENTER("add_table_to_list");
+ DBUG_PRINT("enter", ("Table '%s' (%p) Select %p (%u)",
+ (alias ? alias->str : table->table.str),
+ table,
+ this, select_number));
if (!table)
DBUG_RETURN(0); // End of memory
@@ -8233,7 +8228,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.
@@ -8339,7 +8334,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.str="(nested_join)";
@@ -8447,7 +8441,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);
}
@@ -8639,7 +8632,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()))
@@ -8649,16 +8642,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())
{
@@ -8671,7 +8667,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);
}
@@ -8707,7 +8703,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);
}
@@ -9062,7 +9058,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;
@@ -9161,7 +9157,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
{
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)
@@ -9197,7 +9193,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)
@@ -9231,7 +9227,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");
@@ -9348,7 +9344,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");
@@ -9390,7 +9386,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);
@@ -9481,7 +9478,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
@@ -9512,7 +9509,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");
@@ -10022,6 +10019,8 @@ bool parse_sql(THD *thd, Parser_state *parser_state,
((thd->variables.sql_mode & MODE_ORACLE) ?
ORAparse(thd) :
MYSQLparse(thd)) != 0;
+ DBUG_ASSERT(opt_bootstrap | mysql_parse_status || thd->lex->select_stack_top == 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 09c59c862ad..ef226526e8c 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -833,7 +833,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 6e176a40e6c..b4a42dd6bb2 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;
/*
@@ -735,7 +735,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 24f3cc66c6b..bdc817b7432 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1340,7 +1340,7 @@ static int mysql_test_update(Prepared_statement *stmt,
THD *thd= stmt->thd;
uint table_count= 0;
TABLE_LIST *update_source_table;
- SELECT_LEX *select= &stmt->lex->select_lex;
+ SELECT_LEX *select= stmt->lex->first_select_lex();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
uint want_privilege;
#endif
@@ -1396,10 +1396,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, NULL, 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
@@ -1464,10 +1464,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);
@@ -1499,7 +1499,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 (tables)
@@ -1533,7 +1533,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))
@@ -1691,7 +1691,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);
@@ -1759,7 +1759,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;
@@ -2079,7 +2079,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)))
{
@@ -2118,13 +2118,14 @@ error:
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);
}
@@ -2159,7 +2160,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=
@@ -2167,7 +2168,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;
}
@@ -2193,7 +2194,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
@@ -2202,7 +2203,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())
@@ -2241,7 +2242,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;
@@ -2250,10 +2251,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 */
@@ -2999,7 +3001,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)
@@ -4535,8 +4537,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 ba37d933f12..4de8b8c9961 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
@@ -356,6 +359,8 @@ enum enum_parsing_place
IN_ORDER_BY,
IN_UPDATE_ON_DUP_KEY,
IN_PART_FUNC,
+ BEFORE_OPT_LIST,
+ AFTER_LIST,
PARSING_PLACE_SIZE /* always should be the last */
};
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 13f03fed5f3..6ca21aebb37 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++)
@@ -402,7 +402,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 796ea569e64..8695d227b14 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -351,7 +351,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());
@@ -1388,13 +1388,14 @@ err:
bool JOIN::build_explain()
{
+ DBUG_ENTER("JOIN::build_explain");
create_explain_query_if_not_exists(thd->lex, thd->mem_root);
have_query_plan= QEP_AVAILABLE;
if (save_explain_data(thd->lex->explain, false /* can overwrite */,
need_tmp,
!skip_sort_order && !no_order && (order || group_list),
select_distinct))
- return 1;
+ DBUG_RETURN(1);
uint select_nr= select_lex->select_number;
JOIN_TAB *curr_tab= join_tab + exec_join_tab_cnt();
for (uint i= 0; i < aggr_tables; i++, curr_tab++)
@@ -1412,7 +1413,7 @@ bool JOIN::build_explain()
get_using_temporary_read_tracker();
}
}
- return 0;
+ DBUG_RETURN(0);
}
@@ -3678,6 +3679,15 @@ bool 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
@@ -3704,8 +3714,9 @@ bool JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
/* It's a degenerate join */
message= zero_result_cause ? zero_result_cause : "No tables used";
}
- return save_explain_data_intern(thd->lex->explain, need_tmp_table, need_order,
- distinct, message);
+ bool rc= save_explain_data_intern(thd->lex->explain, need_tmp_table,
+ need_order, distinct, message);
+ DBUG_RETURN(rc);
}
/*
@@ -3727,11 +3738,11 @@ bool JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
{
if (!(join_tab[i].filesort->tracker=
new Filesort_tracker(thd->lex->analyze_stmt)))
- return 1;
+ DBUG_RETURN(1);
}
}
}
- return 0;
+ DBUG_RETURN(0);
}
@@ -12574,7 +12585,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
@@ -18386,7 +18398,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))
@@ -24902,7 +24914,8 @@ bool 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)
@@ -25355,8 +25368,9 @@ int JOIN::save_explain_data_intern(Explain_query *output,
{
JOIN *join= this; /* Legacy: this code used to be a non-member function */
DBUG_ENTER("JOIN::save_explain_data_intern");
- DBUG_PRINT("info", ("Select %p, type %s, message %s",
- 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 */
@@ -26010,6 +26024,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 18f0028908f..1ee20785e9c 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.str,
- lex->select_lex.table_list.first->table_name.str, reason);
+ lex->first_select_lex()->table_list.first->db.str,
+ lex->first_select_lex()->table_list.first->table_name.str, reason);
DBUG_RETURN(TRUE);
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 38a13c49278..fb7a023e817 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -4144,8 +4144,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.str, lex->select_lex.db.length);
+ thd->make_lex_string(&lookup_field_values->db_value,
+ lex->first_select_lex()->db.str,
+ lex->first_select_lex()->db.length);
if (wild)
{
thd->make_lex_string(&lookup_field_values->table_value,
@@ -4538,10 +4539,10 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root,
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)
{
@@ -6746,7 +6747,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;
@@ -7725,7 +7726,8 @@ 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.str, wild))
+ if (!(open_list=list_open_tables(thd, thd->lex->first_select_lex()->db.str,
+ wild))
&& thd->is_fatal_error)
DBUG_RETURN(1);
@@ -8220,7 +8222,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= is_show_command(thd);
if (!(table= create_tmp_table(thd, tmp_table_param,
field_list, (ORDER*) 0, 0, 0,
@@ -8257,7 +8259,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)
@@ -8317,14 +8319,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(" ("));
@@ -8357,7 +8359,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++)
{
@@ -8388,7 +8390,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++)
{
@@ -8415,7 +8417,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 448d095c876..1322d86302e 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4890,7 +4890,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;
}
@@ -10237,8 +10237,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_truncate.cc b/sql/sql_truncate.cc
index 2ddb4bc042c..dabd88e90a4 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -489,7 +489,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 *table= thd->lex->select_lex.table_list.first;
+ TABLE_LIST *table= thd->lex->first_select_lex()->table_list.first;
DBUG_ENTER("Sql_cmd_truncate_table::execute");
if (check_one_table_access(thd, DROP_ACL, table))
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 0149c2848c2..5b84ec45dba 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1387,7 +1387,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 38638d3aa1d..8e7bbadf902 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -318,7 +318,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;
@@ -375,7 +375,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. */
@@ -1241,7 +1241,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
@@ -1518,7 +1518,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;
/*
@@ -1560,14 +1560,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(),
@@ -1590,13 +1591,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;
@@ -1689,7 +1691,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++))
@@ -1711,7 +1713,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);
@@ -1740,7 +1742,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 e910d48c75c..d1795f9c80f 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");
@@ -323,7 +323,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)
@@ -399,7 +401,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;
@@ -995,7 +997,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)
{
@@ -1114,8 +1116,8 @@ loop_out:
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))
@@ -1162,7 +1164,8 @@ err:
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();
@@ -1359,8 +1362,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->stmt_lex->current_select_number;
sql_mode_t saved_mode= thd->variables.sql_mode;
/* switch off modes which can prevent normal parsing of VIEW
@@ -1395,6 +1396,8 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
parse_status= parse_sql(thd, & parser_state, table->view_creation_ctx);
+ view_select= lex->first_select_lex();
+
/* Restore environment. */
if ((old_lex->sql_command == SQLCOM_SHOW_FIELDS) ||
@@ -1544,7 +1547,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
@@ -1572,7 +1575,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,
@@ -1594,8 +1597,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)
@@ -1677,9 +1680,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;
@@ -1690,12 +1694,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,
@@ -1730,7 +1735,11 @@ ok:
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;
@@ -1913,7 +1922,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 d69156ced9b..b5e3bb4f73d 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -511,6 +511,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.
@@ -518,28 +519,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
@@ -554,27 +555,24 @@ 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;
+ DBUG_RETURN(FALSE);
}
@@ -619,6 +617,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();
}
}
@@ -678,6 +677,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;
@@ -796,6 +798,20 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
uint offset;
} sp_cursor_name_and_offset;
vers_history_point_t vers_history_point;
+ 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;
@@ -841,6 +857,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;
@@ -849,7 +866,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;
@@ -888,10 +904,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
- Currently there are 139 shift/reduce conflicts.
+ Currently there are 135 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
-%expect 139
+%expect 135
/*
Comments for TOKENS.
@@ -1210,6 +1226,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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
@@ -1671,7 +1690,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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
@@ -1716,7 +1736,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
opt_temporary all_or_any opt_distinct opt_glimit_clause
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
@@ -1834,11 +1854,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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_simple_table
- derived_query_specification
- derived_table_value_constructor
+ derived_table_list table_reference_list_parens
+ nested_table_reference_list join_table_parens
%type <date_time_type> date_time_type;
%type <interval> interval
@@ -1876,14 +1893,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
UNDERSCORE_CHARSET
%type <select_lex> subselect
- get_select_lex get_select_lex_derived
- simple_table
query_specification
- query_term_union_not_ready
- query_term_union_ready
- query_expression_body
- select_paren_derived
table_value_constructor
+ simple_table
+ query_primary
+ query_primary_parens
+
+%type <select_lex_unit>
+ query_expression_body
+ query_expression
+ query_expression_unit
%type <boolfunc2creator> comp_op
@@ -1895,7 +1914,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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
@@ -1915,7 +1948,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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
@@ -1935,9 +1968,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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
@@ -2066,7 +2098,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;
@@ -2190,14 +2222,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
}
;
@@ -2216,10 +2256,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),
@@ -2227,7 +2278,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:
@@ -2512,15 +2567,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_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();
/*
@@ -2535,7 +2597,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)
{
@@ -2544,20 +2606,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;
/*
@@ -2580,8 +2645,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.str,
- lex->select_lex.table_list.first->table_name.str);
+ lex->builtin_select.table_list.first->db.str,
+ lex->builtin_select.table_list.first->table_name.str);
MYSQL_YYABORT;
}
@@ -2593,7 +2658,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)
{
@@ -2605,42 +2670,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
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
- | create_or_replace opt_unique INDEX_SYM opt_if_not_exists ident
+ 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
{
@@ -2648,58 +2740,104 @@ 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
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
Lex->create_info.set($1);
}
- sf_tail_not_aggregate
- { }
+ sf_tail
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace definer AGGREGATE_SYM FUNCTION_SYM
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
Lex->create_info.set($1);
+
}
sf_tail_aggregate
- { }
+ {
+ 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);
}
create_aggregate_function_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
{
@@ -3098,7 +3236,7 @@ clear_privileges:
lex->columns.empty();
lex->grant= lex->grant_tot_col= 0;
lex->all_privileges= 0;
- lex->select_lex.db= null_clex_str;
+ lex->builtin_select.db= null_clex_str;
lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
bzero((char *)&(lex->mqh),sizeof(lex->mqh));
@@ -3168,8 +3306,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 */
@@ -3586,10 +3729,16 @@ sp_hcond:
;
signal_stmt:
- SIGNAL_SYM signal_value opt_set_signal_information
+ SIGNAL_SYM
+ {
+ if (Lex->main_select_push())
+ YYABORT;
+ }
+ signal_value opt_set_signal_information
{
- if (Lex->add_signal_statement(thd, $2))
+ if (Lex->add_signal_statement(thd, $3))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -3715,9 +3864,14 @@ resignal_stmt:
;
get_diagnostics:
- GET_SYM which_area DIAGNOSTICS_SYM diagnostics_information
+ GET_SYM which_area DIAGNOSTICS_SYM
{
- Diagnostics_information *info= $4;
+ if (Lex->main_select_push())
+ YYABORT;
+ }
+ diagnostics_information
+ {
+ Diagnostics_information *info= $5;
info->set_which_da($2);
@@ -3726,6 +3880,7 @@ get_diagnostics:
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -3893,7 +4048,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;
+ }
;
/*
@@ -3995,10 +4159,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) ||
@@ -4036,6 +4205,8 @@ assignment_source_expr:
{
DBUG_ASSERT(thd->free_list == NULL);
Lex->sphead->reset_lex(thd, $1);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
@@ -4044,6 +4215,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;
}
@@ -4176,9 +4348,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;
@@ -4290,12 +4467,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;
}
@@ -4319,6 +4502,9 @@ simple_when_clause:
WHEN_SYM
{
Lex->sphead->reset_lex(thd); /* For expr $3 */
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
@@ -4327,6 +4513,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;
@@ -4343,12 +4531,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;
@@ -4497,6 +4690,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;
}
@@ -4509,7 +4703,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;
@@ -4520,6 +4719,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 */
@@ -4548,8 +4749,12 @@ sp_labeled_control:
if (Lex->sp_push_loop_label(thd, &$1))
MYSQL_YYABORT;
Lex->sphead->reset_lex(thd);
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
while_body pop_sp_loop_label
+
{ }
| sp_label FOR_SYM
{
@@ -4601,9 +4806,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);
}
| FOR_SYM
@@ -5030,25 +5239,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;
@@ -5059,7 +5258,7 @@ create_body:
create_like:
LIKE table_ident { $$= $2; }
- | '(' LIKE table_ident ')' { $$= $3; }
+ | LEFT_PAREN_LIKE LIKE table_ident ')' { $$= $3; }
;
opt_create_select:
@@ -5068,23 +5267,51 @@ opt_create_select:
;
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();
+
+ 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;
+ }
+ Lex->insert_select_hack(first_select);
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+
+ // fix "main" select
+ SELECT_LEX *blt= Lex->pop_select();
+ DBUG_ASSERT(blt == &Lex->builtin_select);
+ Lex->push_select(first_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);
+
+ 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;
+ }
+
+ Lex->insert_select_hack(first_select);
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+
+ // fix "main" select
+ SELECT_LEX *blt= Lex->pop_select();
+ DBUG_ASSERT(blt == &Lex->builtin_select);
+ Lex->push_select(first_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:
@@ -5170,13 +5397,17 @@ partition_entry:
thd->parse_error(ER_PARTITION_ENTRY_ERROR);
MYSQL_YYABORT;
}
- DBUG_ASSERT(Lex->part_info->table);
+ 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:
@@ -5898,56 +6129,6 @@ opt_versioning_interval_start:
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 {}
@@ -6165,7 +6346,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 ')'
{
@@ -6174,8 +6355,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
@@ -6376,6 +6557,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
@@ -6702,6 +6890,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
{
@@ -6709,13 +6899,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;
}
@@ -7636,22 +7842,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
@@ -7663,11 +7871,14 @@ alter:
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
{
@@ -7676,6 +7887,7 @@ alter:
lex->name= $3;
if (lex->name.str == NULL && lex->copy_db_to(&lex->name))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
| ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
{
@@ -7691,6 +7903,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
@@ -7699,6 +7913,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
{
@@ -7706,6 +7923,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
@@ -7714,14 +7933,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
@@ -7729,14 +7957,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
@@ -7768,6 +8004,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
{
@@ -7811,15 +8049,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
@@ -7828,6 +8068,9 @@ alter:
Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence($3);
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
;
@@ -7977,18 +8220,18 @@ alter_commands:
WITH TABLE_SYM table_ident have_partitioning
{
LEX *lex= thd->lex;
- lex->select_lex.db= $6->db;
- if (lex->select_lex.db.str == NULL &&
- lex->copy_db_to(&lex->select_lex.db))
+ lex->builtin_select.db=$6->db;
+ if (lex->builtin_select.db.str == NULL &&
+ lex->copy_db_to(&lex->builtin_select.db))
{
MYSQL_YYABORT;
}
lex->name= $6->table;
lex->alter_info.partition_flags|= ALTER_PARTITION_EXCHANGE;
- 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)
@@ -8233,9 +8476,9 @@ alter_list_item:
| RENAME opt_to table_ident
{
LEX *lex=Lex;
- lex->select_lex.db= $3->db;
- if (lex->select_lex.db.str == NULL &&
- lex->copy_db_to(&lex->select_lex.db))
+ lex->builtin_select.db= $3->db;
+ if (lex->builtin_select.db.str == NULL &&
+ lex->copy_db_to(&lex->builtin_select.db))
{
MYSQL_YYABORT;
}
@@ -8522,9 +8765,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:
@@ -8550,6 +8797,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
{
@@ -8558,6 +8807,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
}
;
@@ -8586,6 +8836,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();
@@ -8600,6 +8852,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
}
;
@@ -8716,6 +8969,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
{
@@ -8726,6 +8981,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
}
;
@@ -8763,6 +9019,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
{
@@ -8771,6 +9029,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
}
;
@@ -8784,9 +9043,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;
@@ -8880,9 +9143,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:
@@ -8925,8 +9192,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
@@ -8947,217 +9214,347 @@ opt_ignore_leaves:
Select : retrieve data from table
*/
-
select:
- opt_with_clause select_init
+ 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;
+
+ Lex->sql_command= SQLCOM_SELECT;
}
;
-select_init:
- SELECT_SYM select_options_and_item_list select_init3
- | table_value_constructor
- | table_value_constructor union_list
- | table_value_constructor union_order_or_limit
- | '(' 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
- | table_value_constructor
- | table_value_constructor union_list
- | table_value_constructor union_order_or_limit
- | '(' select_paren_union_query_term ')'
- | '(' select_paren_union_query_term ')' union_list
- | '(' select_paren_union_query_term ')' union_order_or_limit
+simple_table:
+ query_specification { $$= $1; }
+ | table_value_constructor { $$= $1; }
;
-
-select_paren:
+
+table_value_constructor:
+ VALUES
+ {
+ LEX *lex= Lex;
+ SELECT_LEX *sel;
+ //lex->field_list.empty();
+ lex->many_values.empty();
+ lex->insert_list=0;
+ if (!(sel= lex->alloc_select(TRUE)) ||
+ lex->push_select(sel))
+ MYSQL_YYABORT;
+ sel->init_select();
+ sel->braces= FALSE; // just initialisation
+ }
+ values_list
+ {
+ LEX *lex=Lex;
+ $$= lex->pop_select(); // above TVC select
+ if (!($$->tvc=
+ new (lex->thd->mem_root) table_value_constr(lex->many_values,
+ $$,
+ $$->options)))
+ MYSQL_YYABORT;
+ lex->many_values.empty();
+ }
+ ;
+
+query_specification:
+ SELECT_SYM
{
- Lex->current_select->set_braces(true);
+ SELECT_LEX *sel;
+ LEX *lex= Lex;
+ if (!(sel= lex->alloc_select(TRUE)) ||
+ lex->push_select(sel))
+ MYSQL_YYABORT;
+ sel->init_select();
+ sel->braces= FALSE;
}
- table_value_constructor
+ select_options
{
- DBUG_ASSERT(Lex->current_select->braces);
+ Select->parsing_place= SELECT_LIST;
}
- |
+ 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
- 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 ')'
;
-select_paren_union_query_term:
- {
- /*
- 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_union_query_term
- opt_select_lock_type
- {
- DBUG_ASSERT(Lex->current_select->braces);
- }
- | '(' select_paren_union_query_term ')'
+opt_from_clause:
+ /* Empty */
+ | from_clause
;
-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 ')'
+
+query_primary:
+ simple_table
+ { $$= $1; }
+ | query_primary_parens
+ { $$= $1; }
;
-/* The equivalent of select_paren for nested queries. */
-select_paren_derived:
+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);
}
- table_value_constructor
+ 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();
}
- |
+ | '(' query_primary
{
- Lex->current_select->set_braces(true);
+ Lex->push_select($2);
}
- 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();
+ $$= $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_paren_derived ')' { $$= $2; }
;
-select_init3:
- 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
- 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();
-select_init3_union_query_term:
- opt_table_expression
- opt_select_lock_type
- {
- /* Parentheses carry no meaning here */
- Lex->current_select->set_braces(false);
- }
- union_clause
- | select_part3_union_not_ready_noproc
- opt_select_lock_type
- {
- /* Parentheses carry no meaning here */
- Lex->current_select->set_braces(false);
+ 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();
}
;
@@ -9165,18 +9562,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
@@ -9274,59 +9659,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
@@ -11563,10 +11952,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);
}
;
@@ -11585,11 +11979,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;
@@ -11606,6 +12007,8 @@ join_table:
USING
{
MYSQL_YYABORT_UNLESS($1 && $3);
+ Select->add_joined_table($1);
+ Select->add_joined_table($3);
}
'(' using_list ')'
{
@@ -11616,6 +12019,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);
}
@@ -11625,6 +12030,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;
@@ -11641,6 +12048,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 ')'
{
@@ -11651,6 +12060,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;
@@ -11661,6 +12072,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;
@@ -11678,6 +12091,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 ')'
{
@@ -11689,6 +12104,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()))
@@ -11724,42 +12141,71 @@ use_partition:
}
;
-/*
- This is a flattening of the rules <table factor> and <table primary>
- in the SQL:2003 standard, since we don't have <sample clause>
-
- 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_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_for_system_time_clause
+ opt_table_alias_clause opt_key_definition
{
- DBUG_ASSERT(Select);
SELECT_LEX *sel= Select;
sel->table_join_options= 0;
- }
- table_ident opt_use_partition opt_for_system_time_clause opt_table_alias opt_key_definition
- {
- if (!($$= Select->add_table_to_list(thd, $2, $5,
+ if (!($$= Select->add_table_to_list(thd, $1, $4,
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($$);
- if ($4)
+ if ($3)
$$->vers_conditions= Lex->vers_conditions;
}
;
-
/*
Represents a flattening of the following rules from the SQL:2003
standard. This sub-rule corresponds to the sub-rule
@@ -11777,289 +12223,66 @@ table_primary_ident:
*/
table_primary_derived:
- '(' get_select_lex select_derived_union ')' opt_for_system_time_clause opt_table_alias
+ query_primary_parens opt_for_system_time_clause table_alias_clause
{
- /* Use $2 instead of Lex->current_select as derived table will
- alter value of Lex->current_select. */
- if (!($3 || $6) && $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, $6, 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 ($6 != 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());
- if ($5)
- {
- MYSQL_YYABORT_UNLESS(!$3);
- $$->vers_conditions= Lex->vers_conditions;
- }
- }
- /* Represents derived table with WITH clause */
- | '(' get_select_lex subselect_start
- with_clause query_expression_body
- subselect_end ')' opt_for_system_time_clause 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, $9, 0,
- TL_READ, MDL_SHARED_READ)))
+ if (!($$= curr_sel->add_table_to_list(lex->thd,
+ ti, $3, 0,
+ TL_READ, MDL_SHARED_READ)))
MYSQL_YYABORT;
- sel->add_joined_table($$);
- if ($8)
- $$->vers_conditions= Lex->vers_conditions;
- }
- ;
-
-/*
- 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)
+ if ($2)
{
- thd->parse_error();
- MYSQL_YYABORT;
+ $$->vers_conditions= Lex->vers_conditions;
}
}
- union_list_derived_part2
- | derived_simple_table opt_select_lock_type
- | derived_simple_table order_or_limit opt_select_lock_type
- | derived_simple_table 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
+ ')' opt_for_system_time_clause 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;
- }
- }
- ;
-derived_simple_table:
- derived_query_specification { $$= $1; }
- | derived_table_value_constructor { $$= $1; }
- ;
-/*
- 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);
-derived_table_value_constructor:
- VALUES
- {
- LEX *lex=Lex;
- lex->field_list.empty();
- lex->many_values.empty();
- lex->insert_list=0;
- }
- values_list
- {
- 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, $5, 0,
+ TL_READ, MDL_SHARED_READ)))
MYSQL_YYABORT;
- mysql_init_select(lex);
- lex->current_select->linkage= DERIVED_TABLE_TYPE;
-
- if (!(lex->current_select->tvc=
- new (lex->thd->mem_root) table_value_constr(lex->many_values,
- lex->current_select,
- lex->current_select->options)))
- MYSQL_YYABORT;
- lex->many_values.empty();
- $$= NULL;
- }
- ;
-
-
-select_derived2:
- {
- LEX *lex= Lex;
- lex->derived_tables|= DERIVED_SUBQUERY;
- if (!lex->expr_allows_subselect ||
- lex->sql_command == (int)SQLCOM_PURGE)
+ if ($4)
{
- thd->parse_error();
- MYSQL_YYABORT;
+ $$->vers_conditions= Lex->vers_conditions;
}
- if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE ||
- mysql_new_select(lex, 1, NULL))
- 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 */ {}
@@ -12190,9 +12413,14 @@ table_alias:
| '='
;
-opt_table_alias:
+opt_table_alias_clause:
/* empty */ { $$=0; }
- | table_alias ident_table_alias
+
+ | table_alias_clause { $$= $1; }
+ ;
+
+table_alias_clause:
+ table_alias ident_table_alias
{
$$= (LEX_CSTRING*) thd->memdup(&$2,sizeof(LEX_STRING));
if ($$ == NULL)
@@ -12359,7 +12587,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:
@@ -12483,64 +12711,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;
- }
+ 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:
@@ -12550,63 +12749,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;
}
;
@@ -12675,6 +12872,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 */
| '+'
@@ -12744,14 +13001,11 @@ 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);
-
lex->proc_list.elements=0;
lex->proc_list.first=0;
lex->proc_list.next= &lex->proc_list.first;
@@ -12771,6 +13025,7 @@ procedure_clause:
parameters are reduced.
*/
Lex->expr_allows_subselect= false;
+ Select->options|= OPTION_PROCEDURE_CLAUSE;
}
'(' procedure_list ')'
{
@@ -12851,8 +13106,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:
@@ -12898,10 +13166,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;
}
;
@@ -13118,16 +13391,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_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:
@@ -13136,15 +13416,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_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:
@@ -13190,35 +13477,47 @@ insert_table:
table_name_with_opt_use_partition
{
LEX *lex=Lex;
- lex->field_list.empty();
+ //lex->field_list.empty();
lex->many_values.empty();
lex->insert_list=0;
};
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 ')'
+ {
+ Lex->current_select->parsing_place= AFTER_LIST;
+ }
+ ;
+
+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 {}
- | create_select_query_expression {}
+ create_select_query_expression {}
;
values_list:
@@ -13328,6 +13627,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;
@@ -13336,13 +13637,14 @@ 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.str, "UPDATE");
+ lex->builtin_select.get_table_list()->alias.str,
+ "UPDATE");
MYSQL_YYABORT;
}
/*
@@ -13352,7 +13654,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:
@@ -13398,9 +13707,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();
}
delete_part2
;
@@ -13421,6 +13732,7 @@ delete_part2:
| HISTORY_SYM delete_single_table opt_delete_system_time
{
Lex->last_table()->vers_conditions= Lex->vers_conditions;
+ Lex->pop_select(); //main select
}
;
@@ -13443,9 +13755,18 @@ single_multi:
opt_where_clause
opt_order_clause
delete_limit_clause
- opt_select_expressions {}
+ opt_select_expressions
+ {
+ if ($3)
+ Select->order_list= *($3);
+ Lex->pop_select(); //main select
+ }
| table_wild_list
{
+ /* XXX
+ 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;
@@ -13454,9 +13775,16 @@ 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
{
+ /* XXX
+ 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;
@@ -13465,6 +13793,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;
}
;
@@ -13528,10 +13859,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;
}
@@ -13542,6 +13875,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
}
;
@@ -13616,6 +13950,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();
@@ -13623,6 +13959,7 @@ show:
show_param
{
Select->parsing_place= NO_MATTER;
+ Lex->pop_select(); //main select
}
;
@@ -13638,7 +13975,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLES;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES))
MYSQL_YYABORT;
}
@@ -13646,7 +13983,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TRIGGERS;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS))
MYSQL_YYABORT;
}
@@ -13654,7 +13991,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_EVENTS;
- lex->select_lex.db= $2;
+ lex->first_select_lex()->db= $2;
if (prepare_schema_table(thd, lex, 0, SCH_EVENTS))
MYSQL_YYABORT;
}
@@ -13662,7 +13999,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLES))
MYSQL_YYABORT;
}
@@ -13670,7 +14007,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES))
MYSQL_YYABORT;
}
@@ -13720,12 +14057,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;
@@ -13767,13 +14105,13 @@ show_param:
LEX_CSTRING var= {STRING_WITH_LEN("error_count")};
(void) create_select_for_variable(thd, &var);
}
- | WARNINGS opt_limit_clause
+ | WARNINGS opt_global_limit_clause
{ Lex->sql_command = SQLCOM_SHOW_WARNS;}
- | ERRORS opt_limit_clause
+ | 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;
@@ -13834,7 +14172,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;
}
@@ -13842,7 +14180,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;
}
@@ -13850,7 +14188,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;
}
@@ -14066,7 +14404,7 @@ describe:
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
lex->sql_command= SQLCOM_SHOW_FIELDS;
- lex->select_lex.db= null_clex_str;
+ lex->builtin_select.db= null_clex_str;
lex->verbose= 0;
if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS))
MYSQL_YYABORT;
@@ -14080,7 +14418,7 @@ describe:
explainable_command
{
LEX *lex=Lex;
- lex->select_lex.options|= SELECT_DESCRIBE;
+ lex->first_select_lex()->options|= SELECT_DESCRIBE;
}
;
@@ -14106,6 +14444,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 {}
;
@@ -14148,8 +14488,7 @@ flush:
lex->type= 0;
lex->no_write_to_binlog= $2;
}
- flush_options
- {}
+ flush_options {}
;
flush_options:
@@ -14166,6 +14505,7 @@ flush_options:
opt_table_list opt_flush_lock
{}
| flush_options_list
+ {}
;
opt_flush_lock:
@@ -14339,9 +14679,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:
@@ -14359,6 +14703,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;
}
;
@@ -14368,6 +14714,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;
@@ -14376,6 +14724,7 @@ kill:
kill_type kill_option kill_expr
{
Lex->kill_signal= (killed_state) ($3 | $4);
+ Lex->pop_select(); //main select
}
;
@@ -14419,7 +14768,7 @@ use:
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_CHANGE_DB;
- lex->select_lex.db= $2;
+ lex->builtin_select.db= $2;
}
;
@@ -14436,6 +14785,9 @@ load:
$2 == FILETYPE_CSV ? "LOAD DATA" : "LOAD XML");
MYSQL_YYABORT;
}
+ if (lex->main_select_push())
+ MYSQL_YYABORT;
+ mysql_init_select(lex);
}
load_data_lock opt_local INFILE TEXT_STRING_filesystem
{
@@ -14462,7 +14814,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:
@@ -14854,17 +15210,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_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();
@@ -14893,9 +15253,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))
@@ -15775,14 +16135,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
@@ -15792,6 +16160,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
{}
@@ -16173,9 +16544,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:
@@ -16206,7 +16581,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);
@@ -16240,9 +16615,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
+ }
;
/*
@@ -16250,25 +16629,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)
@@ -16276,20 +16666,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");
@@ -16920,219 +17314,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();
- }
- ;
+ { $$.unit_type= EXCEPT_TYPE; $$.distinct= 1; }
-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= "";
- }
- ;
-
-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; }
;
-simple_table:
- query_specification { $$= $1; }
- | table_value_constructor { $$= $1; }
- ;
-
-table_value_constructor:
- VALUES
- {
- LEX *lex=Lex;
- lex->field_list.empty();
- lex->many_values.empty();
- lex->insert_list=0;
- }
- values_list
- {
- LEX *lex=Lex;
- $$= lex->current_select;
- mysql_init_select(Lex);
- if (!($$->tvc=
- new (lex->thd->mem_root) table_value_constr(lex->many_values, $$, $$->options)))
- MYSQL_YYABORT;
- lex->many_values.empty();
- }
- ;
-
-/*
- 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:
- simple_table order_or_limit opt_select_lock_type { $$= $1; }
- | '(' select_paren_derived ')' union_order_or_limit { $$= $2; }
- ;
-
-query_term_union_ready:
- simple_table 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;
@@ -17140,18 +17342,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; }
;
@@ -17239,35 +17431,28 @@ 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;
+ 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;
+ size_t not_used;
trim_whitespace(thd->charset(),
- &lex->create_view->select);
- lex->create_view->check= $4;
+ &lex->create_view->select, &not_used);
+ lex->create_view->check= $3;
lex->parsing_options.allows_variable= TRUE;
- lex->current_select->set_with_clause($2);
}
;
-/*
- 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
- | table_value_constructor
- | table_value_constructor union_order_or_limit
- | table_value_constructor union_list_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; }
@@ -17371,11 +17556,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 ec2aeeaefba..7dd065d59ab 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -186,6 +186,20 @@ void ORAerror(THD *thd, const char *s)
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;
@@ -231,6 +245,7 @@ void ORAerror(THD *thd, const char *s)
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;
@@ -240,7 +255,6 @@ void ORAerror(THD *thd, const char *s)
/* enums */
enum enum_sp_suid_behaviour sp_suid;
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;
@@ -277,10 +291,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
- Currently there are 104 shift/reduce conflicts.
+ Currently there are 99 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
-%expect 104
+%expect 99
/*
Comments for TOKENS.
@@ -599,6 +613,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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
@@ -1063,7 +1080,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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
@@ -1111,7 +1129,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
opt_temporary all_or_any opt_distinct opt_glimit_clause
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
@@ -1231,9 +1249,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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
@@ -1276,12 +1293,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
UNDERSCORE_CHARSET
%type <select_lex> subselect
- get_select_lex get_select_lex_derived
query_specification
- query_term_union_not_ready
- query_term_union_ready
+ table_value_constructor
+ simple_table
+ query_primary
+ query_primary_parens
+
+%type <select_lex_unit>
query_expression_body
- select_paren_derived
+ query_expression
+ query_expression_unit
%type <boolfunc2creator> comp_op
@@ -1293,7 +1314,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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
@@ -1313,7 +1348,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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
@@ -1333,9 +1368,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *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
@@ -1481,7 +1515,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;
@@ -1606,14 +1640,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
}
;
@@ -1632,10 +1674,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),
@@ -1643,7 +1696,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:
@@ -1928,15 +1985,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_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();
/*
@@ -1951,7 +2015,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)
{
@@ -1960,20 +2024,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;
/*
@@ -1996,8 +2063,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.str,
- lex->select_lex.table_list.first->table_name.str);
+ lex->builtin_select.table_list.first->db.str,
+ lex->builtin_select.table_list.first->table_name.str);
MYSQL_YYABORT;
}
@@ -2009,7 +2076,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)
{
@@ -2021,42 +2088,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
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
- | create_or_replace opt_unique INDEX_SYM opt_if_not_exists ident
+ 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
{
@@ -2064,51 +2158,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->main_select_push())
+ MYSQL_YYABORT;
if (Lex->add_create_view(thd, $1 | $6, $2, $4, $7))
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_standalone
- { }
+ {
+ 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_standalone
- { }
+ {
+ 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
{
@@ -2724,7 +2861,7 @@ clear_privileges:
lex->columns.empty();
lex->grant= lex->grant_tot_col= 0;
lex->all_privileges= 0;
- lex->select_lex.db= null_clex_str;
+ lex->builtin_select.db= null_clex_str;
lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
bzero((char *)&(lex->mqh),sizeof(lex->mqh));
@@ -2815,8 +2952,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 */
@@ -3346,10 +3488,16 @@ raise_stmt:
;
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
}
;
@@ -3475,9 +3623,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);
@@ -3486,6 +3639,7 @@ get_diagnostics:
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -3666,8 +3820,26 @@ sp_decl_idents:
sp_opt_default:
/* Empty */ { $$ = NULL; }
- | DEFAULT expr { $$ = $2; }
- | SET_VAR expr { $$ = $2; }
+ | DEFAULT
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ expr
+ {
+ Lex->pop_select(); //main select
+ $$ = $3;
+ }
+ | SET_VAR
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ expr
+ {
+ Lex->pop_select(); //main select
+ $$ = $3;
+ }
;
sp_proc_stmt:
@@ -3784,10 +3956,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) ||
@@ -3804,7 +3981,14 @@ sp_proc_stmt_return:
;
reset_lex_expr:
- { Lex->sphead->reset_lex(thd); } expr { $$= $2; }
+ {
+ Lex->sphead->reset_lex(thd);
+ // will be poped in sp_proc_stmt_exit or sp_proc_stmt_continue
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ expr
+ { $$= $2; }
;
sp_proc_stmt_exit:
@@ -3820,12 +4004,14 @@ sp_proc_stmt_exit:
}
| EXIT_SYM WHEN_SYM reset_lex_expr
{
+ Lex->pop_select(); //main select pushed in reset_lex_expr
if (Lex->sp_exit_statement(thd, $3) ||
Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
| EXIT_SYM label_ident WHEN_SYM reset_lex_expr
{
+ Lex->pop_select(); //main select pushed in reset_lex_expr
if (Lex->sp_exit_statement(thd, &$2, $4) ||
Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -3845,12 +4031,14 @@ sp_proc_stmt_continue:
}
| CONTINUE_SYM WHEN_SYM reset_lex_expr
{
+ Lex->pop_select(); //main select pushed in reset_lex_expr
if (Lex->sp_continue_statement(thd, $3) ||
Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
| CONTINUE_SYM label_ident WHEN_SYM reset_lex_expr
{
+ Lex->pop_select(); //main select pushed in reset_lex_expr
if (Lex->sp_continue_statement(thd, &$2, $4) ||
Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -3902,6 +4090,8 @@ assignment_source_expr:
{
DBUG_ASSERT(thd->free_list == NULL);
Lex->sphead->reset_lex(thd, $1);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
@@ -3910,6 +4100,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;
}
@@ -4030,9 +4221,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;
@@ -4144,12 +4340,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;
}
@@ -4173,6 +4375,9 @@ simple_when_clause:
WHEN_SYM
{
Lex->sphead->reset_lex(thd); /* For expr $3 */
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
@@ -4181,6 +4386,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;
@@ -4197,12 +4404,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;
@@ -4442,6 +4654,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;
}
@@ -4454,7 +4667,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;
@@ -4465,6 +4683,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 */
@@ -4493,8 +4713,12 @@ sp_labeled_control:
if (Lex->sp_push_loop_label(thd, &$1))
MYSQL_YYABORT;
Lex->sphead->reset_lex(thd);
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
while_body pop_sp_loop_label
+
{ }
| labels_declaration_oracle FOR_SYM
{
@@ -4546,9 +4770,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);
}
| FOR_SYM
@@ -4981,25 +5209,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;
@@ -5010,7 +5228,7 @@ create_body:
create_like:
LIKE table_ident { $$= $2; }
- | '(' LIKE table_ident ')' { $$= $3; }
+ | LEFT_PAREN_LIKE LIKE table_ident ')' { $$= $3; }
;
opt_create_select:
@@ -5019,23 +5237,51 @@ opt_create_select:
;
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();
+
+ 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;
+ }
+ Lex->insert_select_hack(first_select);
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+
+ // fix "main" select
+ SELECT_LEX *blt= Lex->pop_select();
+ DBUG_ASSERT(blt == &Lex->builtin_select);
+ Lex->push_select(first_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);
+
+ 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;
+ }
+
+ Lex->insert_select_hack(first_select);
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+
+ // fix "main" select
+ SELECT_LEX *blt= Lex->pop_select();
+ DBUG_ASSERT(blt == &Lex->builtin_select);
+ Lex->push_select(first_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:
@@ -5126,8 +5372,13 @@ partition_entry:
We enter here when opening the frm file to translate
partition info string into part_info data structure.
*/
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ partition
+ {
+ Lex->pop_select(); //main select
}
- partition {}
;
partition:
@@ -5742,56 +5993,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 {}
@@ -6009,7 +6210,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 ')'
{
@@ -6018,8 +6219,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
@@ -6195,6 +6396,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
@@ -6462,6 +6670,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
{
@@ -6469,13 +6679,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;
}
@@ -7468,22 +7694,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,
- 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
@@ -7495,11 +7723,14 @@ alter:
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
{
@@ -7508,6 +7739,7 @@ alter:
lex->name= $3;
if (lex->name.str == NULL && lex->copy_db_to(&lex->name))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
| ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
{
@@ -7523,6 +7755,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
@@ -7531,6 +7765,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
{
@@ -7538,6 +7775,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
@@ -7546,14 +7785,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
@@ -7561,14 +7809,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
@@ -7600,6 +7856,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
{
@@ -7643,15 +7901,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
@@ -7660,6 +7920,9 @@ alter:
Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence($3);
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
;
@@ -7809,18 +8072,17 @@ alter_commands:
WITH TABLE_SYM table_ident have_partitioning
{
LEX *lex= thd->lex;
- lex->select_lex.db= $6->db;
- if (lex->select_lex.db.str == NULL &&
- lex->copy_db_to(&lex->select_lex.db))
+ if (lex->builtin_select.db.str == NULL &&
+ lex->copy_db_to(&lex->builtin_select.db))
{
MYSQL_YYABORT;
}
lex->name= $6->table;
lex->alter_info.partition_flags|= ALTER_PARTITION_EXCHANGE;
- 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)
@@ -8061,9 +8323,9 @@ alter_list_item:
| RENAME opt_to table_ident
{
LEX *lex=Lex;
- lex->select_lex.db= $3->db;
- if (lex->select_lex.db.str == NULL &&
- lex->copy_db_to(&lex->select_lex.db))
+ lex->builtin_select.db= $3->db;
+ if (lex->builtin_select.db.str == NULL &&
+ lex->copy_db_to(&lex->builtin_select.db))
{
MYSQL_YYABORT;
}
@@ -8337,9 +8599,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:
@@ -8365,6 +8631,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
{
@@ -8373,6 +8641,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
}
;
@@ -8401,6 +8670,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();
@@ -8415,6 +8686,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
}
;
@@ -8531,6 +8803,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
{
@@ -8541,6 +8815,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
}
;
@@ -8578,6 +8853,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
{
@@ -8586,6 +8863,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
}
;
@@ -8599,9 +8877,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;
@@ -8695,9 +8977,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:
@@ -8740,8 +9026,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
@@ -8764,192 +9050,345 @@ opt_ignore_leaves:
select:
- opt_with_clause select_init
+ 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;
+
+ Lex->sql_command= SQLCOM_SELECT;
}
;
-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
+simple_table:
+ query_specification { $$= $1; }
+ | table_value_constructor { $$= $1; }
;
-
-select_paren:
+
+table_value_constructor:
+ VALUES
+ {
+ LEX *lex= Lex;
+ SELECT_LEX *sel;
+ //lex->field_list.empty();
+ lex->many_values.empty();
+ lex->insert_list=0;
+ if (!(sel= lex->alloc_select(TRUE)) ||
+ lex->push_select(sel))
+ MYSQL_YYABORT;
+ sel->init_select();
+ sel->braces= FALSE; // just initialisation
+ }
+ values_list
+ {
+ LEX *lex=Lex;
+ $$= lex->pop_select(); // above TVC select
+ if (!($$->tvc=
+ new (lex->thd->mem_root) table_value_constr(lex->many_values,
+ $$,
+ $$->options)))
+ MYSQL_YYABORT;
+ lex->many_values.empty();
+ }
+ ;
+
+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 (!(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
+ ;
+
+query_primary:
+ simple_table
+ { $$= $1; }
+ | query_primary_parens
+ { $$= $1; }
;
-/* The equivalent of select_paren for nested queries. */
-select_paren_derived:
+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();
}
;
@@ -8957,18 +9396,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
@@ -9006,59 +9433,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
@@ -11362,10 +11793,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);
}
;
@@ -11384,11 +11820,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;
@@ -11405,6 +11848,8 @@ join_table:
USING
{
MYSQL_YYABORT_UNLESS($1 && $3);
+ Select->add_joined_table($1);
+ Select->add_joined_table($3);
}
'(' using_list ')'
{
@@ -11415,6 +11860,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);
}
@@ -11424,6 +11871,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;
@@ -11440,6 +11889,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 ')'
{
@@ -11450,6 +11901,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;
@@ -11460,6 +11913,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;
@@ -11477,6 +11932,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 ')'
{
@@ -11488,6 +11945,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()))
@@ -11522,40 +11981,70 @@ use_partition:
$$= $3;
}
;
-
-/*
- This is a flattening of the rules <table factor> and <table primary>
- in the SQL:2003 standard, since we don't have <sample clause>
- 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_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
@@ -11573,241 +12062,55 @@ 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 */
}
;
@@ -11940,9 +12243,14 @@ 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)
@@ -12109,7 +12417,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:
@@ -12233,64 +12541,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;
- }
+ 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:
@@ -12300,63 +12579,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;
}
;
@@ -12425,6 +12702,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 */
| '+'
@@ -12494,14 +12831,11 @@ 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);
-
lex->proc_list.elements=0;
lex->proc_list.first=0;
lex->proc_list.next= &lex->proc_list.first;
@@ -12521,6 +12855,7 @@ procedure_clause:
parameters are reduced.
*/
Lex->expr_allows_subselect= false;
+ Select->options|= OPTION_PROCEDURE_CLAUSE;
}
'(' procedure_list ')'
{
@@ -12601,8 +12936,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:
@@ -12648,10 +12996,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;
}
;
@@ -12883,17 +13236,24 @@ insert:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_INSERT;
- lex->duplicates= DUP_ERROR;
- mysql_init_select(lex);
+ lex->duplicates= DUP_ERROR;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ mysql_init_select(lex);
+ lex->current_select->parsing_place= BEFORE_OPT_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:
@@ -12902,15 +13262,22 @@ replace:
LEX *lex=Lex;
lex->sql_command = SQLCOM_REPLACE;
lex->duplicates= DUP_REPLACE;
- mysql_init_select(lex);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ mysql_init_select(lex);
+ lex->current_select->parsing_place= BEFORE_OPT_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:
@@ -12956,35 +13323,47 @@ insert_table:
table_name_with_opt_use_partition
{
LEX *lex=Lex;
- lex->field_list.empty();
+ //lex->field_list.empty();
lex->many_values.empty();
lex->insert_list=0;
};
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 ')'
+ {
+ Lex->current_select->parsing_place= AFTER_LIST;
+ }
+ ;
+
+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 {}
- | create_select_query_expression {}
+ create_select_query_expression {}
;
values_list:
@@ -13094,6 +13473,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;
@@ -13102,13 +13483,14 @@ 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.str, "UPDATE");
+ lex->builtin_select.get_table_list()->alias.str,
+ "UPDATE");
MYSQL_YYABORT;
}
/*
@@ -13118,7 +13500,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:
@@ -13164,9 +13553,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
;
@@ -13185,7 +13576,12 @@ 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
{
mysql_init_multi_delete(Lex);
@@ -13196,6 +13592,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;
}
| FROM table_alias_ref_list
{
@@ -13207,6 +13606,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;
}
;
@@ -13270,10 +13672,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;
}
@@ -13284,6 +13688,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
}
opt_truncate_table_storage_clause { }
;
@@ -13365,6 +13770,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();
@@ -13372,6 +13779,7 @@ show:
show_param
{
Select->parsing_place= NO_MATTER;
+ Lex->pop_select(); //main select
}
;
@@ -13387,7 +13795,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLES;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES))
MYSQL_YYABORT;
}
@@ -13395,7 +13803,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TRIGGERS;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS))
MYSQL_YYABORT;
}
@@ -13403,7 +13811,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_EVENTS;
- lex->select_lex.db= $2;
+ lex->first_select_lex()->db= $2;
if (prepare_schema_table(thd, lex, 0, SCH_EVENTS))
MYSQL_YYABORT;
}
@@ -13411,7 +13819,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLES))
MYSQL_YYABORT;
}
@@ -13419,7 +13827,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES))
MYSQL_YYABORT;
}
@@ -13469,12 +13877,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;
@@ -13516,13 +13925,13 @@ show_param:
LEX_CSTRING var= {STRING_WITH_LEN("error_count")};
(void) create_select_for_variable(thd, &var);
}
- | WARNINGS opt_limit_clause
+ | WARNINGS opt_global_limit_clause
{ Lex->sql_command = SQLCOM_SHOW_WARNS;}
- | ERRORS opt_limit_clause
+ | 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;
@@ -13583,7 +13992,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;
}
@@ -13591,7 +14000,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;
}
@@ -13599,7 +14008,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;
}
@@ -13815,7 +14224,7 @@ describe:
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
lex->sql_command= SQLCOM_SHOW_FIELDS;
- lex->select_lex.db= null_clex_str;
+ lex->builtin_select.db= null_clex_str;
lex->verbose= 0;
if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS))
MYSQL_YYABORT;
@@ -13829,7 +14238,7 @@ describe:
explainable_command
{
LEX *lex=Lex;
- lex->select_lex.options|= SELECT_DESCRIBE;
+ lex->first_select_lex()->options|= SELECT_DESCRIBE;
}
;
@@ -13855,6 +14264,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 {}
;
@@ -13897,8 +14308,7 @@ flush:
lex->type= 0;
lex->no_write_to_binlog= $2;
}
- flush_options
- {}
+ flush_options {}
;
flush_options:
@@ -13915,6 +14325,7 @@ flush_options:
opt_table_list opt_flush_lock
{}
| flush_options_list
+ {}
;
opt_flush_lock:
@@ -14070,9 +14481,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:
@@ -14090,6 +14505,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;
}
;
@@ -14099,6 +14516,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;
@@ -14107,6 +14526,7 @@ kill:
kill_type kill_option kill_expr
{
Lex->kill_signal= (killed_state) ($3 | $4);
+ Lex->pop_select(); //main select
}
;
@@ -14150,7 +14570,7 @@ use:
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_CHANGE_DB;
- lex->select_lex.db= $2;
+ lex->builtin_select.db= $2;
}
;
@@ -14167,6 +14587,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
{
@@ -14193,7 +14615,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:
@@ -14597,17 +15023,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_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();
@@ -14636,9 +15066,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))
@@ -15589,14 +16019,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
@@ -15606,6 +16044,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
{}
@@ -16038,9 +16479,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:
@@ -16071,7 +16516,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);
@@ -16105,9 +16550,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
+ }
;
/*
@@ -16115,25 +16564,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)
@@ -16141,20 +16601,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");
@@ -16800,83 +17264,16 @@ 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= "";
- }
- ;
-
-order_or_limit:
- order_clause opt_limit_clause
- | limit_clause
- ;
+ { $$.unit_type= EXCEPT_TYPE; $$.distinct= 1; }
/*
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; }
@@ -16884,110 +17281,10 @@ union_option:
| 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;
@@ -16996,18 +17293,8 @@ query_expression_option:
| UNIQUE_SYM { 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; }
;
@@ -17095,32 +17382,28 @@ 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;
+ 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;
+ size_t not_used;
trim_whitespace(thd->charset(),
- &lex->create_view->select);
- lex->create_view->check= $4;
+ &lex->create_view->select, &not_used);
+ lex->create_view->check= $3;
lex->parsing_options.allows_variable= TRUE;
- lex->current_select->set_with_clause($2);
}
;
-/*
- 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; }
@@ -17221,11 +17504,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 01d99517fed..19c2405e75d 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -759,6 +759,59 @@ 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);
+};
+
class Load_data_param
{
diff --git a/sql/table.cc b/sql/table.cc
index 577ed20a87e..ce9e2365011 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2689,7 +2689,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())
@@ -4938,13 +4938,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;
@@ -4981,7 +4981,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)
{
@@ -5023,7 +5024,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 */
@@ -5145,7 +5146,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)
{
@@ -5316,7 +5317,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))
@@ -5483,7 +5485,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);
@@ -5675,6 +5677,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);
}
@@ -5691,14 +5694,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 (;;)
{
@@ -5869,7 +5872,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");
@@ -5900,8 +5903,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.str,
name, view));
@@ -8618,7 +8622,7 @@ bool TR_table::query(ulonglong trx_id)
READ_RECORD info;
int error;
List<TABLE_LIST> dummy;
- SELECT_LEX &slex= thd->lex->select_lex;
+ SELECT_LEX &slex= *(thd->lex->first_select_lex());
Name_resolution_context_backup backup(slex.context, *this);
Item *field= newx Item_field(thd, &slex.context, (*this)[FLD_TRX_ID]);
Item *value= newx Item_int(thd, trx_id);
@@ -8648,7 +8652,7 @@ bool TR_table::query(MYSQL_TIME &commit_time, bool backwards)
READ_RECORD info;
int error;
List<TABLE_LIST> dummy;
- SELECT_LEX &slex= thd->lex->select_lex;
+ SELECT_LEX &slex= *(thd->lex->first_select_lex());
Name_resolution_context_backup backup(slex.context, *this);
Item *field= newx Item_field(thd, &slex.context, (*this)[FLD_COMMIT_TS]);
Item *value= newx Item_datetime_literal(thd, &commit_time, 6);
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index def52cb2675..4f9ff51eaf7 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1329,7 +1329,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;
@@ -1421,7 +1421,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 55c6b5d330e..cf486c199b3 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -193,7 +193,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 6ff2e25bc27..b8463adcfef 100644
--- a/storage/spider/spd_db_mysql.cc
+++ b/storage/spider/spd_db_mysql.cc
@@ -7217,7 +7217,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/spider/spd_table.cc b/storage/spider/spd_table.cc
index 76032ca80f0..48d29602bf2 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -9077,8 +9077,14 @@ int spider_set_direct_limit_offset(
)
DBUG_RETURN(FALSE);
+ /*
+ TODO: following comment is wrong or the check is wrong (correct
+ check for derived table will be something like select_lex->linkage,
+ if they need only top level it is better to check nested level and do
+ not loose UNIONS & Co
+ */
// must not be derived table
- if (&thd->lex->select_lex != select_lex)
+ if (thd->lex->first_select_lex() != select_lex)
DBUG_RETURN(FALSE);
spider->direct_select_offset = offset_limit;
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);