Commit 1d0f1741 authored by Igor Babaev's avatar Igor Babaev

Fixed bug mdev-11313.

The fix for bug 11072 was not complete though it also fixed
the bug mdev-10800.
This patch resolves the problems of all three bugs.
parent b5b68b6b
......@@ -7087,10 +7087,10 @@ 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 TABLE t1 (a INT) ENGINE=MyISAM;
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
CREATE TABLE t3 (c INT);
CREATE TABLE t3 (c INT) ENGINE=MyISAM;
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 (
......@@ -7165,8 +7165,154 @@ EXPLAIN
]
}
}
DROP VIEW v2,v3;
DROP TABLE t1,t2,t3;
CREATE TABLE t4 (d INT, e INT) ENGINE=MyISAM;
INSERT INTO t4 VALUES (1,10),(3,11),(2,10),(2,20),(3,21);
CREATE OR REPLACE VIEW v4 AS
SELECT d, sum(e) AS s FROM t4 GROUP BY d;
set statement optimizer_switch='condition_pushdown_for_derived=off' for SELECT * FROM t1 WHERE a IN (
SELECT b FROM v2 WHERE b < a OR b IN (
SELECT d FROM v4 WHERE s > a
)
);
a
2
SELECT * FROM t1 WHERE a IN (
SELECT b FROM v2 WHERE b < a OR b IN (
SELECT d FROM v4 WHERE s > a
)
);
a
2
explain SELECT * FROM t1 WHERE a IN (
SELECT b FROM v2 WHERE b < a OR b IN (
SELECT d FROM v4 WHERE s > a
)
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1)
3 DEPENDENT SUBQUERY <derived5> index_subquery key0 key0 5 func 2 Using where
5 DERIVED t4 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
explain format=json SELECT * FROM t1 WHERE a IN (
SELECT b FROM v2 WHERE b < a OR b IN (
SELECT d FROM v4 WHERE s > 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": ["d"],
"ref": ["func"],
"rows": 2,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 5,
"filesort": {
"sort_key": "t4.d",
"temporary_table": {
"table": {
"table_name": "t4",
"access_type": "ALL",
"rows": 5,
"filtered": 100
}
}
}
}
}
}
}
}
]
}
}
DROP VIEW v2,v3,v4;
DROP TABLE t1,t2,t3,t4;
#
# MDEV-10800: pushdown of the condition obtained
# after constant row substitution
#
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (3),(4);
CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
SELECT * FROM
( SELECT * FROM t1
WHERE EXISTS ( SELECT * FROM v2 WHERE b = a ) ) AS sq;
a
EXPLAIN FORMAT=JSON
SELECT * FROM
( SELECT * FROM t1
WHERE EXISTS ( SELECT * FROM v2 WHERE b = a ) ) AS sq;
EXPLAIN
{
"query_block": {
"select_id": 1,
"const_condition": "<in_optimizer>(1,exists(subquery#3))",
"table": {
"table_name": "t1",
"access_type": "system",
"rows": 1,
"filtered": 100
},
"subqueries": [
{
"query_block": {
"select_id": 3,
"table": {
"table_name": "<derived4>",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "(v2.b = 1)",
"materialized": {
"query_block": {
"select_id": 4,
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "(t2.b = 1)"
}
}
}
}
}
}
]
}
}
DROP VIEW v2;
DROP TABLE t1,t2;
#
# MDEV-11102: condition pushdown into materialized inner table
# of outer join is not applied as not being valid
......@@ -7376,3 +7522,107 @@ EXPLAIN
}
DROP VIEW v1,v2;
DROP TABLE t1,t2;
#
# MDEV-11313: pushdown of the condition obtained
# after constant row substitution
#
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (50);
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
SELECT ( SELECT COUNT(*) FROM v1 WHERE a = t2.b ) AS f FROM t2 GROUP BY f;
f
0
EXPLAIN FORMAT=JSON
SELECT ( SELECT COUNT(*) FROM v1 WHERE a = t2.b ) AS f FROM t2 GROUP BY f;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t2",
"access_type": "system",
"rows": 1,
"filtered": 100
},
"subqueries": [
{
"query_block": {
"select_id": 2,
"table": {
"table_name": "<derived3>",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "(v1.a = 50)",
"materialized": {
"query_block": {
"select_id": 3,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "(t1.a = 50)"
}
}
}
}
}
}
]
}
}
CREATE TABLE t3 (a INT, b INT) ENGINE=MYISAM;
INSERT INTO t3 VALUES (1,10),(3,11),(2,10),(2,20),(3,21);
CREATE VIEW v2 AS SELECT a, sum(b) AS s FROM t3 GROUP BY a ;
SELECT ( SELECT COUNT(*) FROM v2 WHERE s < t2.b ) AS f FROM t2 GROUP BY f;
f
3
EXPLAIN FORMAT=JSON
SELECT ( SELECT COUNT(*) FROM v2 WHERE s < t2.b ) AS f FROM t2 GROUP BY f;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t2",
"access_type": "system",
"rows": 1,
"filtered": 100
},
"subqueries": [
{
"query_block": {
"select_id": 2,
"table": {
"table_name": "<derived3>",
"access_type": "ALL",
"rows": 5,
"filtered": 100,
"attached_condition": "(v2.s < 50)",
"materialized": {
"query_block": {
"select_id": 3,
"filesort": {
"sort_key": "t3.a",
"temporary_table": {
"table": {
"table_name": "t3",
"access_type": "ALL",
"rows": 5,
"filtered": 100
}
}
}
}
}
}
}
}
]
}
}
DROP VIEW v1,v2;
DROP TABLE t1,t2,t3;
......@@ -957,10 +957,10 @@ drop table t1;
--echo # after constant row substitution
--echo #
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT);
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
CREATE TABLE t3 (c INT);
CREATE TABLE t3 (c INT) ENGINE=MyISAM;
CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3;
SELECT * FROM t1 WHERE a IN (
......@@ -986,8 +986,50 @@ SELECT * FROM t1 WHERE a IN (
)
);
DROP VIEW v2,v3;
DROP TABLE t1,t2,t3;
CREATE TABLE t4 (d INT, e INT) ENGINE=MyISAM;
INSERT INTO t4 VALUES (1,10),(3,11),(2,10),(2,20),(3,21);
CREATE OR REPLACE VIEW v4 AS
SELECT d, sum(e) AS s FROM t4 GROUP BY d;
let $query =
SELECT * FROM t1 WHERE a IN (
SELECT b FROM v2 WHERE b < a OR b IN (
SELECT d FROM v4 WHERE s > a
)
);
eval $no_pushdown $query;
eval $query;
eval explain $query;
eval explain format=json $query;
DROP VIEW v2,v3,v4;
DROP TABLE t1,t2,t3,t4;
--echo #
--echo # MDEV-10800: pushdown of the condition obtained
--echo # after constant row substitution
--echo #
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (3),(4);
CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
SELECT * FROM
( SELECT * FROM t1
WHERE EXISTS ( SELECT * FROM v2 WHERE b = a ) ) AS sq;
EXPLAIN FORMAT=JSON
SELECT * FROM
( SELECT * FROM t1
WHERE EXISTS ( SELECT * FROM v2 WHERE b = a ) ) AS sq;
DROP VIEW v2;
DROP TABLE t1,t2;
--echo #
--echo # MDEV-11102: condition pushdown into materialized inner table
......@@ -1058,3 +1100,29 @@ SELECT * FROM ( SELECT * FROM t1 ) AS sq
DROP VIEW v1,v2;
DROP TABLE t1,t2;
--echo #
--echo # MDEV-11313: pushdown of the condition obtained
--echo # after constant row substitution
--echo #
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (50);
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
SELECT ( SELECT COUNT(*) FROM v1 WHERE a = t2.b ) AS f FROM t2 GROUP BY f;
EXPLAIN FORMAT=JSON
SELECT ( SELECT COUNT(*) FROM v1 WHERE a = t2.b ) AS f FROM t2 GROUP BY f;
CREATE TABLE t3 (a INT, b INT) ENGINE=MYISAM;
INSERT INTO t3 VALUES (1,10),(3,11),(2,10),(2,20),(3,21);
CREATE VIEW v2 AS SELECT a, sum(b) AS s FROM t3 GROUP BY a ;
SELECT ( SELECT COUNT(*) FROM v2 WHERE s < t2.b ) AS f FROM t2 GROUP BY f;
EXPLAIN FORMAT=JSON
SELECT ( SELECT COUNT(*) FROM v2 WHERE s < t2.b ) AS f FROM t2 GROUP BY f;
DROP VIEW v1,v2;
DROP TABLE t1,t2,t3;
......@@ -1560,7 +1560,7 @@ class Item: public Value_source,
{ return 0; }
virtual bool exclusive_dependence_on_grouping_fields_processor(void *arg)
{ return 0; }
virtual bool cleanup_excluding_outer_fields_processor(void *arg)
virtual bool cleanup_excluding_const_fields_processor(void *arg)
{ return cleanup_processor(arg); }
virtual Item *get_copy(THD *thd, MEM_ROOT *mem_root)=0;
......@@ -2664,9 +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); }
bool cleanup_excluding_const_fields_processor(void *arg)
{ return field && const_item() ? 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
......@@ -4282,7 +4282,15 @@ class Item_ref :public Item_ident
{ return depended_from != NULL; }
bool exclusive_dependence_on_grouping_fields_processor(void *arg)
{ return depended_from != NULL; }
};
bool cleanup_excluding_const_fields_processor(void *arg)
{
Item *item= real_item();
if (item && item->type() == FIELD_ITEM &&
((Item_field *) item)->field && item->const_item())
return 0;
return cleanup_processor(arg);
}
};
/*
......
......@@ -1195,9 +1195,9 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
(uchar*) sl);
if (extracted_cond_copy)
{
extracted_cond_copy->walk(
&Item::cleanup_excluding_outer_fields_processor, 0, 0);
sl->cond_pushed_into_where= extracted_cond_copy;
extracted_cond_copy->walk(
&Item::cleanup_excluding_const_fields_processor, 0, 0);
sl->cond_pushed_into_where= extracted_cond_copy;
}
continue;
......@@ -1230,9 +1230,9 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
has been pushed into the where clause of sl
*/
extracted_cond_copy= remove_pushed_top_conjuncts(thd, extracted_cond_copy);
cond_over_grouping_fields->walk(
&Item::cleanup_excluding_outer_fields_processor, 0, 0);
&Item::cleanup_excluding_const_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