mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
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.
This commit is contained in:
parent
ebe5ebba16
commit
68e7d92c4c
4 changed files with 131 additions and 3 deletions
|
@ -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 @@ public:
|
|||
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 @@ public:
|
|||
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)
|
||||
|
|
Loading…
Reference in a new issue