Commit 6d29c852 authored by Igor Babaev's avatar Igor Babaev

MDEV-17354 Server crashes in add_key_field / .. / Item_func_null_predicate::add_key_fields

           upon INSERT .. SELECT

The function Item *Item_direct_view_ref::derived_field_transformer_for_where()
erroneously did not strip off ref wrappers from references to materialized
derived tables / views. As a result the expressions that contained some
references of the type Item_direct_view_ref to columns of a materialized
derived table / view V were pushed into V incorrectly. This could cause
crashes for some INSERT ... SELECT statements.
parent 81a5b6cc
......@@ -10241,3 +10241,149 @@ a b c
1 2 2
3 2 2
DROP TABLE t1;
#
# MDEV-17354: INSERT SELECT with condition pushdown into derived
#
CREATE TABLE t1 (f INT NOT NULL);
INSERT INTO t1 VALUES (3), (7), (3);
CREATE ALGORITHM= TEMPTABLE VIEW v1 AS SELECT * FROM ( SELECT * FROM t1 ) AS sq;
INSERT INTO t1
SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ) AS t WHERE f IS NOT NULL;
EXPLAIN INSERT INTO t1
SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ) AS t WHERE f IS NOT NULL;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 144 Using where
2 DERIVED <derived3> ALL NULL NULL NULL NULL 12
2 DERIVED t1 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
3 DERIVED t1 ALL NULL NULL NULL NULL 12
EXPLAIN FORMAT=JSON INSERT INTO t1
SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ) AS t WHERE f IS NOT NULL;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 144,
"filtered": 100,
"attached_condition": "t.f is not null",
"materialized": {
"query_block": {
"select_id": 2,
"table": {
"table_name": "<derived3>",
"access_type": "ALL",
"rows": 12,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 3,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 12,
"filtered": 100
}
}
}
},
"block-nl-join": {
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 12,
"filtered": 100,
"attached_condition": "t1.f is not null"
},
"buffer_type": "flat",
"buffer_size": "256Kb",
"join_type": "BNL"
}
}
}
}
}
}
SELECT * FROM t1;
f
3
7
3
3
3
3
7
7
7
3
3
3
DELETE FROM t1;
INSERT INTO t1 VALUES (3), (7), (3);
INSERT INTO t1
SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ON v1.f=t1.f) AS t
WHERE f IS NOT NULL;
EXPLAIN FORMAT=JSON INSERT INTO t1
SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ON v1.f=t1.f) AS t
WHERE f IS NOT NULL;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 16,
"filtered": 100,
"attached_condition": "t.f is not null",
"materialized": {
"query_block": {
"select_id": 2,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 8,
"filtered": 100,
"attached_condition": "t1.f is not null"
},
"table": {
"table_name": "<derived3>",
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
"key_length": "4",
"used_key_parts": ["f"],
"ref": ["test.t1.f"],
"rows": 2,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 3,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 8,
"filtered": 100,
"attached_condition": "t1.f is not null"
}
}
}
}
}
}
}
}
}
SELECT * FROM t1;
f
3
7
3
3
3
7
3
3
DROP VIEW v1;
DROP TABLE t1;
......@@ -2042,3 +2042,36 @@ SELECT * FROM
WHERE ((a,b) IN ((1,2),(3,2)));
DROP TABLE t1;
--echo #
--echo # MDEV-17354: INSERT SELECT with condition pushdown into derived
--echo #
CREATE TABLE t1 (f INT NOT NULL);
INSERT INTO t1 VALUES (3), (7), (3);
CREATE ALGORITHM= TEMPTABLE VIEW v1 AS SELECT * FROM ( SELECT * FROM t1 ) AS sq;
let $q1=
INSERT INTO t1
SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ) AS t WHERE f IS NOT NULL;
eval $q1;
eval EXPLAIN $q1;
eval EXPLAIN FORMAT=JSON $q1;
SELECT * FROM t1;
DELETE FROM t1;
INSERT INTO t1 VALUES (3), (7), (3);
let $q2=
INSERT INTO t1
SELECT * FROM ( SELECT t1.f FROM v1 JOIN t1 ON v1.f=t1.f) AS t
WHERE f IS NOT NULL;
eval $q2;
eval EXPLAIN FORMAT=JSON $q2;
SELECT * FROM t1;
DROP VIEW v1;
DROP TABLE t1;
......@@ -7214,7 +7214,7 @@ Item *Item_direct_view_ref::derived_field_transformer_for_where(THD *thd,
DBUG_ASSERT (producing_item != NULL);
return producing_item->build_clone(thd, thd->mem_root);
}
return this;
return (*ref);
}
static
......
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