Skip to content

Commit f271100

Browse files
committed
Fixed mdev-15162 Query with CTE hangs if assignment operator (:=) is used
If setting user variable was used in the specification of a recursive CTE then Item_func_set_user_var::fix_fields() went into an infinite loop.
1 parent 465979e commit f271100

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

mysql-test/r/cte_recursive.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3079,3 +3079,16 @@ ERROR 21000: The used SELECT statements have a different number of columns
30793079
DROP TABLE a_tbl;
30803080
WITH RECURSIVE x AS (SELECT 1,2 UNION ALL SELECT 1 FROM x) SELECT * FROM x;
30813081
ERROR 21000: The used SELECT statements have a different number of columns
3082+
#
3083+
# MDEV-15162: Setting user variable in recursive CTE
3084+
#
3085+
SET @c=1;
3086+
WITH RECURSIVE cte AS
3087+
(SELECT 5
3088+
UNION
3089+
SELECT @c:=@c+1 FROM cte WHERE @c<3)
3090+
SELECT * FROM cte;
3091+
5
3092+
5
3093+
2
3094+
3

mysql-test/t/cte_recursive.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2113,3 +2113,15 @@ DROP TABLE a_tbl;
21132113

21142114
--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT
21152115
WITH RECURSIVE x AS (SELECT 1,2 UNION ALL SELECT 1 FROM x) SELECT * FROM x;
2116+
2117+
--echo #
2118+
--echo # MDEV-15162: Setting user variable in recursive CTE
2119+
--echo #
2120+
2121+
SET @c=1;
2122+
2123+
WITH RECURSIVE cte AS
2124+
(SELECT 5
2125+
UNION
2126+
SELECT @c:=@c+1 FROM cte WHERE @c<3)
2127+
SELECT * FROM cte;

sql/item_func.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "set_var.h"
5555
#include "debug_sync.h"
5656
#include "sql_base.h"
57+
#include "sql_cte.h"
5758

5859
#ifdef NO_EMBEDDED_ACCESS_CHECKS
5960
#define sp_restore_security_context(A,B) while (0) {}
@@ -4514,10 +4515,13 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
45144515
TABLE_LIST *derived;
45154516
for (derived= unit->derived;
45164517
derived;
4517-
derived= derived->select_lex->master_unit()->derived)
4518+
derived= unit->derived)
45184519
{
45194520
derived->set_materialized_derived();
45204521
derived->prohibit_cond_pushdown= true;
4522+
if (unit->with_element && unit->with_element->is_recursive)
4523+
break;
4524+
unit= derived->select_lex->master_unit();
45214525
}
45224526
}
45234527

0 commit comments

Comments
 (0)