Skip to content

MDEV-32326 Recursive CTE reference in a scalar subquery must be rejected#5262

Open
Olernov wants to merge 1 commit into
10.11from
10.11-MDEV-32326-exec-recursive
Open

MDEV-32326 Recursive CTE reference in a scalar subquery must be rejected#5262
Olernov wants to merge 1 commit into
10.11from
10.11-MDEV-32326-exec-recursive

Conversation

@Olernov

@Olernov Olernov commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

A recursive reference to a WITH RECURSIVE table that is reachable only through a scalar subquery (in particular through a WITH clause nested inside such a subquery) was not recognized as a subquery reference. As a result the recursive CTE was wrongly accepted as standard-compliant instead of being rejected with ER_NOT_STANDARD_COMPLIANT_RECURSIVE, and execution later dereferenced an uninitialized join_tab for that reference in st_select_lex_unit::exec_recursive(), crashing the server.

The cause was in With_element::check_dependencies_in_unit(). The flag marking that we are inside a subquery (in_subq) was updated only after the unit's own WITH clause had already been analyzed. Hence dependencies discovered while descending into a WITH clause attached to a scalar subquery were recorded in top_level_dep_map instead of sq_dep_map, so contains_sq_with_recursive_reference() failed to report the violation.

The fix: set in_subq from unit->item before processing the unit's WITH clause, so that dependencies found in nested WITH clauses of a scalar subquery are correctly attributed to the subquery context.

The expected error for the MDEV-32299 cases in cte_recursive.test changes accordingly from ER_BAD_FIELD_ERROR to ER_NOT_STANDARD_COMPLIANT_RECURSIVE: the query is now rejected at dependency analysis for its non-compliant recursive reference rather than failing later during name resolution. The test still verifies that no crash occurs.

A recursive reference to a WITH RECURSIVE table that is reachable only
through a scalar subquery (in particular through a WITH clause nested
inside such a subquery) was not recognized as a subquery reference. As a
result the recursive CTE was wrongly accepted as standard-compliant instead
of being rejected with ER_NOT_STANDARD_COMPLIANT_RECURSIVE, and execution
later dereferenced an uninitialized join_tab for that reference in
st_select_lex_unit::exec_recursive(), crashing the server.

The cause was in With_element::check_dependencies_in_unit(). The flag
marking that we are inside a subquery (in_subq) was updated only after the
unit's own WITH clause had already been analyzed. Hence dependencies
discovered while descending into a WITH clause attached to a scalar
subquery were recorded in top_level_dep_map instead of sq_dep_map, so
contains_sq_with_recursive_reference() failed to report the violation.

The fix: set in_subq from unit->item before processing the unit's WITH
clause, so that dependencies found in nested WITH clauses of a scalar
subquery are correctly attributed to the subquery context.

The expected error for the MDEV-32299 cases in cte_recursive.test changes
accordingly from ER_BAD_FIELD_ERROR to ER_NOT_STANDARD_COMPLIANT_RECURSIVE:
the query is now rejected at dependency analysis for its non-compliant
recursive reference rather than failing later during name resolution. The
test still verifies that no crash occurs.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses MDEV-32326 by rejecting recursive references in scalar subqueries, updating test cases to expect ER_NOT_STANDARD_COMPLIANT_RECURSIVE instead of ER_BAD_FIELD_ERROR. In sql/sql_cte.cc, the dependency check is modified to set in_subq before checking the with_clause. However, because in_subq is a member variable of With_element, modifying it permanently affects subsequent sibling subqueries or top-level query blocks, potentially rejecting valid CTEs. It is recommended to save and restore the state of in_subq using an RAII helper upon entering and leaving check_dependencies_in_unit.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread sql/sql_cte.cc
table_map *dep_map)
{
st_unit_ctxt_elem unit_ctxt_elem= {ctxt, unit};
in_subq |= unit->item != NULL;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Because in_subq is a member variable of With_element, modifying it with in_subq |= unit->item != NULL; during the recursive traversal of nested units (subqueries) permanently sets it to true for the remainder of the dependency check of this With_element. This means that any subsequent sibling subqueries or top-level query blocks (such as the recursive step of a UNION) will incorrectly inherit in_subq == true, causing valid, standard-compliant recursive CTEs to be rejected with ER_NOT_STANDARD_COMPLIANT_RECURSIVE.

To fix this, we should save and restore the state of in_subq when entering and leaving check_dependencies_in_unit. Since the end of the function is outside the current diff hunk, we can use a simple local RAII struct to automatically restore the value upon function exit.

Suggested change
in_subq |= unit->item != NULL;
struct Save_in_subq {
bool &ref;
bool val;
Save_in_subq(bool &r) : ref(r), val(r) {}
~Save_in_subq() { ref = val; }
} save_in_subq(in_subq);
in_subq |= unit->item != NULL;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are wrong, in_subq is not a member of With_element but a by-value parameter of the function, so it's scoped to only this frame and doesn't mutate the caller's in_subq value upstream.

@Olernov Olernov requested a review from sanja-byelkin June 20, 2026 13:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

1 participant