Skip to content

Commit c2300d0

Browse files
committed
MDEV-28617 Crash with INSERT...SELECT using derived table in GROUP BY clause
This bug manifested itself for INSERT...SELECT and DELETE statements whose WHERE condition used an IN/ANY/ALL predicand or a EXISTS predicate with such grouping subquery that: - its GROUP BY clause could be eliminated, - the GROUP clause contained a subquery over a mergeable derived table referencing the updated table. The bug ultimately caused a server crash when the prepare phase of the statement processing was executed. This happened after removal redundant subqueries used in the eliminated GROUP BY clause from the statement tree. The function that excluded the subqueries from the did not do it properly. As a result the specification of any derived table contained in a removed subquery was not marked as excluded. Approved by Oleksandr Byelkin <sanja@mariadb.com>
1 parent 07a670b commit c2300d0

File tree

3 files changed

+175
-3
lines changed

3 files changed

+175
-3
lines changed

mysql-test/main/insert_select.result

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,3 +954,92 @@ ERROR 23000: Duplicate entry '-128' for key 'a'
954954
DROP TABLE t1, t2;
955955
DROP PROCEDURE p1;
956956
# End of 10.2 test
957+
#
958+
# MDEV-28617: INSERT ... SELECT with redundant IN subquery in GROUP BY
959+
# list that uses mergeable derived table containing
960+
# reference to target table
961+
#
962+
create table t1 (a int);
963+
create table t2 (b int);
964+
create table t3 (c int);
965+
insert into t1 values (3), (1);
966+
insert into t2 values (3), (2);
967+
insert into t3 values (4), (2);
968+
insert into t1
969+
select b from t2
970+
where b in (select c from t3
971+
group by (select * from (select a from t1) dt where a = 1));
972+
select * from t1;
973+
a
974+
3
975+
1
976+
2
977+
delete from t1;
978+
insert into t1 values (3), (1);
979+
insert into t1
980+
select b from t2
981+
where b >= any (select c from t3
982+
group by (select * from (select a from t1) dt where a = 1));
983+
select * from t1;
984+
a
985+
3
986+
1
987+
3
988+
2
989+
delete from t1;
990+
insert into t1 values (3), (1);
991+
insert into t1
992+
select b from t2
993+
where b <= all (select c from t3
994+
group by (select * from (select a from t1) dt where a = 1));
995+
select * from t1;
996+
a
997+
3
998+
1
999+
2
1000+
delete from t1;
1001+
insert into t1 values (3), (1);
1002+
insert into t1
1003+
select b from t2
1004+
where exists (select c from t3
1005+
group by (select * from (select a from t1) dt where a = 1));
1006+
select * from t1;
1007+
a
1008+
3
1009+
1
1010+
3
1011+
2
1012+
delete from t1;
1013+
insert into t1 values (3), (1);
1014+
prepare stmt from "
1015+
insert into t1
1016+
select b from t2
1017+
where b in (select c from t3
1018+
group by (select * from (select a from t1) dt where a = 1));
1019+
";
1020+
execute stmt;
1021+
select * from t1;
1022+
a
1023+
3
1024+
1
1025+
2
1026+
delete from t1;
1027+
insert into t1 values (3), (1);
1028+
execute stmt;
1029+
select * from t1;
1030+
a
1031+
3
1032+
1
1033+
2
1034+
delete from t1;
1035+
insert into t1 values (3), (1);
1036+
delete from t1
1037+
where exists (select b from t2
1038+
where b in (select c from t3
1039+
group by (select * from (select a from t1) dt
1040+
where a = 1)));
1041+
select * from t1;
1042+
a
1043+
deallocate prepare stmt;
1044+
drop table t1,t2,t3;
1045+
# End of 10.3 test

mysql-test/main/insert_select.test

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,3 +514,85 @@ DROP TABLE t1, t2;
514514
DROP PROCEDURE p1;
515515

516516
--echo # End of 10.2 test
517+
518+
--echo #
519+
--echo # MDEV-28617: INSERT ... SELECT with redundant IN subquery in GROUP BY
520+
--echo # list that uses mergeable derived table containing
521+
--echo # reference to target table
522+
--echo #
523+
524+
create table t1 (a int);
525+
create table t2 (b int);
526+
create table t3 (c int);
527+
528+
insert into t1 values (3), (1);
529+
insert into t2 values (3), (2);
530+
insert into t3 values (4), (2);
531+
532+
insert into t1
533+
select b from t2
534+
where b in (select c from t3
535+
group by (select * from (select a from t1) dt where a = 1));
536+
select * from t1;
537+
538+
delete from t1;
539+
insert into t1 values (3), (1);
540+
541+
insert into t1
542+
select b from t2
543+
where b >= any (select c from t3
544+
group by (select * from (select a from t1) dt where a = 1));
545+
select * from t1;
546+
547+
delete from t1;
548+
insert into t1 values (3), (1);
549+
550+
insert into t1
551+
select b from t2
552+
where b <= all (select c from t3
553+
group by (select * from (select a from t1) dt where a = 1));
554+
select * from t1;
555+
556+
delete from t1;
557+
insert into t1 values (3), (1);
558+
559+
insert into t1
560+
select b from t2
561+
where exists (select c from t3
562+
group by (select * from (select a from t1) dt where a = 1));
563+
select * from t1;
564+
565+
delete from t1;
566+
insert into t1 values (3), (1);
567+
568+
prepare stmt from "
569+
insert into t1
570+
select b from t2
571+
where b in (select c from t3
572+
group by (select * from (select a from t1) dt where a = 1));
573+
";
574+
575+
execute stmt;
576+
select * from t1;
577+
578+
delete from t1;
579+
insert into t1 values (3), (1);
580+
581+
execute stmt;
582+
select * from t1;
583+
584+
delete from t1;
585+
insert into t1 values (3), (1);
586+
587+
delete from t1
588+
where exists (select b from t2
589+
where b in (select c from t3
590+
group by (select * from (select a from t1) dt
591+
where a = 1)));
592+
select * from t1;
593+
594+
deallocate prepare stmt;
595+
596+
drop table t1,t2,t3;
597+
598+
--echo # End of 10.3 test

sql/sql_lex.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,6 +2530,7 @@ void st_select_lex_node::fast_exclude()
25302530
for (; slave; slave= slave->next)
25312531
slave->fast_exclude();
25322532

2533+
prev= NULL; // to ensure correct behavior of st_select_lex_unit::is_excluded()
25332534
}
25342535

25352536

@@ -2604,16 +2605,16 @@ void st_select_lex_node::exclude_from_tree()
26042605
*/
26052606
void st_select_lex_node::exclude()
26062607
{
2607-
/* exclude from global list */
2608-
fast_exclude();
2609-
/* exclude from other structures */
2608+
/* exclude the node from the tree */
26102609
exclude_from_tree();
26112610
/*
26122611
We do not need following statements, because prev pointer of first
26132612
list element point to master->slave
26142613
if (master->slave == this)
26152614
master->slave= next;
26162615
*/
2616+
/* exclude all nodes under this excluded node */
2617+
fast_exclude();
26172618
}
26182619

26192620

0 commit comments

Comments
 (0)