MDEV-32395: update_depend_map_for_order: SEGV at /mariadb-11.3.0/sql/sql_select.cc:16583

MDEV-32329 (patch) pushdown from having into where: Server crashes at sub_select

When generating an Item_equal with a Item_ref that refers to a field
outside of a subselect, remove_item_direct_ref() causes the dependency
(depended_from) on the outer select to be lost, which causes trouble
for code downstream that can no longer determine the scope of the Item.
Not calling remove_item_direct_ref() retains the Item's dependency.

Test cases from MDEV-32395 and MDEV-32329 are included.

Some fixes from other developers:

Monty:
- Fixed wrong code in Item_equal::create_pushable_equalities()
  that could cause wrong item to be used if there was no matching items.
Daniel Black:
- Added test cases from MDEV-32329
Igor Babaev:
- Provided fix for removing call to remove_item_direct_ref() in
  eliminate_item_equal()

MDEV-32395: update_depend_map_for_order: SEGV at /mariadb-11.3.0/sql/sql_select.cc:16583

Include test cases from MDEV-32329.
This commit is contained in:
Jason Cu 2023-11-16 15:34:53 -08:00 committed by Monty
parent 8e9aa9c6b0
commit 2bf9f0d422
5 changed files with 112 additions and 21 deletions

View file

@ -19078,4 +19078,58 @@ f a c
0 0 -1
DROP VIEW v;
DROP TABLE t1;
#
# MDEV-32395: update_depend_map_for_order: SEGV at
# /mariadb-11.3.0/sql/sql_select.cc:16583
#
create table t1 (c1 int);
insert into t1 values (1), (2);
create table t2 (c2 int);
insert into t2 values (1), (2);
create table t3 (c3 int);
insert into t3 values (1), (2);
set statement optimizer_switch='condition_pushdown_for_derived=off,condition_pushdown_for_subquery=off,condition_pushdown_from_having=off' for
select t1.c1 as a from t2, t1 where t1.c1=t2.c2
order by (select c3 from t3 group by a having a=2);
a
1
2
drop table t1, t2, t3;
# Test case 2
CREATE TABLE t1 ( x BOOLEAN NOT NULL );
INSERT INTO t1 ( x ) VALUES ( 1 ) ;
UPDATE t1 SET x = 1 WHERE x = 1 ;
INSERT INTO t1 ( x ) VALUES ( 1 ) , ( x IN ( SELECT x FROM ( SELECT ( SELECT EXISTS ( SELECT * FROM ( SELECT DISTINCT ( - CASE WHEN x = 1 THEN 1 ELSE x + 1 END >= x IS NOT NULL = 1 AND x = 1 ) OR x = x OR x = 'x' FROM t1 AS x GROUP BY x ) AS x WHERE 1 / x GROUP BY x HAVING ( 1 = 1 AND x = 1 ) ) FROM t1 GROUP BY EXISTS ( SELECT 1 ) ) FROM t1 UNION SELECT x FROM t1 ) AS x ) ) ;
DROP TABLE t1;
# Test case 3
CREATE TABLE t0 ( c6 INT , c21 INT ) ;
INSERT INTO t0 VALUES ( 55 , -95 ) , ( 9 , 90 ) ;
ALTER TABLE t0 ADD COLUMN c37 INT AFTER c6 ;
INSERT INTO t0 VALUES ( ) , ( ) ;
SELECT t0 . c6 AS c42 FROM ( SELECT t0 . c6 = TRIM( TRAILING FROM 96 ) SOUNDS LIKE CONVERT ( t0 . c6 , UNSIGNED ) >> PI ( ) AS c49 FROM t0 ) AS t1 JOIN t0 ON RTRIM ( - RAND ( -66 ) BETWEEN FIND_IN_SET ( 20 , UNHEX ( -80 ) IS NULL OR IF ( 85 , -83 , -113 ) ) AND -125 ) / EXP ( c21 ) = t1 . c49 ORDER BY c42 , ( c42 + ( SELECT c21 AS c61 FROM t0 WHERE t0 . c37 >= -19.601384 = RAND ( ) / TRIM( t0 . c21 FROM 'C@rG3D(#9*17(a.,rV' ) = -106 GROUP BY c21 , c42 HAVING c42 = -73 LIMIT 1 ) ) ;
c42
9
9
55
55
drop table t0;
#
# MDEV-32329 pushdown from having into where: Server crashes at sub_select
#
WITH RECURSIVE cte AS ( SELECT 1 as x UNION SELECT x FROM cte)
SELECT ( SELECT 1 FROM ( SELECT 1 FROM cte) dt GROUP BY x HAVING x= 1 )
FROM cte
GROUP BY 1 ;
( SELECT 1 FROM ( SELECT 1 FROM cte) dt GROUP BY x HAVING x= 1 )
1
# Test case 2
WITH
cte1 AS ( SELECT 1 as x UNION SELECT 1),
cte2 AS ( SELECT 1 as x UNION SELECT 1)
SELECT
( SELECT 1 FROM ( SELECT 1 FROM cte1) dt GROUP BY x HAVING x= 1 )
FROM cte2
GROUP BY 1 ;
( SELECT 1 FROM ( SELECT 1 FROM cte1) dt GROUP BY x HAVING x= 1 )
1
# End of 10.5 tests

View file

@ -4217,5 +4217,57 @@ SELECT * FROM v,t1 WHERE f = DEFAULT(c);
DROP VIEW v;
DROP TABLE t1;
--echo #
--echo # MDEV-32395: update_depend_map_for_order: SEGV at
--echo # /mariadb-11.3.0/sql/sql_select.cc:16583
--echo #
create table t1 (c1 int);
insert into t1 values (1), (2);
create table t2 (c2 int);
insert into t2 values (1), (2);
create table t3 (c3 int);
insert into t3 values (1), (2);
set statement optimizer_switch='condition_pushdown_for_derived=off,condition_pushdown_for_subquery=off,condition_pushdown_from_having=off' for
select t1.c1 as a from t2, t1 where t1.c1=t2.c2
order by (select c3 from t3 group by a having a=2);
drop table t1, t2, t3;
--echo # Test case 2
CREATE TABLE t1 ( x BOOLEAN NOT NULL );
INSERT INTO t1 ( x ) VALUES ( 1 ) ;
UPDATE t1 SET x = 1 WHERE x = 1 ;
INSERT INTO t1 ( x ) VALUES ( 1 ) , ( x IN ( SELECT x FROM ( SELECT ( SELECT EXISTS ( SELECT * FROM ( SELECT DISTINCT ( - CASE WHEN x = 1 THEN 1 ELSE x + 1 END >= x IS NOT NULL = 1 AND x = 1 ) OR x = x OR x = 'x' FROM t1 AS x GROUP BY x ) AS x WHERE 1 / x GROUP BY x HAVING ( 1 = 1 AND x = 1 ) ) FROM t1 GROUP BY EXISTS ( SELECT 1 ) ) FROM t1 UNION SELECT x FROM t1 ) AS x ) ) ;
DROP TABLE t1;
--echo # Test case 3
CREATE TABLE t0 ( c6 INT , c21 INT ) ;
INSERT INTO t0 VALUES ( 55 , -95 ) , ( 9 , 90 ) ;
ALTER TABLE t0 ADD COLUMN c37 INT AFTER c6 ;
INSERT INTO t0 VALUES ( ) , ( ) ;
SELECT t0 . c6 AS c42 FROM ( SELECT t0 . c6 = TRIM( TRAILING FROM 96 ) SOUNDS LIKE CONVERT ( t0 . c6 , UNSIGNED ) >> PI ( ) AS c49 FROM t0 ) AS t1 JOIN t0 ON RTRIM ( - RAND ( -66 ) BETWEEN FIND_IN_SET ( 20 , UNHEX ( -80 ) IS NULL OR IF ( 85 , -83 , -113 ) ) AND -125 ) / EXP ( c21 ) = t1 . c49 ORDER BY c42 , ( c42 + ( SELECT c21 AS c61 FROM t0 WHERE t0 . c37 >= -19.601384 = RAND ( ) / TRIM( t0 . c21 FROM 'C@rG3D(#9*17(a.,rV' ) = -106 GROUP BY c21 , c42 HAVING c42 = -73 LIMIT 1 ) ) ;
drop table t0;
--echo #
--echo # MDEV-32329 pushdown from having into where: Server crashes at sub_select
--echo #
WITH RECURSIVE cte AS ( SELECT 1 as x UNION SELECT x FROM cte)
SELECT ( SELECT 1 FROM ( SELECT 1 FROM cte) dt GROUP BY x HAVING x= 1 )
FROM cte
GROUP BY 1 ;
--echo # Test case 2
WITH
cte1 AS ( SELECT 1 as x UNION SELECT 1),
cte2 AS ( SELECT 1 as x UNION SELECT 1)
SELECT
( SELECT 1 FROM ( SELECT 1 FROM cte1) dt GROUP BY x HAVING x= 1 )
FROM cte2
GROUP BY 1 ;
--echo # End of 10.5 tests

View file

@ -2511,12 +2511,6 @@ public:
*/
virtual void under_not(Item_func_not * upper
__attribute__((unused))) {};
/*
If Item_field is wrapped in Item_direct_wrep remove this Item_direct_ref
wrapper.
*/
virtual Item *remove_item_direct_ref() { return this; }
void register_in(THD *thd);
@ -5758,11 +5752,6 @@ public:
With_sum_func_cache* get_with_sum_func_cache() override { return this; }
Item *field_transformer_for_having_pushdown(THD *thd, uchar *arg) override
{ return (*ref)->field_transformer_for_having_pushdown(thd, arg); }
Item *remove_item_direct_ref() override
{
*ref= (*ref)->remove_item_direct_ref();
return this;
}
};
@ -5810,8 +5799,6 @@ public:
Ref_Type ref_type() override { return DIRECT_REF; }
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_direct_ref>(thd, this); }
Item *remove_item_direct_ref() override
{ return (*ref)->remove_item_direct_ref(); }
};
@ -6194,7 +6181,6 @@ public:
{ return get_item_copy<Item_direct_view_ref>(thd, this); }
Item *field_transformer_for_having_pushdown(THD *, uchar *) override
{ return this; }
Item *remove_item_direct_ref() override { return this; }
};

View file

@ -7823,10 +7823,11 @@ bool Item_equal::create_pushable_equalities(THD *thd,
while ((item=it++))
{
left_item= item;
if (checker && !((item->*checker) (arg)))
continue;
break;
if (!checker || ((item->*checker)(arg)))
{
left_item= item;
break;
}
}
if (!left_item)

View file

@ -16266,9 +16266,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels,
*/
Item *head_item= (!item_const && current_sjm &&
current_sjm_head != field_item) ? current_sjm_head: head;
eq_item= new (thd->mem_root) Item_func_eq(thd,
field_item->remove_item_direct_ref(),
head_item->remove_item_direct_ref());
eq_item= new (thd->mem_root) Item_func_eq(thd, field_item, head_item);
if (!eq_item || eq_item->set_cmp_func(thd))
return 0;