Commit 68e7d92c authored by Igor Babaev's avatar Igor Babaev

Fixed bug mdev-11072.

In a general case the conditions with outer fields cannot
be pushed into materialized views / derived tables.
However if the outer field in the condition refers to a
single row table then the condition may be pushable.
In this case a special care should be taken for outer
fields when pushing the condition into a materialized view /
derived table.
parent ebe5ebba
......@@ -7083,3 +7083,87 @@ a
3
6
drop table t1;
#
# MDEV-11072: pushdown of the condition obtained
# after constant row substitution
#
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT);
CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
CREATE TABLE t3 (c INT);
CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3;
SELECT * FROM t1 WHERE a IN (
SELECT b FROM v2 WHERE b < a OR b IN (
SELECT c FROM v3 WHERE c = a
)
);
a
INSERT INTO t1 VALUES (2);
INSERT INTO t2 VALUES (3), (2);
INSERT INTO t3 VALUES (4), (1), (2), (7);
SELECT * FROM t1 WHERE a IN (
SELECT b FROM v2 WHERE b < a OR b IN (
SELECT c FROM v3 WHERE c = a
)
);
a
2
EXPLAIN FORMAT=JSON
SELECT * FROM t1 WHERE a IN (
SELECT b FROM v2 WHERE b < a OR b IN (
SELECT c FROM v3 WHERE c = a
)
);
EXPLAIN
{
"query_block": {
"select_id": 1,
"const_condition": "(0 or <in_optimizer>(2,<exists>(subquery#3)))",
"table": {
"table_name": "t1",
"access_type": "system",
"rows": 1,
"filtered": 100
},
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "(t2.b = 2)",
"first_match": "t1"
},
"subqueries": [
{
"query_block": {
"select_id": 3,
"table": {
"table_name": "<derived5>",
"access_type": "index_subquery",
"possible_keys": ["key0"],
"key": "key0",
"key_length": "5",
"used_key_parts": ["c"],
"ref": ["func"],
"rows": 2,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 5,
"table": {
"table_name": "t3",
"access_type": "ALL",
"rows": 4,
"filtered": 100,
"attached_condition": "(t3.c = 2)"
}
}
}
}
}
}
]
}
}
DROP VIEW v2,v3;
DROP TABLE t1,t2,t3;
......@@ -951,3 +951,40 @@ select * from
order by a limit 5) t where t.a not in (2,9);
drop table t1;
--echo #
--echo # MDEV-11072: pushdown of the condition obtained
--echo # after constant row substitution
--echo #
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT);
CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
CREATE TABLE t3 (c INT);
CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3;
SELECT * FROM t1 WHERE a IN (
SELECT b FROM v2 WHERE b < a OR b IN (
SELECT c FROM v3 WHERE c = a
)
);
INSERT INTO t1 VALUES (2);
INSERT INTO t2 VALUES (3), (2);
INSERT INTO t3 VALUES (4), (1), (2), (7);
SELECT * FROM t1 WHERE a IN (
SELECT b FROM v2 WHERE b < a OR b IN (
SELECT c FROM v3 WHERE c = a
)
);
EXPLAIN FORMAT=JSON
SELECT * FROM t1 WHERE a IN (
SELECT b FROM v2 WHERE b < a OR b IN (
SELECT c FROM v3 WHERE c = a
)
);
DROP VIEW v2,v3;
DROP TABLE t1,t2,t3;
......@@ -1559,7 +1559,9 @@ class Item: public Value_source,
virtual bool exclusive_dependence_on_table_processor(void *map)
{ return 0; }
virtual bool exclusive_dependence_on_grouping_fields_processor(void *arg)
{ return 0; }
{ return 0; }
virtual bool cleanup_excluding_outer_fields_processor(void *arg)
{ return cleanup_processor(arg); }
virtual Item *get_copy(THD *thd, MEM_ROOT *mem_root)=0;
......@@ -2662,6 +2664,9 @@ class Item_field :public Item_ident
virtual void print(String *str, enum_query_type query_type);
bool exclusive_dependence_on_table_processor(void *map);
bool exclusive_dependence_on_grouping_fields_processor(void *arg);
bool cleanup_excluding_outer_fields_processor(void *arg)
{ return depended_from ? 0 :cleanup_processor(arg); }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_field>(thd, mem_root, this); }
bool is_outer_field() const
......
......@@ -1195,7 +1195,8 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
(uchar*) sl);
if (extracted_cond_copy)
{
extracted_cond_copy->walk(&Item::cleanup_processor, 0, 0);
extracted_cond_copy->walk(
&Item::cleanup_excluding_outer_fields_processor, 0, 0);
sl->cond_pushed_into_where= extracted_cond_copy;
}
......@@ -1230,7 +1231,8 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
*/
extracted_cond_copy= remove_pushed_top_conjuncts(thd, extracted_cond_copy);
cond_over_grouping_fields->walk(&Item::cleanup_processor, 0, 0);
cond_over_grouping_fields->walk(
&Item::cleanup_excluding_outer_fields_processor, 0, 0);
sl->cond_pushed_into_where= cond_over_grouping_fields;
if (!extracted_cond_copy)
......
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