MDEV-34506 2nd execution name resolution problem with pushdown into unions
Statements affected by this bug need all the following to be true 1) a derived table table or view whose specification contains a set operation at the top level. 2) a grouping operator (group by/having) operating on a column alias other than in the first select of the union/intersect 3) an outer condition that will be pushed into all selects in this union/intersect, either into the where or having clause When pushing a condition into all selects of a unit with more than one select, pushdown_cond_for_derived() renames items so we can re-use the condition being pushed. These names need to be saved and reset for correct name resolution on second execution of prepared statements. Reviewed by Igor Babaev (igor@mariadb.com)
This commit is contained in:
parent
7e5c9ccda5
commit
48b256a7e2
@ -18557,3 +18557,498 @@ valdouble valint1
|
||||
5 3289988
|
||||
DROP TABLE t1,t2;
|
||||
# End of 10.4 tests
|
||||
# MDEV-34506 2nd execution name resolution problem with pushdown into
|
||||
# unions
|
||||
#
|
||||
# Statements affected by this bug need all the following to be true
|
||||
# 1) a derived table table or view whose specification contains a set
|
||||
# operation at the top level.
|
||||
# 2) a grouping operator (group by/having) operating on a column alias
|
||||
# other than in the first select of the union/intersect
|
||||
# 3) an outer condition that will be pushed into all selects in this
|
||||
# union/intersect, either into the where or having clause
|
||||
#
|
||||
# When pushing a condition into all selects of a unit with more than one
|
||||
# select, pushdown_cond_for_derived() renames items so we can re-use the
|
||||
# condition being pushed.
|
||||
# These names need to be saved and reset for correct name resolution on
|
||||
# second execution of prepared statements.
|
||||
create table t1 (c1 int, c2 int, c3 int);
|
||||
insert into t1 values (1,2,3),(1,2,2),(4,5,6);
|
||||
insert into t1 values (17,8,9),(11,11,12);
|
||||
create table t2 (c4 int, c5 int, c6 int);
|
||||
insert into t2 values (7,8,9),(10,11,12);
|
||||
prepare stmt from 'select * from
|
||||
(
|
||||
select c1, sum(c3) as s from t1 group by c1
|
||||
union
|
||||
select c4 as c, sum(c6) as u from t2 group by c
|
||||
) dt
|
||||
where c1 > 6';
|
||||
execute stmt;
|
||||
c1 s
|
||||
11 12
|
||||
17 9
|
||||
7 9
|
||||
10 12
|
||||
execute stmt;
|
||||
c1 s
|
||||
11 12
|
||||
17 9
|
||||
7 9
|
||||
10 12
|
||||
prepare stmt from 'explain format=json select * from
|
||||
(
|
||||
select c1, sum(c3) as s from t1 group by c1
|
||||
union
|
||||
select c4 as c, sum(c6) as u from t2 group by c
|
||||
) dt
|
||||
where c1 > 6';
|
||||
execute stmt;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"table": {
|
||||
"table_name": "<derived2>",
|
||||
"access_type": "ALL",
|
||||
"rows": 7,
|
||||
"filtered": 100,
|
||||
"attached_condition": "dt.c1 > 6",
|
||||
"materialized": {
|
||||
"query_block": {
|
||||
"union_result": {
|
||||
"table_name": "<union2,3>",
|
||||
"access_type": "ALL",
|
||||
"query_specifications": [
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 2,
|
||||
"filesort": {
|
||||
"sort_key": "t1.c1",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 5,
|
||||
"filtered": 100,
|
||||
"attached_condition": "t1.c1 > 6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 3,
|
||||
"operation": "UNION",
|
||||
"filesort": {
|
||||
"sort_key": "t2.c4",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t2",
|
||||
"access_type": "ALL",
|
||||
"rows": 2,
|
||||
"filtered": 100,
|
||||
"attached_condition": "t2.c4 > 6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
execute stmt;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"table": {
|
||||
"table_name": "<derived2>",
|
||||
"access_type": "ALL",
|
||||
"rows": 7,
|
||||
"filtered": 100,
|
||||
"attached_condition": "dt.c1 > 6",
|
||||
"materialized": {
|
||||
"query_block": {
|
||||
"union_result": {
|
||||
"table_name": "<union2,3>",
|
||||
"access_type": "ALL",
|
||||
"query_specifications": [
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 2,
|
||||
"filesort": {
|
||||
"sort_key": "t1.c1",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 5,
|
||||
"filtered": 100,
|
||||
"attached_condition": "t1.c1 > 6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 3,
|
||||
"operation": "UNION",
|
||||
"filesort": {
|
||||
"sort_key": "t2.c4",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t2",
|
||||
"access_type": "ALL",
|
||||
"rows": 2,
|
||||
"filtered": 100,
|
||||
"attached_condition": "t2.c4 > 6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
prepare stmt from 'select * from
|
||||
(
|
||||
select c1, c2, sum(c3) as s from t1 group by c1, c2 having s > 2
|
||||
union
|
||||
select c4, c5, sum(c6) as u from t2 group by c4, c5 having u > 3
|
||||
) dt
|
||||
where c2 > 5';
|
||||
execute stmt;
|
||||
c1 c2 s
|
||||
11 11 12
|
||||
17 8 9
|
||||
7 8 9
|
||||
10 11 12
|
||||
execute stmt;
|
||||
c1 c2 s
|
||||
11 11 12
|
||||
17 8 9
|
||||
7 8 9
|
||||
10 11 12
|
||||
prepare stmt from 'explain format=json select * from
|
||||
(
|
||||
select c1, c2, sum(c3) as s from t1 group by c1, c2 having s > 2
|
||||
union
|
||||
select c4, c5, sum(c6) as u from t2 group by c4, c5 having u > 3
|
||||
) dt
|
||||
where c2 > 5';
|
||||
execute stmt;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"table": {
|
||||
"table_name": "<derived2>",
|
||||
"access_type": "ALL",
|
||||
"rows": 7,
|
||||
"filtered": 100,
|
||||
"attached_condition": "dt.c2 > 5",
|
||||
"materialized": {
|
||||
"query_block": {
|
||||
"union_result": {
|
||||
"table_name": "<union2,3>",
|
||||
"access_type": "ALL",
|
||||
"query_specifications": [
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 2,
|
||||
"having_condition": "s > 2",
|
||||
"filesort": {
|
||||
"sort_key": "t1.c1, t1.c2",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 5,
|
||||
"filtered": 100,
|
||||
"attached_condition": "t1.c2 > 5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 3,
|
||||
"operation": "UNION",
|
||||
"having_condition": "s > 3",
|
||||
"filesort": {
|
||||
"sort_key": "t2.c4, t2.c5",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t2",
|
||||
"access_type": "ALL",
|
||||
"rows": 2,
|
||||
"filtered": 100,
|
||||
"attached_condition": "t2.c5 > 5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
execute stmt;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"table": {
|
||||
"table_name": "<derived2>",
|
||||
"access_type": "ALL",
|
||||
"rows": 7,
|
||||
"filtered": 100,
|
||||
"attached_condition": "dt.c2 > 5",
|
||||
"materialized": {
|
||||
"query_block": {
|
||||
"union_result": {
|
||||
"table_name": "<union2,3>",
|
||||
"access_type": "ALL",
|
||||
"query_specifications": [
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 2,
|
||||
"having_condition": "s > 2",
|
||||
"filesort": {
|
||||
"sort_key": "t1.c1, t1.c2",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 5,
|
||||
"filtered": 100,
|
||||
"attached_condition": "t1.c2 > 5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 3,
|
||||
"operation": "UNION",
|
||||
"having_condition": "s > 3",
|
||||
"filesort": {
|
||||
"sort_key": "t2.c4, t2.c5",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t2",
|
||||
"access_type": "ALL",
|
||||
"rows": 2,
|
||||
"filtered": 100,
|
||||
"attached_condition": "t2.c5 > 5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
prepare stmt from 'select *
|
||||
from
|
||||
(
|
||||
select c1, c2, max(c3) as max_c, avg(c3) as avg_c
|
||||
from t1
|
||||
group by c1,c2
|
||||
having max_c < 7
|
||||
union
|
||||
select c4, c5, max(c6) as u, avg(c6) as w
|
||||
from t2
|
||||
group by c4, c5
|
||||
having u < 10
|
||||
) dt,
|
||||
t2
|
||||
where dt.max_c > 6 and t2.c6 > dt.c1';
|
||||
execute stmt;
|
||||
c1 c2 max_c avg_c c4 c5 c6
|
||||
7 8 9 9.0000 7 8 9
|
||||
7 8 9 9.0000 10 11 12
|
||||
execute stmt;
|
||||
c1 c2 max_c avg_c c4 c5 c6
|
||||
7 8 9 9.0000 7 8 9
|
||||
7 8 9 9.0000 10 11 12
|
||||
prepare stmt from 'explain format=json select *
|
||||
from
|
||||
(
|
||||
select c1, c2, max(c3) as max_c, avg(c3) as avg_c
|
||||
from t1
|
||||
group by c1,c2
|
||||
having max_c < 7
|
||||
union
|
||||
select c4, c5, max(c6) as u, avg(c6) as w
|
||||
from t2
|
||||
group by c4, c5
|
||||
having u < 10
|
||||
) dt,
|
||||
t2
|
||||
where dt.max_c > 6 and t2.c6 > dt.c1';
|
||||
execute stmt;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"table": {
|
||||
"table_name": "t2",
|
||||
"access_type": "ALL",
|
||||
"rows": 2,
|
||||
"filtered": 100
|
||||
},
|
||||
"block-nl-join": {
|
||||
"table": {
|
||||
"table_name": "<derived2>",
|
||||
"access_type": "ALL",
|
||||
"rows": 7,
|
||||
"filtered": 100,
|
||||
"attached_condition": "dt.max_c > 6"
|
||||
},
|
||||
"buffer_type": "flat",
|
||||
"buffer_size": "173",
|
||||
"join_type": "BNL",
|
||||
"attached_condition": "t2.c6 > dt.c1",
|
||||
"materialized": {
|
||||
"query_block": {
|
||||
"union_result": {
|
||||
"table_name": "<union2,3>",
|
||||
"access_type": "ALL",
|
||||
"query_specifications": [
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 2,
|
||||
"having_condition": "max_c < 7 and max_c > 6",
|
||||
"filesort": {
|
||||
"sort_key": "t1.c1, t1.c2",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 5,
|
||||
"filtered": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 3,
|
||||
"operation": "UNION",
|
||||
"having_condition": "max_c < 10 and max_c > 6",
|
||||
"filesort": {
|
||||
"sort_key": "t2.c4, t2.c5",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t2",
|
||||
"access_type": "ALL",
|
||||
"rows": 2,
|
||||
"filtered": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
execute stmt;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"table": {
|
||||
"table_name": "t2",
|
||||
"access_type": "ALL",
|
||||
"rows": 2,
|
||||
"filtered": 100
|
||||
},
|
||||
"block-nl-join": {
|
||||
"table": {
|
||||
"table_name": "<derived2>",
|
||||
"access_type": "ALL",
|
||||
"rows": 7,
|
||||
"filtered": 100,
|
||||
"attached_condition": "dt.max_c > 6"
|
||||
},
|
||||
"buffer_type": "flat",
|
||||
"buffer_size": "173",
|
||||
"join_type": "BNL",
|
||||
"attached_condition": "t2.c6 > dt.c1",
|
||||
"materialized": {
|
||||
"query_block": {
|
||||
"union_result": {
|
||||
"table_name": "<union2,3>",
|
||||
"access_type": "ALL",
|
||||
"query_specifications": [
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 2,
|
||||
"having_condition": "max_c < 7 and max_c > 6",
|
||||
"filesort": {
|
||||
"sort_key": "t1.c1, t1.c2",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 5,
|
||||
"filtered": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 3,
|
||||
"operation": "UNION",
|
||||
"having_condition": "max_c < 10 and max_c > 6",
|
||||
"filesort": {
|
||||
"sort_key": "t2.c4, t2.c5",
|
||||
"temporary_table": {
|
||||
"table": {
|
||||
"table_name": "t2",
|
||||
"access_type": "ALL",
|
||||
"rows": 2,
|
||||
"filtered": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
drop table t1, t2;
|
||||
# End of 10.5 tests
|
||||
|
@ -4102,3 +4102,90 @@ eval $q;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo # End of 10.4 tests
|
||||
|
||||
--echo # MDEV-34506 2nd execution name resolution problem with pushdown into
|
||||
--echo # unions
|
||||
--echo #
|
||||
--echo # Statements affected by this bug need all the following to be true
|
||||
--echo # 1) a derived table table or view whose specification contains a set
|
||||
--echo # operation at the top level.
|
||||
--echo # 2) a grouping operator (group by/having) operating on a column alias
|
||||
--echo # other than in the first select of the union/intersect
|
||||
--echo # 3) an outer condition that will be pushed into all selects in this
|
||||
--echo # union/intersect, either into the where or having clause
|
||||
--echo #
|
||||
--echo # When pushing a condition into all selects of a unit with more than one
|
||||
--echo # select, pushdown_cond_for_derived() renames items so we can re-use the
|
||||
--echo # condition being pushed.
|
||||
--echo # These names need to be saved and reset for correct name resolution on
|
||||
--echo # second execution of prepared statements.
|
||||
|
||||
create table t1 (c1 int, c2 int, c3 int);
|
||||
insert into t1 values (1,2,3),(1,2,2),(4,5,6);
|
||||
insert into t1 values (17,8,9),(11,11,12);
|
||||
create table t2 (c4 int, c5 int, c6 int);
|
||||
insert into t2 values (7,8,9),(10,11,12);
|
||||
let $q=select * from
|
||||
(
|
||||
select c1, sum(c3) as s from t1 group by c1
|
||||
union
|
||||
select c4 as c, sum(c6) as u from t2 group by c
|
||||
) dt
|
||||
where c1 > 6;
|
||||
eval prepare stmt from '$q';
|
||||
execute stmt;
|
||||
execute stmt;
|
||||
|
||||
eval prepare stmt from 'explain format=json $q';
|
||||
--source include/analyze-format.inc
|
||||
execute stmt;
|
||||
--source include/analyze-format.inc
|
||||
execute stmt;
|
||||
|
||||
let $q=select * from
|
||||
(
|
||||
select c1, c2, sum(c3) as s from t1 group by c1, c2 having s > 2
|
||||
union
|
||||
select c4, c5, sum(c6) as u from t2 group by c4, c5 having u > 3
|
||||
) dt
|
||||
where c2 > 5;
|
||||
|
||||
eval prepare stmt from '$q';
|
||||
execute stmt;
|
||||
execute stmt;
|
||||
|
||||
eval prepare stmt from 'explain format=json $q';
|
||||
--source include/analyze-format.inc
|
||||
execute stmt;
|
||||
--source include/analyze-format.inc
|
||||
execute stmt;
|
||||
|
||||
let $q=select *
|
||||
from
|
||||
(
|
||||
select c1, c2, max(c3) as max_c, avg(c3) as avg_c
|
||||
from t1
|
||||
group by c1,c2
|
||||
having max_c < 7
|
||||
union
|
||||
select c4, c5, max(c6) as u, avg(c6) as w
|
||||
from t2
|
||||
group by c4, c5
|
||||
having u < 10
|
||||
) dt,
|
||||
t2
|
||||
where dt.max_c > 6 and t2.c6 > dt.c1;
|
||||
|
||||
eval prepare stmt from '$q';
|
||||
execute stmt;
|
||||
execute stmt;
|
||||
|
||||
eval prepare stmt from 'explain format=json $q';
|
||||
--source include/analyze-format.inc
|
||||
execute stmt;
|
||||
--source include/analyze-format.inc
|
||||
execute stmt;
|
||||
|
||||
drop table t1, t2;
|
||||
|
||||
--echo # End of 10.5 tests
|
||||
|
@ -1557,6 +1557,7 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
|
||||
if (sl != first_sl)
|
||||
{
|
||||
DBUG_ASSERT(sl->item_list.elements == first_sl->item_list.elements);
|
||||
sl->save_item_list_names(thd);
|
||||
List_iterator_fast<Item> it(sl->item_list);
|
||||
List_iterator_fast<Item> nm_it(unit->types);
|
||||
while (Item *item= it++)
|
||||
|
Loading…
x
Reference in New Issue
Block a user