Commit 09aa5d3f authored by Igor Babaev's avatar Igor Babaev

MDEV-17894 Assertion `(thd->lex)->current_select' failed in MYSQLparse(),

           query with VALUES()

A table value constructor can be used in all contexts where a select
can be used. In particular an ORDER BY clause or a LIMIT clause or both
of them can be attached to a table value constructor to produce a new
query. Unfortunately execution of such queries was not supported.
This patch fixes the problem.
parent 9d805004
...@@ -2189,3 +2189,400 @@ EXECUTE stmt; ...@@ -2189,3 +2189,400 @@ EXECUTE stmt;
1 + 1 2 abc 1 + 1 2 abc
2 2 abc 2 2 abc
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
#
# MDEV-17894: tvc with ORDER BY ... LIMIT
#
values (5), (7), (1), (3), (4) limit 2;
5
5
7
explain extended values (5), (7), (1), (3), (4) limit 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 values (5),(7),(1),(3),(4) limit 2
values (5), (7), (1), (3), (4) limit 2 offset 1;
5
7
1
explain extended values (5), (7), (1), (3), (4) limit 2 offset 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 values (5),(7),(1),(3),(4) limit 1,2
values (5), (7), (1), (3), (4) order by 1 limit 2;
5
1
3
explain extended values (5), (7), (1), (3), (4) order by 1 limit 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 values (5),(7),(1),(3),(4) order by 1 limit 2
values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1;
5
3
4
explain extended values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 values (5),(7),(1),(3),(4) order by 1 limit 1,2
values (5), (7), (1), (3), (4) order by 1;
5
1
3
4
5
7
explain extended values (5), (7), (1), (3), (4) order by 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 values (5),(7),(1),(3),(4) order by 1
values (5,90), (7,20), (1,70), (3,50), (4,10) order by 2;
5 90
4 10
7 20
3 50
1 70
5 90
explain extended values (5,90), (7,20), (1,70), (3,50), (4,10) order by 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 values (5,90),(7,20),(1,70),(3,50),(4,10) order by 2
select 2 union (values (5), (7), (1), (3), (4) limit 2);
2
2
5
7
explain extended select 2 union (values (5), (7), (1), (3), (4) limit 2);
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
Warnings:
Note 1003 /* select#1 */ select 2 AS `2` union (values (5),(7),(1),(3),(4) limit 2)
select 2 union (values (5), (7), (1), (3), (4) limit 2 offset 1);
2
2
7
1
explain extended select 2 union (values (5), (7), (1), (3), (4) limit 2 offset 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
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select 2 AS `2` union (values (5),(7),(1),(3),(4) limit 1,2)
select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2);
2
2
1
3
explain extended select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2);
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
3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select 2 AS `2` union (/* select#3 */ select `tvc_0`.`5` AS `5` from (values (5),(7),(1),(3),(4)) `tvc_0` order by 1 limit 2)
select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1);
2
2
3
4
explain extended select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2 offset 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
3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select 2 AS `2` union (/* select#3 */ select `tvc_0`.`5` AS `5` from (values (5),(7),(1),(3),(4)) `tvc_0` order by 1 limit 1,2)
(values (5), (7), (1), (3), (4) limit 2) union select 2;
5
5
7
2
explain extended (values (5), (7), (1), (3), (4) limit 2) union select 2;
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
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 2) union /* select#2 */ select 2 AS `2`
(values (5), (7), (1), (3), (4) limit 2 offset 1) union select 2;
5
7
1
2
explain extended (values (5), (7), (1), (3), (4) limit 2 offset 1) union select 2;
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
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 1,2) union /* select#2 */ select 2 AS `2`
(values (5), (7), (1), (3), (4) order by 1 limit 2) union select 2;
5
1
3
2
explain extended (values (5), (7), (1), (3), (4) order by 1 limit 2) union select 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SUBQUERY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort
3 SIMPLE 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
Warnings:
Note 1003 (/* select#1 */ select `tvc_0`.`5` AS `5` from (values (5),(7),(1),(3),(4)) `tvc_0` order by 1 limit 2) union /* select#2 */ select 2 AS `2`
(values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1) union select 2;
5
3
4
2
explain extended (values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1) union select 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SUBQUERY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort
3 SIMPLE 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
Warnings:
Note 1003 (/* select#1 */ select `tvc_0`.`5` AS `5` from (values (5),(7),(1),(3),(4)) `tvc_0` order by 1 limit 1,2) union /* select#2 */ select 2 AS `2`
select 3 union all (values (5), (7), (1), (3), (4) limit 2 offset 3);
3
3
3
4
explain extended select 3 union all (values (5), (7), (1), (3), (4) limit 2 offset 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
2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 /* select#1 */ select 3 AS `3` union all (values (5),(7),(1),(3),(4) limit 3,2)
(values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3;
5
3
4
3
explain extended (values (5), (7), (1), (3), (4) limit 2 offset 3) union all 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
2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 3,2) union all /* select#2 */ select 3 AS `3`
select 3 union all (values (5), (7), (1), (3), (4) order by 1 limit 2);
3
3
1
3
explain extended select 3 union all (values (5), (7), (1), (3), (4) order by 1 limit 2);
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
3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select 3 AS `3` union all (/* select#3 */ select `tvc_0`.`5` AS `5` from (values (5),(7),(1),(3),(4)) `tvc_0` order by 1 limit 2)
(values (5), (7), (1), (3), (4) order by 1 limit 2) union all select 3;
5
1
3
3
explain extended (values (5), (7), (1), (3), (4) order by 1 limit 2) union all select 3;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SUBQUERY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort
3 SIMPLE 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
Warnings:
Note 1003 (/* select#1 */ select `tvc_0`.`5` AS `5` from (values (5),(7),(1),(3),(4)) `tvc_0` order by 1 limit 2) union all /* select#2 */ select 3 AS `3`
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
5
7
1
3
explain extended ( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
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
3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 1,2) union (/* select#3 */ select `tvc_0`.`5` AS `5` from (values (5),(7),(1),(3),(4)) `tvc_0` order by 1 limit 2)
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union all
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
5
7
1
1
3
explain extended ( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union all
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
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
3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 1,2) union all (/* select#3 */ select `tvc_0`.`5` AS `5` from (values (5),(7),(1),(3),(4)) `tvc_0` order by 1 limit 2)
(values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3 order by 1;
5
3
3
4
explain extended (values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3 order by 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
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 3,2) union all /* select#2 */ select 3 AS `3` order by 1
(values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3 order by 1;
5
3
3
4
5
explain extended (values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3 order by 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SUBQUERY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort
3 SIMPLE 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 `tvc_0`.`5` AS `5` from (values (5),(7),(1),(3),(4)) `tvc_0` order by 1 limit 1,3) union all /* select#2 */ select 3 AS `3` order by 1
(values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3
order by 1 limit 2 offset 1;
5
3
4
explain extended (values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3
order by 1 limit 2 offset 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SUBQUERY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort
3 SIMPLE 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 `tvc_0`.`5` AS `5` from (values (5),(7),(1),(3),(4)) `tvc_0` order by 1 limit 1,3) union all /* select#2 */ select 3 AS `3` order by 1 limit 1,2
values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3;
ERROR 42S22: Unknown column '3' in 'order clause'
prepare stmt from "
select 2 union (values (5), (7), (1), (3), (4) limit 2)
";
execute stmt;
2
2
5
7
execute stmt;
2
2
5
7
deallocate prepare stmt;
prepare stmt from "
select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2)
";
execute stmt;
2
2
1
3
execute stmt;
2
2
1
3
deallocate prepare stmt;
prepare stmt from "
select 3 union all (values (5), (7), (1), (3), (4) limit 2)
";
execute stmt;
3
3
5
7
execute stmt;
3
3
5
7
deallocate prepare stmt;
prepare stmt from "
select 3 union all (values (5), (7), (1), (3), (4) order by 1 limit 2)
";
execute stmt;
3
3
1
3
execute stmt;
3
3
1
3
deallocate prepare stmt;
prepare stmt from "
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
";
execute stmt;
5
7
1
3
execute stmt;
5
7
1
3
deallocate prepare stmt;
prepare stmt from "
values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3;
";
ERROR 42S22: Unknown column '3' in 'order clause'
create view v1 as values (5), (7), (1), (3), (4) order by 1 limit 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 values (5),(7),(1),(3),(4) order by 1 limit 2 latin1 latin1_swedish_ci
select * from v1;
5
1
3
drop view v1;
create view v1 as
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 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 (values (5),(7),(1),(3),(4) limit 1,2) union (values (5),(7),(1),(3),(4) order by 1 limit 2) latin1 latin1_swedish_ci
select * from v1;
5
7
1
3
drop view v1;
create view v1 as values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3;
ERROR 42S22: Unknown column '3' in 'order clause'
create view v1 as
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 2 limit 2 );
ERROR 42S22: Unknown column '2' in 'order clause'
...@@ -1123,3 +1123,196 @@ PREPARE stmt FROM "SELECT * FROM (VALUES(1 + 1,2,'abc')) t"; ...@@ -1123,3 +1123,196 @@ PREPARE stmt FROM "SELECT * FROM (VALUES(1 + 1,2,'abc')) t";
EXECUTE stmt; EXECUTE stmt;
EXECUTE stmt; EXECUTE stmt;
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
--echo #
--echo # MDEV-17894: tvc with ORDER BY ... LIMIT
--echo #
let $q=
values (5), (7), (1), (3), (4) limit 2;
eval $q;
eval explain extended $q;
let $q=
values (5), (7), (1), (3), (4) limit 2 offset 1;
eval $q;
eval explain extended $q;
let $q=
values (5), (7), (1), (3), (4) order by 1 limit 2;
eval $q;
eval explain extended $q;
let $q=
values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1;
eval $q;
eval explain extended $q;
let $q=
values (5), (7), (1), (3), (4) order by 1;
eval $q;
eval explain extended $q;
let $q=
values (5,90), (7,20), (1,70), (3,50), (4,10) order by 2;
eval $q;
eval explain extended $q;
let $q=
select 2 union (values (5), (7), (1), (3), (4) limit 2);
eval $q;
eval explain extended $q;
let $q=
select 2 union (values (5), (7), (1), (3), (4) limit 2 offset 1);
eval $q;
eval explain extended $q;
let $q=
select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2);
eval $q;
eval explain extended $q;
let $q=
select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1);
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) limit 2) union select 2;
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) limit 2 offset 1) union select 2;
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) order by 1 limit 2) union select 2;
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1) union select 2;
eval $q;
eval explain extended $q;
let $q=
select 3 union all (values (5), (7), (1), (3), (4) limit 2 offset 3);
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3;
eval $q;
eval explain extended $q;
let $q=
select 3 union all (values (5), (7), (1), (3), (4) order by 1 limit 2);
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) order by 1 limit 2) union all select 3;
eval $q;
eval explain extended $q;
let $q=
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
eval $q;
eval explain extended $q;
let $q=
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union all
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3 order by 1;
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3 order by 1;
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3
order by 1 limit 2 offset 1;
eval $q;
eval explain extended $q;
--error ER_BAD_FIELD_ERROR
values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3;
prepare stmt from "
select 2 union (values (5), (7), (1), (3), (4) limit 2)
";
execute stmt;
execute stmt;
deallocate prepare stmt;
prepare stmt from "
select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2)
";
execute stmt;
execute stmt;
deallocate prepare stmt;
prepare stmt from "
select 3 union all (values (5), (7), (1), (3), (4) limit 2)
";
execute stmt;
execute stmt;
deallocate prepare stmt;
prepare stmt from "
select 3 union all (values (5), (7), (1), (3), (4) order by 1 limit 2)
";
execute stmt;
execute stmt;
deallocate prepare stmt;
prepare stmt from "
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
";
execute stmt;
execute stmt;
deallocate prepare stmt;
--error ER_BAD_FIELD_ERROR
prepare stmt from "
values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3;
";
create view v1 as values (5), (7), (1), (3), (4) order by 1 limit 2;
show create view v1;
select * from v1;
drop view v1;
create view v1 as
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
show create view v1;
select * from v1;
drop view v1;
--error ER_BAD_FIELD_ERROR
create view v1 as values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3;
--error ER_BAD_FIELD_ERROR
create view v1 as
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 2 limit 2 );
...@@ -2183,3 +2183,324 @@ VALUES(1 + 1,2,'abc'); ...@@ -2183,3 +2183,324 @@ VALUES(1 + 1,2,'abc');
SELECT * FROM (VALUES(1 + 1,2,'abc')) t; SELECT * FROM (VALUES(1 + 1,2,'abc')) t;
1 + 1 2 abc 1 + 1 2 abc
2 2 abc 2 2 abc
#
# MDEV-17894: tvc with ORDER BY ... LIMIT
#
values (5), (7), (1), (3), (4) limit 2;
5
5
7
explain extended values (5), (7), (1), (3), (4) limit 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 values (5),(7),(1),(3),(4) limit 2
values (5), (7), (1), (3), (4) limit 2 offset 1;
5
7
1
explain extended values (5), (7), (1), (3), (4) limit 2 offset 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 values (5),(7),(1),(3),(4) limit 1,2
values (5), (7), (1), (3), (4) order by 1 limit 2;
5
1
3
explain extended values (5), (7), (1), (3), (4) order by 1 limit 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 values (5),(7),(1),(3),(4) order by 1 limit 2
values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1;
5
3
4
explain extended values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 values (5),(7),(1),(3),(4) order by 1 limit 1,2
values (5), (7), (1), (3), (4) order by 1;
5
1
3
4
5
7
explain extended values (5), (7), (1), (3), (4) order by 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 values (5),(7),(1),(3),(4) order by 1
values (5,90), (7,20), (1,70), (3,50), (4,10) order by 2;
5 90
4 10
7 20
3 50
1 70
5 90
explain extended values (5,90), (7,20), (1,70), (3,50), (4,10) order by 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 values (5,90),(7,20),(1,70),(3,50),(4,10) order by 2
select 2 union (values (5), (7), (1), (3), (4) limit 2);
2
2
5
7
explain extended select 2 union (values (5), (7), (1), (3), (4) limit 2);
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
Warnings:
Note 1003 /* select#1 */ select 2 AS "2" union (values (5),(7),(1),(3),(4) limit 2)
select 2 union (values (5), (7), (1), (3), (4) limit 2 offset 1);
2
2
7
1
explain extended select 2 union (values (5), (7), (1), (3), (4) limit 2 offset 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
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select 2 AS "2" union (values (5),(7),(1),(3),(4) limit 1,2)
select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2);
2
2
1
3
explain extended select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2);
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
3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select 2 AS "2" union (/* select#3 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2)
select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1);
2
2
3
4
explain extended select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2 offset 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
3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select 2 AS "2" union (/* select#3 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 1,2)
(values (5), (7), (1), (3), (4) limit 2) union select 2;
5
5
7
2
explain extended (values (5), (7), (1), (3), (4) limit 2) union select 2;
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
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 2) union /* select#2 */ select 2 AS "2"
(values (5), (7), (1), (3), (4) limit 2 offset 1) union select 2;
5
7
1
2
explain extended (values (5), (7), (1), (3), (4) limit 2 offset 1) union select 2;
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
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 1,2) union /* select#2 */ select 2 AS "2"
(values (5), (7), (1), (3), (4) order by 1 limit 2) union select 2;
5
1
3
2
explain extended (values (5), (7), (1), (3), (4) order by 1 limit 2) union select 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SUBQUERY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort
3 SIMPLE 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
Warnings:
Note 1003 (/* select#1 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2) union /* select#2 */ select 2 AS "2"
(values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1) union select 2;
5
3
4
2
explain extended (values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1) union select 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SUBQUERY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort
3 SIMPLE 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
Warnings:
Note 1003 (/* select#1 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 1,2) union /* select#2 */ select 2 AS "2"
select 3 union all (values (5), (7), (1), (3), (4) limit 2 offset 3);
3
3
3
4
explain extended select 3 union all (values (5), (7), (1), (3), (4) limit 2 offset 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
2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 /* select#1 */ select 3 AS "3" union all (values (5),(7),(1),(3),(4) limit 3,2)
(values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3;
5
3
4
3
explain extended (values (5), (7), (1), (3), (4) limit 2 offset 3) union all 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
2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 3,2) union all /* select#2 */ select 3 AS "3"
select 3 union all (values (5), (7), (1), (3), (4) order by 1 limit 2);
3
3
1
3
explain extended select 3 union all (values (5), (7), (1), (3), (4) order by 1 limit 2);
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
3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select 3 AS "3" union all (/* select#3 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2)
(values (5), (7), (1), (3), (4) order by 1 limit 2) union all select 3;
5
1
3
3
explain extended (values (5), (7), (1), (3), (4) order by 1 limit 2) union all select 3;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SUBQUERY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort
3 SIMPLE 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
Warnings:
Note 1003 (/* select#1 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2) union all /* select#2 */ select 3 AS "3"
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
5
7
1
3
explain extended ( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
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
3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 1,2) union (/* select#3 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2)
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union all
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
5
7
1
1
3
explain extended ( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union all
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
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
3 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00 Using filesort
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 1,2) union all (/* select#3 */ select "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 2)
(values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3 order by 1;
5
3
3
4
explain extended (values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3 order by 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
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings:
Note 1003 (values (5),(7),(1),(3),(4) limit 3,2) union all /* select#2 */ select 3 AS "3" order by 1
(values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3 order by 1;
5
3
3
4
5
explain extended (values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3 order by 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SUBQUERY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort
3 SIMPLE 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 "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 1,3) union all /* select#2 */ select 3 AS "3" order by 1
(values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3
order by 1 limit 2 offset 1;
5
3
4
explain extended (values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3
order by 1 limit 2 offset 1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SUBQUERY <derived3> ALL NULL NULL NULL NULL 5 100.00 Using filesort
3 SIMPLE 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 "tvc_0"."5" AS "5" from (values (5),(7),(1),(3),(4)) "tvc_0" order by 1 limit 1,3) union all /* select#2 */ select 3 AS "3" order by 1 limit 1,2
values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3;
ERROR 42S22: Unknown column '3' in 'order clause'
create view v1 as values (5), (7), (1), (3), (4) order by 1 limit 2;
show create view v1;
View Create View character_set_client collation_connection
v1 CREATE VIEW "v1" AS values (5),(7),(1),(3),(4) order by 1 limit 2 latin1 latin1_swedish_ci
select * from v1;
5
1
3
drop view v1;
create view v1 as
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
show create view v1;
View Create View character_set_client collation_connection
v1 CREATE VIEW "v1" AS (values (5),(7),(1),(3),(4) limit 1,2) union (values (5),(7),(1),(3),(4) order by 1 limit 2) latin1 latin1_swedish_ci
select * from v1;
5
7
1
3
drop view v1;
create view v1 as values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3;
ERROR 42S22: Unknown column '3' in 'order clause'
create view v1 as
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 2 limit 2 );
ERROR 42S22: Unknown column '2' in 'order clause'
...@@ -1125,3 +1125,154 @@ DROP VIEW v1; ...@@ -1125,3 +1125,154 @@ DROP VIEW v1;
VALUES(1 + 1,2,'abc'); VALUES(1 + 1,2,'abc');
SELECT * FROM (VALUES(1 + 1,2,'abc')) t; SELECT * FROM (VALUES(1 + 1,2,'abc')) t;
--echo #
--echo # MDEV-17894: tvc with ORDER BY ... LIMIT
--echo #
let $q=
values (5), (7), (1), (3), (4) limit 2;
eval $q;
eval explain extended $q;
let $q=
values (5), (7), (1), (3), (4) limit 2 offset 1;
eval $q;
eval explain extended $q;
let $q=
values (5), (7), (1), (3), (4) order by 1 limit 2;
eval $q;
eval explain extended $q;
let $q=
values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1;
eval $q;
eval explain extended $q;
let $q=
values (5), (7), (1), (3), (4) order by 1;
eval $q;
eval explain extended $q;
let $q=
values (5,90), (7,20), (1,70), (3,50), (4,10) order by 2;
eval $q;
eval explain extended $q;
let $q=
select 2 union (values (5), (7), (1), (3), (4) limit 2);
eval $q;
eval explain extended $q;
let $q=
select 2 union (values (5), (7), (1), (3), (4) limit 2 offset 1);
eval $q;
eval explain extended $q;
let $q=
select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2);
eval $q;
eval explain extended $q;
let $q=
select 2 union (values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1);
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) limit 2) union select 2;
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) limit 2 offset 1) union select 2;
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) order by 1 limit 2) union select 2;
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) order by 1 limit 2 offset 1) union select 2;
eval $q;
eval explain extended $q;
let $q=
select 3 union all (values (5), (7), (1), (3), (4) limit 2 offset 3);
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3;
eval $q;
eval explain extended $q;
let $q=
select 3 union all (values (5), (7), (1), (3), (4) order by 1 limit 2);
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) order by 1 limit 2) union all select 3;
eval $q;
eval explain extended $q;
let $q=
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
eval $q;
eval explain extended $q;
let $q=
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union all
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) limit 2 offset 3) union all select 3 order by 1;
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3 order by 1;
eval $q;
eval explain extended $q;
let $q=
(values (5), (7), (1), (3), (4) order by 1 limit 3 offset 1) union all select 3
order by 1 limit 2 offset 1;
eval $q;
eval explain extended $q;
--error ER_BAD_FIELD_ERROR
values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3;
create view v1 as values (5), (7), (1), (3), (4) order by 1 limit 2;
show create view v1;
select * from v1;
drop view v1;
create view v1 as
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 1 limit 2 );
show create view v1;
select * from v1;
drop view v1;
--error ER_BAD_FIELD_ERROR
create view v1 as values (5,90), (7,20), (1,70), (3,50), (4,10) order by 3;
--error ER_BAD_FIELD_ERROR
create view v1 as
( values (5), (7), (1), (3), (4) limit 2 offset 1 )
union
( values (5), (7), (1), (3), (4) order by 2 limit 2 );
...@@ -269,7 +269,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) ...@@ -269,7 +269,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
{ {
if (sl->tvc) if (sl->tvc)
{ {
wrap_tvc_in_derived_table(thd, sl); wrap_tvc_into_select(thd, sl);
} }
} }
......
...@@ -267,7 +267,7 @@ class Item_subselect :public Item_result_field, ...@@ -267,7 +267,7 @@ class Item_subselect :public Item_result_field,
Item* build_clone(THD *thd) { return 0; } Item* build_clone(THD *thd) { return 0; }
Item* get_copy(THD *thd) { return 0; } Item* get_copy(THD *thd) { return 0; }
bool wrap_tvc_in_derived_table(THD *thd, st_select_lex *tvc_sl); bool wrap_tvc_into_select(THD *thd, st_select_lex *tvc_sl);
friend class select_result_interceptor; friend class select_result_interceptor;
friend class Item_in_optimizer; friend class Item_in_optimizer;
......
...@@ -2292,6 +2292,7 @@ void st_select_lex_unit::init_query() ...@@ -2292,6 +2292,7 @@ void st_select_lex_unit::init_query()
with_element= 0; with_element= 0;
columns_are_renamed= false; columns_are_renamed= false;
intersect_mark= NULL; intersect_mark= NULL;
with_wrapped_tvc= false;
} }
void st_select_lex::init_query() void st_select_lex::init_query()
...@@ -3428,6 +3429,19 @@ bool st_select_lex_unit::union_needs_tmp_table() ...@@ -3428,6 +3429,19 @@ bool st_select_lex_unit::union_needs_tmp_table()
{ {
if (with_element && with_element->is_recursive) if (with_element && with_element->is_recursive)
return true; return true;
if (!with_wrapped_tvc)
{
for (st_select_lex *sl= first_select(); sl; sl=sl->next_select())
{
if (sl->tvc && sl->tvc->to_be_wrapped_as_with_tail())
{
with_wrapped_tvc= true;
break;
}
}
}
if (with_wrapped_tvc)
return true;
return union_distinct != NULL || return union_distinct != NULL ||
global_parameters()->order_list.elements != 0 || global_parameters()->order_list.elements != 0 ||
thd->lex->sql_command == SQLCOM_INSERT_SELECT || thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
...@@ -8238,6 +8252,8 @@ bool LEX::tvc_finalize() ...@@ -8238,6 +8252,8 @@ bool LEX::tvc_finalize()
current_select->options)))) current_select->options))))
return true; return true;
many_values.empty(); many_values.empty();
if (!current_select->master_unit()->fake_select_lex)
current_select->master_unit()->add_fake_select_lex(thd);
return false; return false;
} }
......
...@@ -800,6 +800,12 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -800,6 +800,12 @@ class st_select_lex_unit: public st_select_lex_node {
table for it table for it
*/ */
Item_int *intersect_mark; Item_int *intersect_mark;
/**
TRUE if the unit contained TVC at the top level that has been wrapped
into SELECT:
VALUES (v1) ... (vn) => SELECT * FROM (VALUES (v1) ... (vn)) as tvc
*/
bool with_wrapped_tvc;
/** /**
Pointer to 'last' select, or pointer to select where we stored Pointer to 'last' select, or pointer to select where we stored
global parameters for union. global parameters for union.
......
...@@ -263,6 +263,35 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl, ...@@ -263,6 +263,35 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl,
if (result && result->prepare(sl->item_list, unit_arg)) if (result && result->prepare(sl->item_list, unit_arg))
DBUG_RETURN(true); DBUG_RETURN(true);
/*
setup_order() for a TVC is not called when the following is true
(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)
*/
thd->where="order clause";
ORDER *order= sl->order_list.first;
for (; order; order=order->next)
{
Item *order_item= *order->item;
if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item())
{
uint count= 0;
if (order->counter_used)
count= order->counter; // counter was once resolved
else
count= (uint) order_item->val_int();
if (!count || count > first_elem->elements)
{
my_error(ER_BAD_FIELD_ERROR, MYF(0),
order_item->full_name(), thd->where);
DBUG_RETURN(true);
}
order->in_field_list= 1;
order->counter= count;
order->counter_used= 1;
}
}
select_lex->in_tvc= false; select_lex->in_tvc= false;
DBUG_RETURN(false); DBUG_RETURN(false);
} }
...@@ -344,6 +373,7 @@ bool table_value_constr::exec(SELECT_LEX *sl) ...@@ -344,6 +373,7 @@ bool table_value_constr::exec(SELECT_LEX *sl)
DBUG_ENTER("table_value_constr::exec"); DBUG_ENTER("table_value_constr::exec");
List_iterator_fast<List_item> li(lists_of_values); List_iterator_fast<List_item> li(lists_of_values);
List_item *elem; List_item *elem;
ha_rows send_records= 0;
if (select_options & SELECT_DESCRIBE) if (select_options & SELECT_DESCRIBE)
DBUG_RETURN(false); DBUG_RETURN(false);
...@@ -357,7 +387,13 @@ bool table_value_constr::exec(SELECT_LEX *sl) ...@@ -357,7 +387,13 @@ bool table_value_constr::exec(SELECT_LEX *sl)
while ((elem= li++)) while ((elem= li++))
{ {
result->send_data(*elem); if (send_records >= sl->master_unit()->select_limit_cnt)
break;
int rc= result->send_data(*elem);
if (!rc)
send_records++;
else if (rc > 0)
DBUG_RETURN(true);
} }
if (result->send_eof()) if (result->send_eof())
...@@ -436,6 +472,12 @@ void table_value_constr::print(THD *thd, String *str, ...@@ -436,6 +472,12 @@ void table_value_constr::print(THD *thd, String *str,
print_list_item(str, list, query_type); print_list_item(str, list, query_type);
} }
if (select_lex->order_list.elements)
{
str->append(STRING_WITH_LEN(" order by "));
select_lex->print_order(str, select_lex->order_list.first, query_type);
}
select_lex->print_limit(thd, str, query_type);
} }
...@@ -533,7 +575,8 @@ static bool create_tvc_name(THD *thd, st_select_lex *parent_select, ...@@ -533,7 +575,8 @@ static bool create_tvc_name(THD *thd, st_select_lex *parent_select,
char buff[6]; char buff[6];
alias->length= my_snprintf(buff, sizeof(buff), alias->length= my_snprintf(buff, sizeof(buff),
"tvc_%u", parent_select->curr_tvc_name); "tvc_%u",
parent_select ? parent_select->curr_tvc_name : 0);
alias->str= thd->strmake(buff, alias->length); alias->str= thd->strmake(buff, alias->length);
if (!alias->str) if (!alias->str)
return true; return true;
...@@ -542,19 +585,57 @@ static bool create_tvc_name(THD *thd, st_select_lex *parent_select, ...@@ -542,19 +585,57 @@ static bool create_tvc_name(THD *thd, st_select_lex *parent_select,
} }
bool Item_subselect::wrap_tvc_in_derived_table(THD *thd, /**
st_select_lex *tvc_sl) @brief
Check whether TVC used in unit is to be wrapped into select
@details
TVC used in unit that contains more than one members is to be wrapped
into select if it is tailed with ORDER BY ... LIMIT n [OFFSET m]
@retval
true if TVC is to be wrapped
false otherwise
*/
bool table_value_constr::to_be_wrapped_as_with_tail()
{
return select_lex->master_unit()->first_select()->next_select() &&
select_lex->order_list.elements && select_lex->explicit_limit;
}
/**
@brief
Wrap table value constructor into a select
@param thd The context handler
@param tvc_sl The TVC to wrap
@parent_select The parent select if tvc_sl used in a subquery
@details
The function wraps the TVC tvc_sl into a select:
the function transforms the TVC of the form VALUES (v1), ... (vn) into
the select of the form
SELECT * FROM (VALUES (v1), ... (vn)) tvc_x
@retval pointer to the result of of the transformation if successful
NULL - otherwise
*/
static
st_select_lex *wrap_tvc(THD *thd, st_select_lex *tvc_sl,
st_select_lex *parent_select)
{ {
LEX *lex= thd->lex; LEX *lex= thd->lex;
/* SELECT_LEX object where the transformation is performed */ select_result *save_result= thd->lex->result;
SELECT_LEX *parent_select= lex->current_select;
uint8 save_derived_tables= lex->derived_tables; uint8 save_derived_tables= lex->derived_tables;
thd->lex->result= NULL;
Query_arena backup; Query_arena backup;
Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup); Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup);
/* /*
Create SELECT_LEX of the subquery SQ used in the result of transformation Create SELECT_LEX of the select used in the result of transformation
*/ */
lex->current_select= tvc_sl; lex->current_select= tvc_sl;
if (mysql_new_select(lex, 0, NULL)) if (mysql_new_select(lex, 0, NULL))
...@@ -562,15 +643,15 @@ bool Item_subselect::wrap_tvc_in_derived_table(THD *thd, ...@@ -562,15 +643,15 @@ bool Item_subselect::wrap_tvc_in_derived_table(THD *thd,
mysql_init_select(lex); mysql_init_select(lex);
/* Create item list as '*' for the subquery SQ */ /* Create item list as '*' for the subquery SQ */
Item *item; Item *item;
SELECT_LEX *sq_select; // select for IN subquery; SELECT_LEX *wrapper_sl;
sq_select= lex->current_select; wrapper_sl= lex->current_select;
sq_select->linkage= tvc_sl->linkage; wrapper_sl->linkage= tvc_sl->linkage;
sq_select->parsing_place= SELECT_LIST; wrapper_sl->parsing_place= SELECT_LIST;
item= new (thd->mem_root) Item_field(thd, &sq_select->context, item= new (thd->mem_root) Item_field(thd, &wrapper_sl->context,
NULL, NULL, &star_clex_str); NULL, NULL, &star_clex_str);
if (item == NULL || add_item_to_list(thd, item)) if (item == NULL || add_item_to_list(thd, item))
goto err; goto err;
(sq_select->with_wild)++; (wrapper_sl->with_wild)++;
/* Exclude SELECT with TVC */ /* Exclude SELECT with TVC */
tvc_sl->exclude(); tvc_sl->exclude();
...@@ -585,11 +666,11 @@ bool Item_subselect::wrap_tvc_in_derived_table(THD *thd, ...@@ -585,11 +666,11 @@ bool Item_subselect::wrap_tvc_in_derived_table(THD *thd,
derived_unit= tvc_select->master_unit(); derived_unit= tvc_select->master_unit();
tvc_select->linkage= DERIVED_TABLE_TYPE; tvc_select->linkage= DERIVED_TABLE_TYPE;
lex->current_select= sq_select; lex->current_select= wrapper_sl;
/* /*
Create the name of the wrapping derived table and Create the name of the wrapping derived table and
add it to the FROM list of the subquery SQ add it to the FROM list of the wrapper
*/ */
Table_ident *ti; Table_ident *ti;
LEX_CSTRING alias; LEX_CSTRING alias;
...@@ -598,35 +679,120 @@ bool Item_subselect::wrap_tvc_in_derived_table(THD *thd, ...@@ -598,35 +679,120 @@ bool Item_subselect::wrap_tvc_in_derived_table(THD *thd,
create_tvc_name(thd, parent_select, &alias)) create_tvc_name(thd, parent_select, &alias))
goto err; goto err;
if (!(derived_tab= if (!(derived_tab=
sq_select->add_table_to_list(thd, wrapper_sl->add_table_to_list(thd,
ti, &alias, 0, ti, &alias, 0,
TL_READ, MDL_SHARED_READ))) TL_READ, MDL_SHARED_READ)))
goto err; goto err;
sq_select->add_joined_table(derived_tab); wrapper_sl->add_joined_table(derived_tab);
sq_select->add_where_field(derived_unit->first_select()); wrapper_sl->add_where_field(derived_unit->first_select());
sq_select->context.table_list= sq_select->table_list.first; wrapper_sl->context.table_list= wrapper_sl->table_list.first;
sq_select->context.first_name_resolution_table= sq_select->table_list.first; wrapper_sl->context.first_name_resolution_table= wrapper_sl->table_list.first;
sq_select->table_list.first->derived_type= DTYPE_TABLE | DTYPE_MATERIALIZE; wrapper_sl->table_list.first->derived_type= DTYPE_TABLE | DTYPE_MATERIALIZE;
lex->derived_tables|= DERIVED_SUBQUERY; lex->derived_tables|= DERIVED_SUBQUERY;
sq_select->where= 0; wrapper_sl->where= 0;
sq_select->set_braces(false); wrapper_sl->set_braces(false);
derived_unit->set_with_clause(0); derived_unit->set_with_clause(0);
if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
((subselect_single_select_engine *) engine)->change_select(sq_select);
if (arena) if (arena)
thd->restore_active_arena(arena, &backup); thd->restore_active_arena(arena, &backup);
lex->current_select= sq_select; thd->lex->result= save_result;
return false; return wrapper_sl;
err: err:
if (arena) if (arena)
thd->restore_active_arena(arena, &backup); thd->restore_active_arena(arena, &backup);
thd->lex->result= save_result;
lex->derived_tables= save_derived_tables; lex->derived_tables= save_derived_tables;
lex->current_select= parent_select; return 0;
return true; }
/**
@brief
Wrap TVC with ORDER BY ... LIMIT tail into a select
@param thd The context handler
@param tvc_sl The TVC to wrap
@details
The function wraps the TVC tvc_sl into a select:
the function transforms the TVC with tail of the form
VALUES (v1), ... (vn) ORDER BY ... LIMIT n [OFFSET m]
into the select with the same tail of the form
SELECT * FROM (VALUES (v1), ... (vn)) tvc_x
ORDER BY ... LIMIT n [OFFSET m]
@retval pointer to the result of of the transformation if successful
NULL - otherwise
*/
st_select_lex *wrap_tvc_with_tail(THD *thd, st_select_lex *tvc_sl)
{
st_select_lex *wrapper_sl= wrap_tvc(thd, tvc_sl, NULL);
if (!wrapper_sl)
return NULL;
wrapper_sl->order_list= tvc_sl->order_list;
wrapper_sl->select_limit= tvc_sl->select_limit;
wrapper_sl->offset_limit= tvc_sl->offset_limit;
wrapper_sl->braces= tvc_sl->braces;
wrapper_sl->explicit_limit= tvc_sl->explicit_limit;
tvc_sl->order_list.empty();
tvc_sl->select_limit= NULL;
tvc_sl->offset_limit= NULL;
tvc_sl->braces= 0;
tvc_sl->explicit_limit= false;
if (tvc_sl->select_number == 1)
{
tvc_sl->select_number= wrapper_sl->select_number;
wrapper_sl->select_number= 1;
}
if (tvc_sl->master_unit()->union_distinct == tvc_sl)
{
wrapper_sl->master_unit()->union_distinct= wrapper_sl;
}
thd->lex->current_select= wrapper_sl;
return wrapper_sl;
}
/**
@brief
Wrap TVC in a subselect into a select
@param thd The context handler
@param tvc_sl The TVC to wrap
@details
The function wraps the TVC tvc_sl used in a subselect into a select
the function transforms the TVC of the form VALUES (v1), ... (vn)
into the select the form
SELECT * FROM (VALUES (v1), ... (vn)) tvc_x
and replaces the subselect with the result of the transformation.
@retval false if successfull
true otherwise
*/
bool Item_subselect::wrap_tvc_into_select(THD *thd, st_select_lex *tvc_sl)
{
LEX *lex= thd->lex;
/* SELECT_LEX object where the transformation is performed */
SELECT_LEX *parent_select= lex->current_select;
SELECT_LEX *wrapper_sl= wrap_tvc(thd, tvc_sl, parent_select);
if (wrapper_sl)
{
if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
((subselect_single_select_engine *) engine)->change_select(wrapper_sl);
lex->current_select= wrapper_sl;
return false;
}
else
{
lex->current_select= parent_select;
return true;
}
} }
......
...@@ -57,6 +57,8 @@ class table_value_constr : public Sql_alloc ...@@ -57,6 +57,8 @@ class table_value_constr : public Sql_alloc
select_result *tmp_result, select_result *tmp_result,
st_select_lex_unit *unit_arg); st_select_lex_unit *unit_arg);
bool to_be_wrapped_as_with_tail();
int save_explain_data_intern(THD *thd_arg, int save_explain_data_intern(THD *thd_arg,
Explain_query *output); Explain_query *output);
bool optimize(THD *thd_arg); bool optimize(THD *thd_arg);
...@@ -64,4 +66,7 @@ class table_value_constr : public Sql_alloc ...@@ -64,4 +66,7 @@ class table_value_constr : public Sql_alloc
void print(THD *thd_arg, String *str, enum_query_type query_type); void print(THD *thd_arg, String *str, enum_query_type query_type);
}; };
st_select_lex *wrap_tvc_with_tail(THD *thd, st_select_lex *tvc_sl);
#endif /* SQL_TVC_INCLUDED */ #endif /* SQL_TVC_INCLUDED */
...@@ -831,7 +831,8 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -831,7 +831,8 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
bool is_union_select; bool is_union_select;
bool have_except= FALSE, have_intersect= FALSE; bool have_except= FALSE, have_intersect= FALSE;
bool instantiate_tmp_table= false; bool instantiate_tmp_table= false;
bool single_tvc= !first_sl->next_select() && first_sl->tvc; bool single_tvc= !first_sl->next_select() && first_sl->tvc &&
!fake_select_lex;
DBUG_ENTER("st_select_lex_unit::prepare"); DBUG_ENTER("st_select_lex_unit::prepare");
DBUG_ASSERT(thd == current_thd); DBUG_ASSERT(thd == current_thd);
...@@ -986,7 +987,23 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -986,7 +987,23 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
{ {
if (sl->tvc) if (sl->tvc)
{ {
if (sl->tvc->prepare(thd, sl, tmp_result, this)) if (sl->tvc->to_be_wrapped_as_with_tail() &&
!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW))
{
st_select_lex *wrapper_sl= wrap_tvc_with_tail(thd, sl);
if (!wrapper_sl)
goto err;
if (sl == first_sl)
first_sl= wrapper_sl;
sl= wrapper_sl;
if (prepare_join(thd, sl, tmp_result, additional_options,
is_union_select))
goto err;
}
else if (sl->tvc->prepare(thd, sl, tmp_result, this))
goto err; goto err;
} }
else if (prepare_join(thd, sl, tmp_result, additional_options, else if (prepare_join(thd, sl, tmp_result, additional_options,
......
...@@ -9192,7 +9192,7 @@ select_paren: ...@@ -9192,7 +9192,7 @@ select_paren:
{ {
Lex->current_select->set_braces(true); Lex->current_select->set_braces(true);
} }
table_value_constructor table_value_constructor select_part3
{ {
DBUG_ASSERT(Lex->current_select->braces); DBUG_ASSERT(Lex->current_select->braces);
} }
...@@ -9212,6 +9212,12 @@ select_paren: ...@@ -9212,6 +9212,12 @@ select_paren:
| '(' select_paren ')' | '(' select_paren ')'
; ;
select_parent_union_query_term_proper:
SELECT_SYM select_options_and_item_list select_part3_union_query_term
opt_select_lock_type
| table_value_constructor select_part3_union_query_term
;
select_paren_union_query_term: select_paren_union_query_term:
{ {
/* /*
...@@ -9220,14 +9226,19 @@ select_paren_union_query_term: ...@@ -9220,14 +9226,19 @@ select_paren_union_query_term:
*/ */
Lex->current_select->set_braces(true); Lex->current_select->set_braces(true);
} }
SELECT_SYM select_options_and_item_list select_part3_union_query_term select_parent_union_query_term_proper
opt_select_lock_type
{ {
DBUG_ASSERT(Lex->current_select->braces); DBUG_ASSERT(Lex->current_select->braces);
} }
| '(' select_paren_union_query_term ')' | '(' select_paren_union_query_term ')'
; ;
select_parent_view_proper:
SELECT_SYM select_options_and_item_list select_part3_view
opt_select_lock_type
| table_value_constructor select_part3_view
;
select_paren_view: select_paren_view:
{ {
/* /*
...@@ -9236,8 +9247,7 @@ select_paren_view: ...@@ -9236,8 +9247,7 @@ select_paren_view:
*/ */
Lex->current_select->set_braces(true); Lex->current_select->set_braces(true);
} }
SELECT_SYM select_options_and_item_list select_part3_view select_parent_view_proper
opt_select_lock_type
{ {
DBUG_ASSERT(Lex->current_select->braces); DBUG_ASSERT(Lex->current_select->braces);
} }
......
...@@ -9129,7 +9129,7 @@ select_paren: ...@@ -9129,7 +9129,7 @@ select_paren:
{ {
Lex->current_select->set_braces(true); Lex->current_select->set_braces(true);
} }
table_value_constructor table_value_constructor select_part3
{ {
DBUG_ASSERT(Lex->current_select->braces); DBUG_ASSERT(Lex->current_select->braces);
} }
...@@ -9149,6 +9149,12 @@ select_paren: ...@@ -9149,6 +9149,12 @@ select_paren:
| '(' select_paren ')' | '(' select_paren ')'
; ;
select_parent_union_query_term_proper:
SELECT_SYM select_options_and_item_list select_part3_union_query_term
opt_select_lock_type
| table_value_constructor select_part3_union_query_term
;
select_paren_union_query_term: select_paren_union_query_term:
{ {
/* /*
...@@ -9157,14 +9163,19 @@ select_paren_union_query_term: ...@@ -9157,14 +9163,19 @@ select_paren_union_query_term:
*/ */
Lex->current_select->set_braces(true); Lex->current_select->set_braces(true);
} }
SELECT_SYM select_options_and_item_list select_part3_union_query_term select_parent_union_query_term_proper
opt_select_lock_type
{ {
DBUG_ASSERT(Lex->current_select->braces); DBUG_ASSERT(Lex->current_select->braces);
} }
| '(' select_paren_union_query_term ')' | '(' select_paren_union_query_term ')'
; ;
select_parent_view_proper:
SELECT_SYM select_options_and_item_list select_part3_view
opt_select_lock_type
| table_value_constructor select_part3_view
;
select_paren_view: select_paren_view:
{ {
/* /*
...@@ -9173,8 +9184,7 @@ select_paren_view: ...@@ -9173,8 +9184,7 @@ select_paren_view:
*/ */
Lex->current_select->set_braces(true); Lex->current_select->set_braces(true);
} }
SELECT_SYM select_options_and_item_list select_part3_view select_parent_view_proper
opt_select_lock_type
{ {
DBUG_ASSERT(Lex->current_select->braces); DBUG_ASSERT(Lex->current_select->braces);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment