Skip to content

CALCITE-7815 Support the SQL-standard SEARCH clause in recursive CTEs - #5370

Open
vldpyatkov wants to merge 1 commit into
apache:mainfrom
vldpyatkov:calcite-7815
Open

vldpyatkov wants to merge 1 commit into
apache:mainfrom
vldpyatkov:calcite-7815

Conversation

@vldpyatkov

Copy link
Copy Markdown
Contributor

Jira Link

CALCITE-7815

Changes Proposed

Adds support for SEARCH DEPTH FIRST BY ... SET ... and SEARCH BREADTH FIRST BY ... SET ... in recursive CTEs. The generated column can be used in ORDER BY to obtain the corresponding traversal order.

The clause is represented by SqlSearchClause on SqlWithItem. During validation, RecursiveWithRewriter builds an ARRAY<ROW<...>> path for depth-first ordering or a row containing depth and keys for breadth-first ordering. SEARCH can be combined with CYCLE.

Also updates enumerable comparators to handle composite keys in multi-column sorts and adds Java and iq tests.

@vldpyatkov
vldpyatkov force-pushed the calcite-7815 branch 3 times, most recently from d1ddc48 to 5945e66 Compare October 29, 2026 20:53
@rubenada

rubenada commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

@vldpyatkov thanks for pushing this forward!
Quick question: IIUC the usage of SEARCH on a diamond shape graph could lead to "duplicated" results, e.g.:

Edges: 0→1, 0→2, 1→3, 2→3. Node 3 can be reached two ways.

WITH RECURSIVE edges(src, dst) AS (VALUES (0,1), (0,2), (1,3), (2,3)),
walk(node) AS (
  VALUES (0)
  UNION
  SELECT e.dst FROM walk AS w JOIN edges AS e ON e.src = w.node)
SELECT node FROM walk

Without SEARCH: 0,1,2,3
With SEARCH DEPTH: (0, [0]), (1, [0,1]), (2, [0,2]), (3, [0,1,3]), (3, [0,2,3])
On the second case, 3 is returned two times (because paths differ).

Analogously, on a graph: 0→1, 1→3, 0→3
Without SEARCH: 0,1,3
With SEARCH BREADTH: (0, ROW(0,0)), (1, ROW(1,1)), (3, ROW(1,3)), (3, ROW(2,3)).
On the second case, 3 is returned two times (because depths differ).

If this is the case, could we have some tests showing these cases? Shall we document somehow this phenomenon?

@vldpyatkov

Copy link
Copy Markdown
Contributor Author

@vldpyatkov thanks for pushing this forward! Quick question: IIUC the usage of SEARCH on a diamond shape graph could lead to "duplicated" results, e.g.:

Edges: 0→1, 0→2, 1→3, 2→3. Node 3 can be reached two ways.

WITH RECURSIVE edges(src, dst) AS (VALUES (0,1), (0,2), (1,3), (2,3)),
walk(node) AS (
  VALUES (0)
  UNION
  SELECT e.dst FROM walk AS w JOIN edges AS e ON e.src = w.node)
SELECT node FROM walk

Without SEARCH: 0,1,2,3 With SEARCH DEPTH: (0, [0]), (1, [0,1]), (2, [0,2]), (3, [0,1,3]), (3, [0,2,3]) On the second case, 3 is returned two times (because paths differ).

Analogously, on a graph: 0→1, 1→3, 0→3 Without SEARCH: 0,1,3 With SEARCH BREADTH: (0, ROW(0,0)), (1, ROW(1,1)), (3, ROW(1,3)), (3, ROW(2,3)). On the second case, 3 is returned two times (because depths differ).

If this is the case, could we have some tests showing these cases? Shall we document somehow this phenomenon?

@rubenada The generated SEARCH column participates in duplicate elimination. Documented this behavior in the SQL reference.

@vldpyatkov
vldpyatkov requested a review from rubenada November 10, 2026 16:47
Comment thread site/_docs/reference.md Resolved
Comment thread site/_docs/reference.md Resolved
@rubenada

Copy link
Copy Markdown
Contributor

@vldpyatkov sorry, I just added two final minor remarks that I had missed on my last review. Please take a look. I think the PR is in a good shape, so you can also proceed and squash commits into a single one to prepare the merge.

@vldpyatkov

Copy link
Copy Markdown
Contributor Author

@rubenada I've addressed the last two comments and squashed everything into a single commit.
Thanks for the thorough review!

@sonarqubecloud

Copy link
Copy Markdown

@rubenada rubenada added the LGTM-will-merge-soon Overall PR looks OK. Only minor things left. label Nov 11, 2026
@rubenada

Copy link
Copy Markdown
Contributor

LGTM, the build-website error seems an unrelated problem to be handled separately, no reason to block the current PR because of that. I'll merge in the next 24-48h if not further comment arrives.

@vldpyatkov vldpyatkov closed this Nov 14, 2026
@vldpyatkov vldpyatkov reopened this Nov 14, 2026
@vldpyatkov

Copy link
Copy Markdown
Contributor Author

LGTM, the build-website error seems an unrelated problem to be handled separately, no reason to block the current PR because of that. I'll merge in the next 24-48h if not further comment arrives.

I closed and reopened PR by misclicking.
Really, I wanted to mention that @rubenada promised to merge it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

LGTM-will-merge-soon Overall PR looks OK. Only minor things left.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants