Commit 86cf60a6 authored by Igor Babaev's avatar Igor Babaev

Fixed mdev-14845 Server crashes in st_join_table::is_inner_table_of_outer_join

Do not try to apply the splitting optimization to a materialized
derived if it's specified by a select with impossible where
or if all joined tables of this select are constant.
parent c664c487
...@@ -14772,3 +14772,19 @@ SELECT * FROM v3 JOIN t1 ON (bmax = b); ...@@ -14772,3 +14772,19 @@ SELECT * FROM v3 JOIN t1 ON (bmax = b);
a bmax a b a bmax a b
DROP VIEW v1,v2,v3; DROP VIEW v1,v2,v3;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# MDEV-14845: Impossible where for derived with GROUP BY
#
CREATE TABLE t1 (pk INT PRIMARY KEY);
INSERT INTO t1 VALUES (1),(2);
WITH cte AS ( SELECT pk FROM t1 WHERE pk IS NULL GROUP BY pk )
SELECT * FROM cte;
pk
EXPLAIN EXTENDED WITH cte AS ( SELECT pk FROM t1 WHERE pk IS NULL GROUP BY pk )
SELECT * FROM cte;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 Const row not found
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings:
Note 1003 with cte as (/* select#2 */ select `test`.`t1`.`pk` AS `pk` from `test`.`t1` where 0 group by `test`.`t1`.`pk`)/* select#1 */ select NULL AS `pk` from `cte`
DROP TABLE t1;
...@@ -2519,3 +2519,19 @@ SELECT * FROM v3 JOIN t1 ON (bmax = b); ...@@ -2519,3 +2519,19 @@ SELECT * FROM v3 JOIN t1 ON (bmax = b);
DROP VIEW v1,v2,v3; DROP VIEW v1,v2,v3;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # MDEV-14845: Impossible where for derived with GROUP BY
--echo #
CREATE TABLE t1 (pk INT PRIMARY KEY);
INSERT INTO t1 VALUES (1),(2);
let $q=
WITH cte AS ( SELECT pk FROM t1 WHERE pk IS NULL GROUP BY pk )
SELECT * FROM cte;
eval $q;
eval EXPLAIN EXTENDED $q;
DROP TABLE t1;
...@@ -291,14 +291,15 @@ struct SplM_field_ext_info: public SplM_field_info ...@@ -291,14 +291,15 @@ struct SplM_field_ext_info: public SplM_field_info
3. this is the only select in the specification of T 3. this is the only select in the specification of T
4. condition pushdown is not prohibited into T 4. condition pushdown is not prohibited into T
5. T is not recursive 5. T is not recursive
6. T is either 6. not all of this join are constant or optimized away
6.1. a grouping table with GROUP BY list P 7. T is either
7.1. a grouping table with GROUP BY list P
or or
6.2. a non-grouping table with window functions over the same non-empty 7.2. a non-grouping table with window functions over the same non-empty
partition specified by the PARTITION BY list P partition specified by the PARTITION BY list P
7. P contains some references on the columns of the joined tables C 8. P contains some references on the columns of the joined tables C
occurred also in the select list of this join occurred also in the select list of this join
8. There are defined some keys usable for ref access of fields from C 9. There are defined some keys usable for ref access of fields from C
with available statistics. with available statistics.
@retval @retval
...@@ -315,15 +316,16 @@ bool JOIN::check_for_splittable_materialized() ...@@ -315,15 +316,16 @@ bool JOIN::check_for_splittable_materialized()
!(derived && derived->is_materialized_derived()) || // !(2) !(derived && derived->is_materialized_derived()) || // !(2)
(unit->first_select()->next_select()) || // !(3) (unit->first_select()->next_select()) || // !(3)
(derived->prohibit_cond_pushdown) || // !(4) (derived->prohibit_cond_pushdown) || // !(4)
(derived->is_recursive_with_table())) // !(5) (derived->is_recursive_with_table()) || // !(5)
(table_count == 0 || const_tables == top_join_tab_count)) // !(6)
return false; return false;
if (group_list) // (6.1) if (group_list) // (7.1)
{ {
if (!select_lex->have_window_funcs()) if (!select_lex->have_window_funcs())
partition_list= group_list; partition_list= group_list;
} }
else if (select_lex->have_window_funcs() && else if (select_lex->have_window_funcs() &&
select_lex->window_specs.elements == 1) // (6.2) select_lex->window_specs.elements == 1) // (7.2)
{ {
partition_list= partition_list=
select_lex->window_specs.head()->partition_list->first; select_lex->window_specs.head()->partition_list->first;
...@@ -337,15 +339,15 @@ bool JOIN::check_for_splittable_materialized() ...@@ -337,15 +339,15 @@ bool JOIN::check_for_splittable_materialized()
/* /*
Select from partition_list all candidates for splitting. Select from partition_list all candidates for splitting.
A candidate must be A candidate must be
- field item or refer to such (7.1) - field item or refer to such (8.1)
- item mentioned in the select list (7.2) - item mentioned in the select list (8.2)
Put info about such candidates into the array candidates Put info about such candidates into the array candidates
*/ */
table_map usable_tables= 0; // tables that contains the candidate table_map usable_tables= 0; // tables that contains the candidate
for (ord= partition_list; ord; ord= ord->next) for (ord= partition_list; ord; ord= ord->next)
{ {
Item *ord_item= *ord->item; Item *ord_item= *ord->item;
if (ord_item->real_item()->type() != Item::FIELD_ITEM) // !(7.1) if (ord_item->real_item()->type() != Item::FIELD_ITEM) // !(8.1)
continue; continue;
Field *ord_field= ((Item_field *) (ord_item->real_item()))->field; Field *ord_field= ((Item_field *) (ord_item->real_item()))->field;
...@@ -359,7 +361,7 @@ bool JOIN::check_for_splittable_materialized() ...@@ -359,7 +361,7 @@ bool JOIN::check_for_splittable_materialized()
uint item_no= 0; uint item_no= 0;
while ((item= li++)) while ((item= li++))
{ {
if ((*ord->item)->eq(item, 0)) // (7.2) if ((*ord->item)->eq(item, 0)) // (8.2)
{ {
SplM_field_ext_info new_elem; SplM_field_ext_info new_elem;
new_elem.producing_item= item; new_elem.producing_item= item;
...@@ -374,7 +376,7 @@ bool JOIN::check_for_splittable_materialized() ...@@ -374,7 +376,7 @@ bool JOIN::check_for_splittable_materialized()
item_no++; item_no++;
} }
} }
if (candidates.elements() == 0) // no candidates satisfying (7.1) && (7.2) if (candidates.elements() == 0) // no candidates satisfying (8.1) && (8.2)
return false; return false;
/* /*
...@@ -432,7 +434,7 @@ bool JOIN::check_for_splittable_materialized() ...@@ -432,7 +434,7 @@ bool JOIN::check_for_splittable_materialized()
spl_field_cnt--; spl_field_cnt--;
} }
if (!spl_field_cnt) // No candidate field can be accessed by ref => !(8) if (!spl_field_cnt) // No candidate field can be accessed by ref => !(9)
return false; return false;
/* /*
......
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