Introduce ViewUnionAll to differentiate view-produced unions from subquery unions#143564
Introduce ViewUnionAll to differentiate view-produced unions from subquery unions#143564craigtaverner merged 20 commits intoelastic:mainfrom
Conversation
craigtaverner
left a comment
There was a problem hiding this comment.
If we can name the subqueries, we will complete the requirements. This could be done by enhancing UnionAll (discuss with @Fang), or adding names here. If we add names here we could also consider directly extending Fork, instead of UnionAll. Some more thinking might be required for that option.
Also, this PR needs to rebase on the security PR at #141050, or wait for that to merge and rebase on main. There will be conflicts.
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/ViewUnionAll.java
Outdated
Show resolved
Hide resolved
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/view/ViewResolver.java
Show resolved
Hide resolved
x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/ViewUnionAll.java
Show resolved
Hide resolved
...k/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plan/logical/ViewUnionAllTests.java
Show resolved
Hide resolved
...ck/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/view/InMemoryViewServiceTests.java
Show resolved
Hide resolved
| // --- Behavioral test: views inside subqueries --- | ||
|
|
||
| public void testViewInsideSubqueryIsResolved() { | ||
| assumeTrue("Requires subquery in FROM command support", EsqlCapabilities.Cap.SUBQUERY_IN_FROM_COMMAND.isEnabled()); |
There was a problem hiding this comment.
We could use VIEWS_WITH_BRANCHING here, since that depends on subqueries in from, and will also only turn on when both subqueries and views are out of snapshot.
...ck/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/view/InMemoryViewServiceTests.java
Show resolved
Hide resolved
|
Pinging @elastic/es-analytical-engine (Team:Analytics) |
docs/changelog/143564.yaml
Outdated
| @@ -0,0 +1,6 @@ | |||
| area: ES|QL | |||
| issues: | |||
| - 143564 | |||
There was a problem hiding this comment.
PR cannot refer to itself as an issue
docs/changelog/143564.yaml
Outdated
| - 143564 | ||
| pr: 143564 | ||
| summary: Introduce ViewUnionAll to differentiate view-produced unions from subquery unions | ||
| type: bug |
There was a problem hiding this comment.
For in-progress development we would rather mark this as non-issue to prevent an explosion of changelog entries for as-yet-unreleased work.
…query unions ViewResolver and the parser's subquery syntax both produce UnionAll nodes. Previously, ViewResolver skipped all UnionAll nodes assuming they were from view resolution, and the Fork handler lost the UnionAll type by rebuilding as plain Fork. This change: - Creates ViewUnionAll (extends UnionAll) as a type marker for view-produced unions - ViewResolver now only skips ViewUnionAll, allowing plain UnionAll from subqueries to be processed normally - The Fork handler uses replaceSubPlans() to preserve subclass types instead of constructing new Fork directly - createTopPlan() produces ViewUnionAll instead of UnionAll
Move ViewUnionAll unit tests from InMemoryViewServiceTests into a dedicated test file following the codebase convention of per-node test classes. Adds equals/hashCode and type-inequality tests.
The testAllCommandsWhitelistedOrBlacklisted test scans the classpath for all LogicalPlan subclasses and requires each to be listed. ViewUnionAll was missing, causing CI part-3 to fail.
6db7690 to
a2c3ce4
Compare
fang-xing-esql
left a comment
There was a problem hiding this comment.
LGTM! I left a minor comment.
| otherPlans.add(new Subquery(ur.source(), lp.plan, lp.name)); | ||
| assert otherPlans.containsKey(lp.name) == false; | ||
| // TODO: Consider dropping Subquery nodes entirely | ||
| otherPlans.put(lp.name, new Subquery(ur.source(), lp.plan, lp.name)); |
There was a problem hiding this comment.
It seems like the view name is saved in the hash map, shall we just use the subquery constructor without name here?
There was a problem hiding this comment.
Yes, definitely. I had thought to make that change together with removing Subquery entirely (another PR), but could do it here too!
There was a problem hiding this comment.
I've removed it here, and will remove Subquery as part of another PR.
| 12 | false | ||
| ; | ||
|
|
||
| // Testing views used inside subqueries |
There was a problem hiding this comment.
Could also test subqueries inside views
There was a problem hiding this comment.
Done inside the InMemoryViewServiceTests
Test views inside subqueries and subqueries inside views
craigtaverner
left a comment
There was a problem hiding this comment.
All previous comments have been taken care of now.
| 12 | false | ||
| ; | ||
|
|
||
| // Testing views used inside subqueries |
There was a problem hiding this comment.
Done inside the InMemoryViewServiceTests
| listener.delegateFailureAndWrap((l, rewritten) -> listener.onResponse(new ViewResolutionResult(rewritten, viewQueries))) | ||
| ); | ||
| replaceViews(plan, parser, new LinkedHashSet<>(), viewQueries, 0, listener.delegateFailureAndWrap((l, rewritten) -> { | ||
| LogicalPlan postProcessed = rewriteUnionAllsWithNamedSubqueries(rewritten); |
There was a problem hiding this comment.
Perhaps add comments describing which use cases need this post-view-resolution update
Only because Subquery is there already
Taking into account Nik's new approach of using TestAnalyzer for maintaining test state.
Summary
ViewUnionAll extends UnionAllas a type marker for view-produced unionsViewResolvernow only skipsViewUnionAll, allowing plainUnionAllfrom subqueries to be processed normally for view resolutionForkhandler usesreplaceSubPlans()to preserve subclass types instead of constructingnew Fork(...)directly, fixing a pre-existing type-erasure bugcreateTopPlan()producesViewUnionAllinstead ofUnionAllRelates to esql-planning#181 (under "Loose ends and TODOs")
Test plan
ViewUnionAllcopy methods (replaceChildren, replaceSubPlans, replaceSubPlansAndOutput preserve type)viewInSubquery,viewInSubqueryMultipleRows)ViewUnionAllPushDownFilterAndLimitIntoUnionAllTestspass unchangedPost-review changes
>non-issueand remove changelog file