diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result index 7bbdcb47f26..db1c95788e8 100644 --- a/mysql-test/r/cte_recursive.result +++ b/mysql-test/r/cte_recursive.result @@ -3050,3 +3050,16 @@ Warnings: Note 1003 with recursive destinations as (select `test`.`a`.`arrival` AS `city`,1 AS `legs` from `test`.`flights` `a` where `test`.`a`.`departure` = 'Cairo' union select `test`.`b`.`arrival` AS `arrival`,`r`.`legs` + 1 AS `r.legs + 1` from `destinations` `r` join `test`.`flights` `b` where `r`.`city` = `test`.`b`.`departure` and !(`test`.`b`.`arrival`,(select `destinations`.`city` from `destinations` where trigcond(`test`.`b`.`arrival` = `destinations`.`city` or `destinations`.`city` is null) having trigcond(`destinations`.`city` is null))))select `destinations`.`city` AS `city`,`destinations`.`legs` AS `legs` from `destinations` set standard_compliant_cte=default; drop table flights; +# +# MDEV-15162: Setting user variable in recursive CTE +# +SET @c=1; +WITH RECURSIVE cte AS +(SELECT 5 +UNION +SELECT @c:=@c+1 FROM cte WHERE @c<3) +SELECT * FROM cte; +5 +5 +2 +3 diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test index 332f6cfa49b..c3a5ed5cff0 100644 --- a/mysql-test/t/cte_recursive.test +++ b/mysql-test/t/cte_recursive.test @@ -2085,3 +2085,15 @@ eval explain extended $q; set standard_compliant_cte=default; drop table flights; + +--echo # +--echo # MDEV-15162: Setting user variable in recursive CTE +--echo # + +SET @c=1; + +WITH RECURSIVE cte AS + (SELECT 5 + UNION + SELECT @c:=@c+1 FROM cte WHERE @c<3) +SELECT * FROM cte; diff --git a/sql/item_func.cc b/sql/item_func.cc index a4952742d94..f54e79a9f2d 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -53,6 +53,7 @@ #include "sp.h" #include "set_var.h" #include "debug_sync.h" +#include "sql_cte.h" #ifdef NO_EMBEDDED_ACCESS_CHECKS #define sp_restore_security_context(A,B) while (0) {} @@ -4703,10 +4704,13 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref) TABLE_LIST *derived; for (derived= unit->derived; derived; - derived= derived->select_lex->master_unit()->derived) + derived= unit->derived) { derived->set_materialized_derived(); derived->prohibit_cond_pushdown= true; + if (unit->with_element && unit->with_element->is_recursive) + break; + unit= derived->select_lex->master_unit(); } }