Commit 3b27e69
[Analytics-Engine] Decorrelate RexSubQuery before marking in PlannerImpl (opensearch-project#21795)
* Decorrelate RexSubQuery before marking in PlannerImpl
PPL queries that contain EXISTS / IN / SOME / ANY subqueries (and the
`subsearch` shapes the frontend lowers to them) reach the analytics
engine as a LogicalFilter / LogicalProject / LogicalJoin holding a
RexSubQuery. The downstream marking rules — particularly
OpenSearchFilterRule, which resolves leaf predicates through a
ScalarFunction table that doesn't (and shouldn't) cover EXISTS — reject
the operator at run time:
IllegalStateException: Unrecognized filter operator [EXISTS / EXISTS]
Add a 'subquery-remove' phase at the top of PlannerImpl.runAllOptimizations
that runs Calcite's three SUB_QUERY_TO_CORRELATE rules to lower every
RexSubQuery into a LogicalCorrelate, then decorrelates the result back to
a straight join shape via RelDecorrelator.decorrelateQuery. Every later
phase (reduce / pushdown / decompose / marking / CBO) sees a
subquery-free tree.
Placement: per the Component Responsibilities table in
opensearch-project/sql#5246, logical-plan rewrites are an SQL-plugin
concern long-term — but the unified path has no logical-optimizer stage
yet, and AE already owns RelNode → physical-execution. Putting the
rewrite here lets every AE client (PPL today, ANSI SQL / Spark / future
frontends) get correct subquery handling without each frontend having to
remember to run SubQueryRemoveRule + RelDecorrelator before handoff. When
a UnifiedQueryOptimizer lands SQL-side, this phase can migrate upward.
After: CalcitePPLExistsSubqueryIT goes from 19/19 fail (all
IllegalStateException at the filter rule) to 6/19 pass + 13/19
AssertionError result mismatches. The remaining 13 failures are
downstream analytics-engine semantics for bare-group-by Aggregate inside
the decorrelated join — unrelated to subquery removal, tracked
separately.
Tests:
* SubQueryPlanShapeTests — 3 new tests covering uncorrelated EXISTS,
correlated EXISTS, and IN-subquery; each asserts no RexSubQuery
survives the planner pipeline.
* RuleProfilingListenerTests — EXPECTED_PHASES extended with
'subquery-remove' so the profile-listener phase-list assertion still
matches the actual phase ordering.
* Full :sandbox:plugins:analytics-engine:test — 311 tests, 0 failures.
Signed-off-by: Jialiang Liang <jialianl@amazon.com>
Signed-off-by: Jialiang Liang <jiallian@amazon.com>
* spotlessApply
Inline the RelDecorrelator.decorrelateQuery call and reorder the
RelHomogeneousShuttle import — fixes the spotlessJavaCheck failure
sandbox-check flagged on the prior commit.
Signed-off-by: Jialiang Liang <jialianl@amazon.com>
Signed-off-by: Jialiang Liang <jiallian@amazon.com>
* Flip StreamstatsCommandIT.testWhereInWithStreamstatsSubquery to positive assertion
The subquery-remove phase introduced in PlannerImpl makes the
where-in-with-streamstats-subquery shape reachable on the
analytics-engine route — RexSubQuery lowers to LogicalCorrelate, then
decorrelates into a semi-join that the marking + capability rules
already support. The test was previously pinned as assertErrorAny(...)
because the query crashed at the filter rule before this phase existed.
Flip it to executePpl(...) + assertRowCount(1) — `| head 1` over a
non-empty matching set returns one row — and update the class-level
'known limitations' comment so testWhereInWithStreamstatsSubquery is
no longer listed alongside testLeftJoinWithStreamstats.
Signed-off-by: Jialiang Liang <jialianl@amazon.com>
Signed-off-by: Jialiang Liang <jiallian@amazon.com>
* Revert testWhereInWithStreamstatsSubquery flip — keep assertErrorAny
The previous flip to executePpl + assertRowCount(1) was based on a
single-node local run where the query succeeded. On the 4-node testcluster
that sandbox-check uses, the decorrelated streamstats-inside-correlate
shape errors with 'Stage 0 sink feed failed: partition stream receiver
dropped before send' rather than producing rows. The subquery-remove
phase moves the failure point from plan-time (IllegalStateException at
OpenSearchFilterRule) to runtime (sink-feed failure during distributed
execution) — same overall outcome from the test's perspective (HTTP 500),
just a different message.
Restore the original assertErrorAny(...) assertion: it catches any
ResponseException so both the old and new error shapes satisfy it.
Keep the test on the broad-failure pin until the downstream multi-node
correctness gap is closed.
Locally verified: integTest --tests testWhereInWithStreamstatsSubquery
passes 1/1 against a 4-node testcluster on this commit.
Signed-off-by: Jialiang Liang <jialianl@amazon.com>
Signed-off-by: Jialiang Liang <jiallian@amazon.com>
* Skip testWhereInWithStreamstatsSubquery with @AwaitsFix — nondeterministic on multi-node
The subquery-remove phase makes this where-in-with-streamstats shape
reachable on the analytics-engine route, but the streamstats-inside-
decorrelated-correlate execution path races on multi-node clusters:
sometimes the Stage 0 sender hits a 'partition stream receiver dropped
before send' error, sometimes it returns one row successfully. Neither
a positive assertion (executePpl + assertRowCount) nor the prior
broad-failure assertion (assertErrorAny) is stable across CI runs.
Pin with @AwaitsFix until the downstream multi-node race is closed —
re-enable by removing the annotation. The annotation message names the
specific failure signature so the next person picking this up knows
which subsystem to investigate.
Locally verified: integTest --tests testWhereInWithStreamstatsSubquery
reports the test as skipped (tests=1 skipped=1 failures=0 errors=0).
Signed-off-by: Jialiang Liang <jialianl@amazon.com>
Signed-off-by: Jialiang Liang <jiallian@amazon.com>
---------
Signed-off-by: Jialiang Liang <jialianl@amazon.com>
Signed-off-by: Jialiang Liang <jiallian@amazon.com>1 parent e1f3cda commit 3b27e69
4 files changed
Lines changed: 178 additions & 3 deletions
File tree
- sandbox
- plugins/analytics-engine/src
- main/java/org/opensearch/analytics/planner
- test/java/org/opensearch/analytics/planner
- qa/analytics-engine-rest/src/test/java/org/opensearch/analytics/qa
Lines changed: 38 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
| |||
87 | 88 | | |
88 | 89 | | |
89 | 90 | | |
| 91 | + | |
90 | 92 | | |
91 | 93 | | |
92 | 94 | | |
| |||
112 | 114 | | |
113 | 115 | | |
114 | 116 | | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
115 | 153 | | |
116 | 154 | | |
117 | 155 | | |
| |||
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
| |||
Lines changed: 120 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
Lines changed: 19 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| |||
52 | 53 | | |
53 | 54 | | |
54 | 55 | | |
55 | | - | |
56 | | - | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
57 | 62 | | |
58 | 63 | | |
59 | 64 | | |
| |||
919 | 924 | | |
920 | 925 | | |
921 | 926 | | |
922 | | - | |
| 927 | + | |
| 928 | + | |
| 929 | + | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
923 | 939 | | |
924 | 940 | | |
925 | 941 | | |
| |||
0 commit comments