Skip to content
Permalink
Browse files
MDEV-30248 Infinite sequence of recursive calls when processing embed…
…ded CTE

This patch fixes the patch for bug MDEV-30248 that unsatisfactorily
resolved the problem of resolution of references to CTE. In some cases
when such a reference has the same table name as the name of one of
CTEs containing this reference the reference could be resolved incorrectly
that led to an invalid select tree where units could be mutually dependent.
This in its turn could lead to an infinite sequence of recursive calls or
to falls into infinite loops.

The patch also removes LEX::resolve_references_to_cte_in_hanging_cte() as
with the new code for resolution of CTE references the call of this
function is not needed anymore.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
  • Loading branch information
igorbabaev committed Jan 23, 2023
1 parent f18c2b6 commit 074bef4
Show file tree
Hide file tree
Showing 5 changed files with 311 additions and 81 deletions.
@@ -5604,5 +5604,177 @@ r
3
drop table t1,t2,t3,x;
#
# MDEV-30248: Embedded non-recursive CTE referring to base table 'x'
# within a CTE with name 'x' used in a subquery from
# select list of another CTE
#
CREATE TABLE x (a int) ENGINE=MyISAM;
INSERT INTO x VALUES (3),(7),(1);
CREATE TABLE t1 (b int) ENGINE=MYISAM;
INSERT INTO t1 VALUES (1);
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT 1 AS b)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
c
1
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT b FROM t1)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
c
1
WITH cte AS
(
SELECT
(
WITH x AS
(WITH y AS (SELECT a FROM x AS t) SELECT b FROM t1)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
c
1
WITH cte AS
(
SELECT
(
WITH x AS
(WITH y(b) AS (SELECT a FROM x AS t LIMIT 1) SELECT b FROM y)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
c
3
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x(b) AS (SELECT a FROM x AS t LIMIT 1) SELECT b FROM x)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
c
3
WITH x AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT 1 AS b)
SELECT b FROM x AS r
) AS c
)
SELECT x.c from x;
c
1
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT 2 AS b)
SELECT r1.b FROM x AS r1, x AS r2 WHERE r1.b=r2.b
) AS c
)
SELECT cte.c from cte;
c
2
DROP TABLE x;
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT 1 AS b)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
ERROR 42S02: Table 'test.x' doesn't exist
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT b FROM t1)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
ERROR 42S02: Table 'test.x' doesn't exist
WITH cte AS
(
SELECT
(
WITH x AS
(WITH y AS (SELECT a FROM x AS t) SELECT b FROM t1)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
ERROR 42S02: Table 'test.x' doesn't exist
WITH cte AS
(
SELECT
(
WITH x AS
(WITH y(b) AS (SELECT a FROM x AS t LIMIT 1) SELECT b FROM y)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
ERROR 42S02: Table 'test.x' doesn't exist
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x(b) AS (SELECT a FROM x AS t LIMIT 1) SELECT b FROM x)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
ERROR 42S02: Table 'test.x' doesn't exist
WITH x AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT 1 AS b)
SELECT b FROM x AS r
) AS c
)
SELECT x.c from x;
ERROR 42S02: Table 'test.x' doesn't exist
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT 2 AS b)
SELECT r1.b FROM x AS r1, x AS r2 WHERE r1.b=r2.b
) AS c
)
SELECT cte.c from cte;
ERROR 42S02: Table 'test.x' doesn't exist
DROP TABLE t1;
#
# End of 10.3 tests
#
@@ -3871,6 +3871,129 @@ select * from cte;

drop table t1,t2,t3,x;

--echo #
--echo # MDEV-30248: Embedded non-recursive CTE referring to base table 'x'
--echo # within a CTE with name 'x' used in a subquery from
--echo # select list of another CTE
--echo #

CREATE TABLE x (a int) ENGINE=MyISAM;
INSERT INTO x VALUES (3),(7),(1);
CREATE TABLE t1 (b int) ENGINE=MYISAM;
INSERT INTO t1 VALUES (1);

let $q1=
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT 1 AS b)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
eval $q1;

let $q2=
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT b FROM t1)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
eval $q2;

let $q3=
WITH cte AS
(
SELECT
(
WITH x AS
(WITH y AS (SELECT a FROM x AS t) SELECT b FROM t1)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
eval $q3;


let $q4=
WITH cte AS
(
SELECT
(
WITH x AS
(WITH y(b) AS (SELECT a FROM x AS t LIMIT 1) SELECT b FROM y)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
eval $q4;

let $q5=
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x(b) AS (SELECT a FROM x AS t LIMIT 1) SELECT b FROM x)
SELECT b FROM x AS r
) AS c
)
SELECT cte.c FROM cte;
eval $q5;

let $q6=
WITH x AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT 1 AS b)
SELECT b FROM x AS r
) AS c
)
SELECT x.c from x;
eval $q6;

let $q7=
WITH cte AS
(
SELECT
(
WITH x AS
(WITH x AS (SELECT a FROM x AS t) SELECT 2 AS b)
SELECT r1.b FROM x AS r1, x AS r2 WHERE r1.b=r2.b
) AS c
)
SELECT cte.c from cte;
eval $q7;


DROP TABLE x;

--ERROR ER_NO_SUCH_TABLE
eval $q1;
--ERROR ER_NO_SUCH_TABLE
eval $q2;
--ERROR ER_NO_SUCH_TABLE
eval $q3;
--ERROR ER_NO_SUCH_TABLE
eval $q4;
--ERROR ER_NO_SUCH_TABLE
eval $q5;
--ERROR ER_NO_SUCH_TABLE
eval $q6;
--ERROR ER_NO_SUCH_TABLE
eval $q7;

DROP TABLE t1;

--echo #
--echo # End of 10.3 tests
--echo #

0 comments on commit 074bef4

Please sign in to comment.