summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2020-06-23 23:28:37 +0300
committerSergei Petrunia <psergey@askmonty.org>2020-06-23 23:28:37 +0300
commite9b7bbd85f5ec1b4858b1278a620c84b1949699e (patch)
tree510706659bbbef51e13542b65c6b28f0af0f9051
parentb7324e133f569acde8622429425f6e608c4d88a1 (diff)
downloadmariadb-git-bb-10.4-mdev22993.tar.gz
MDEV-22993: Crash on EXPLAIN with PUSHED DOWN SELECT and subquerybb-10.4-mdev22993
- select_describe() should not attempt to produce query plans for subqueries if the query is handled by a Select Handler. - JOIN::save_explain_data_intern should not add links to Explain_select for children selects if: 1. The whole query is handled by the Select Handler, or 2. this select (and so its children) is handled by Derived Handler.
-rw-r--r--mysql-test/suite/federated/federatedx_create_handlers.result93
-rw-r--r--mysql-test/suite/federated/federatedx_create_handlers.test34
-rw-r--r--sql/sql_select.cc54
3 files changed, 143 insertions, 38 deletions
diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result
index 65a9d52803f..63e56bff425 100644
--- a/mysql-test/suite/federated/federatedx_create_handlers.result
+++ b/mysql-test/suite/federated/federatedx_create_handlers.result
@@ -209,7 +209,6 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 7
1 PRIMARY <derived2> ref key0 key0 18 federated.t3.name 2
2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL
-3 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 Using temporary
ANALYZE FORMAT=JSON
SELECT *
FROM federated.t3, (SELECT t1.name FROM federated.t1
@@ -251,25 +250,7 @@ ANALYZE
"select_id": 2,
"table": {
"message": "Pushed derived"
- },
- "subqueries": [
- {
- "query_block": {
- "select_id": 3,
- "temporary_table": {
- "table": {
- "table_name": "t2",
- "access_type": "ALL",
- "r_loops": 0,
- "rows": 7,
- "r_rows": null,
- "filtered": 100,
- "r_filtered": null
- }
- }
- }
- }
- ]
+ }
}
}
}
@@ -319,6 +300,78 @@ select @var;
@var
xxx
select name into outfile 'tmp.txt' from federated.t1;
+#
+# MDEV-22993: Crash on EXPLAIN with PUSHED DOWN SELECT and subquery
+#
+explain
+select * from federated.t1
+where name in (select name from federated.t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL
+explain format=json
+select * from federated.t1
+where name in (select name from federated.t2);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "message": "Pushed select"
+ }
+ }
+}
+#
+# MDEV-22993, testcase #2: EXPLAIN output doesn't make sense when
+# derived table pushdown is used.
+#
+create table t5 (a int) engine=myisam;
+insert into t5 values (1),(2);
+# Must not show lines with id=3
+explain
+select * from t5,
+(select id from federated.t1
+where name in (select name from federated.t2) or name like 'foo%') as TQ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t5 ALL NULL NULL NULL NULL 2
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
+2 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL
+# Must not show elements with select_id=3
+explain format=json
+select * from t5,
+(select id from federated.t1
+where name in (select name from federated.t2) or name like 'foo%') as TQ;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t5",
+ "access_type": "ALL",
+ "rows": 2,
+ "filtered": 100
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100
+ },
+ "buffer_type": "flat",
+ "buffer_size": "65",
+ "join_type": "BNL",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "message": "Pushed derived"
+ }
+ }
+ }
+ }
+ }
+}
+drop table t5;
DROP TABLE federated.t1, federated.t2, federated.t3, federated.t4;
connection slave;
DROP TABLE federated.t1, federated.t2;
diff --git a/mysql-test/suite/federated/federatedx_create_handlers.test b/mysql-test/suite/federated/federatedx_create_handlers.test
index 42a03e60d67..d765588b79b 100644
--- a/mysql-test/suite/federated/federatedx_create_handlers.test
+++ b/mysql-test/suite/federated/federatedx_create_handlers.test
@@ -167,6 +167,40 @@ select name into outfile 'tmp.txt' from federated.t1;
let $path=`select concat(@@datadir, 'test/tmp.txt')`;
remove_file $path;
+--echo #
+--echo # MDEV-22993: Crash on EXPLAIN with PUSHED DOWN SELECT and subquery
+--echo #
+
+explain
+select * from federated.t1
+where name in (select name from federated.t2);
+
+explain format=json
+select * from federated.t1
+where name in (select name from federated.t2);
+
+--echo #
+--echo # MDEV-22993, testcase #2: EXPLAIN output doesn't make sense when
+--echo # derived table pushdown is used.
+--echo #
+
+create table t5 (a int) engine=myisam;
+insert into t5 values (1),(2);
+
+--echo # Must not show lines with id=3
+explain
+select * from t5,
+(select id from federated.t1
+ where name in (select name from federated.t2) or name like 'foo%') as TQ;
+
+--echo # Must not show elements with select_id=3
+explain format=json
+select * from t5,
+(select id from federated.t1
+ where name in (select name from federated.t2) or name like 'foo%') as TQ;
+
+drop table t5;
+
DROP TABLE federated.t1, federated.t2, federated.t3, federated.t4;
connection slave;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 040c9acd2ae..0ca5ab23288 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -26840,24 +26840,33 @@ int JOIN::save_explain_data_intern(Explain_query *output,
output->add_node(xpl_sel);
}
- for (SELECT_LEX_UNIT *tmp_unit= join->select_lex->first_inner_unit();
- tmp_unit;
- tmp_unit= tmp_unit->next_unit())
+ /*
+ Don't try to add query plans for child selects if this select was pushed
+ down into a Smart Storage Engine:
+ - the entire statement was pushed down ("PUSHED SELECT"), or
+ - this derived table was pushed down ("PUSHED DERIVED")
+ */
+ if (!select_lex->pushdown_select && select_lex->type != pushed_derived_text)
{
- /*
- Display subqueries only if
- (1) they are not parts of ON clauses that were eliminated by table
- elimination.
- (2) they are not merged derived tables
- (3) they are not hanging CTEs (they are needed for execution)
- */
- if (!(tmp_unit->item && tmp_unit->item->eliminated) && // (1)
- (!tmp_unit->derived ||
- tmp_unit->derived->is_materialized_derived()) && // (2)
- !(tmp_unit->with_element &&
- (!tmp_unit->derived || !tmp_unit->derived->derived_result))) // (3)
- {
- explain->add_child(tmp_unit->first_select()->select_number);
+ for (SELECT_LEX_UNIT *tmp_unit= join->select_lex->first_inner_unit();
+ tmp_unit;
+ tmp_unit= tmp_unit->next_unit())
+ {
+ /*
+ Display subqueries only if
+ (1) they are not parts of ON clauses that were eliminated by table
+ elimination.
+ (2) they are not merged derived tables
+ (3) they are not hanging CTEs (they are needed for execution)
+ */
+ if (!(tmp_unit->item && tmp_unit->item->eliminated) && // (1)
+ (!tmp_unit->derived ||
+ tmp_unit->derived->is_materialized_derived()) && // (2)
+ !(tmp_unit->with_element &&
+ (!tmp_unit->derived || !tmp_unit->derived->derived_result))) // (3)
+ {
+ explain->add_child(tmp_unit->first_select()->select_number);
+ }
}
}
@@ -26890,7 +26899,16 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
THD *thd=join->thd;
select_result *result=join->result;
DBUG_ENTER("select_describe");
-
+
+ if (join->select_lex->pushdown_select)
+ {
+ /*
+ The whole statement was pushed down to a Smart Storage Engine. Do not
+ attempt to produce a query plan locally.
+ */
+ DBUG_VOID_RETURN;
+ }
+
/* Update the QPF with latest values of using_temporary, using_filesort */
for (SELECT_LEX_UNIT *unit= join->select_lex->first_inner_unit();
unit;