[QA] Add UnionCommandIT for analytics-engine route - #21649
Conversation
There was a problem hiding this comment.
I had moved the schema coercion handling on java side entirely: #21690 and moved it to rust to eliminate the need of this - I think your change should not be needed now. Can you please validate this with your tests.
Can you please still add up the test-cases for these cases just so that we can ensure cases covered by you are part of tests.
There was a problem hiding this comment.
Confirmed — after rebasing on main (which now includes #21690), the Java-side coerceToDeclaredSchema is gone and the union surface works end-to-end without my Timestamp patch. The Java commit is dropped on rebase.
Validation on upstream/main + this branch (no Java-side coercion):
UnionCommandIT(this PR): 7 / 7 ✅DatafusionReduceSinkTests(post-[Analytics Engine] Eliminate string/utf8 views & timestamp field coercion across the data-node→coordinator pipeline #21690): 8 / 8 ✅
calcs has date / time / datetime columns, so each branch's partial output schema carries Timestamp types through to the reduce sink's typesMatch tripwire. That means the IT does exercise the Timestamp → Timestamp loose-match path on every test even when the final projection is | stats count() — so the case my unit tests used to cover is now covered end-to-end here. The original four unit-pair coercion paths (SEC/MILLI/MICRO/NANO rescaling, overflow, timezone metadata) are now Rust-side concerns under derive_schema_from_partial_plan and not directly callable from Java, so I haven't re-added equivalents to the Java test surface — happy to add Rust-side coverage if you'd like, just point me at the right test module.
PR title / description updated to reflect the reduced scope.
Mirrors the union surface from CalciteUnionCommandIT in opensearch-project/sql so the analytics-engine path can be verified inside core without cross-plugin dependencies on the SQL plugin. Seven tests against POST /_analytics/ppl over the existing calcs dataset: - testBasicUnionTwoSubsearches — two-subsearch shape - testUnionThreeSubsearches — three-subsearch shape - testUnionMidPipelineSingleExplicitDataset — search ... | union [search ...] - testUnionPreservesDuplicates — three identical branches → 3x row count - testUnionWithEmptySubsearch — one branch returns 0 rows - testUnionWithAllEmptyDatasets — both branches empty - testUnionWithSingleSubsearchThrowsError — validation error surfaces Assertions are dataset-independent (sums of branch counts, not hardcoded totals) so the suite stays resilient to calcs bulk-data changes. Also serves as the end-to-end regression net for the reduce-sink's Timestamp handling. calcs carries date/time/datetime columns; each branch's partial output schema includes them, so DatafusionReduceSink.typesMatch (the loose-match tripwire added in opensearch-project#21690 alongside the native-side coercion in derive_schema_from_partial_plan) gets exercised on every test here even when the final projection is | stats count(). Originally this IT was paired with a Java-side Timestamp→Timestamp coercion patch in DatafusionReduceSink.coerceToDeclaredSchema. PR opensearch-project#21690 superseded that approach by moving the coercion into Rust at input-registration time, so the Java-side patch is dropped from this PR; the IT remains because the union surface itself is worth keeping in core's analytics-engine QA suite. Signed-off-by: Kai Huang <huangkaics@gmail.com> Signed-off-by: Kai Huang <ahkcs@amazon.com>
9e53bf1 to
3982f72
Compare
PR Reviewer Guide 🔍(Review updated until commit 42caf0f)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 42caf0f Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit 33169e3
Suggestions up to commit 3982f72
|
|
❕ Gradle check result for 3982f72: UNSTABLE Please review all flaky tests that succeeded after retry and create an issue if one does not already exist to track the flaky failure. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #21649 +/- ##
============================================
+ Coverage 73.41% 73.47% +0.05%
- Complexity 75533 75582 +49
============================================
Files 6035 6035
Lines 342710 342721 +11
Branches 49298 49301 +3
============================================
+ Hits 251610 251808 +198
+ Misses 71111 70925 -186
+ Partials 19989 19988 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…vious run Signed-off-by: Kai Huang <ahkcs@amazon.com>
|
Persistent review updated to latest commit 33169e3 |
|
| Run | Module | Failures |
|---|---|---|
| Rebased branch (this PR, run 26114136971) | analytics-engine-coordinator:internalClusterTest |
8 (3× SearchCancellationIT, 5× CoordinatorTransportStressIT) + a few more |
| Rebased branch (retrigger, run 26119419897) | same | same 8 + CoordinatorSingleNodeTopologyIT, CoordinatorTwoNodeTopologyIT, WindowSqlIT, ValuesSqlIT, CompositeLocalRecoveryIT |
Base commit debf6edcad0 with no IT cherry-picked (local) |
same | same 8 failures, identical test names |
UnionCommandIT (this PR, the only file changed) |
analytics-engine-rest:integTest |
7 / 7 pass ✅ |
All failures share the same root cause: IllegalStateException: Allocator[ROOT] closed with outstanding child allocators — an Arrow allocator lifecycle issue at JVM-test teardown. The failures vary slightly across runs (which is the hallmark of a flake), but the same suites surface consistently.
This PR only adds one file under sandbox/qa/analytics-engine-rest, a different gradle module from the failing one, and touches no allocator / coordinator code. There is no causal path from the IT change to these failures.
sandbox-check on the same base commit debf6edcad0 was green in upstream CI (run), so these tests pass intermittently on main too.
Happy to retry CI again if helpful, but absent an upstream fix for the allocator-lifecycle flake the PR has no path to a clean sandbox-check. Could you take a look or rerun the job on the merge queue? UnionCommandIT itself passes 7/7 both locally and in CI.
|
Persistent review updated to latest commit 42caf0f |
Description
Adds a self-contained
UnionCommandITundersandbox/qa/analytics-engine-rest, mirroring the union surface fromCalciteUnionCommandITinopensearch-project/sqlso the analytics-engine path can be verified inside core without cross-plugin dependencies on the SQL plugin.Scope change after rebase
This PR was originally a two-commit change: (1) a Java-side
Timestamp → Timestampcoercion patch inDatafusionReduceSink.coerceToDeclaredSchema, plus (2) the new IT. PR #21690 (merged 2026-05-16) moved schema coercion handling from Java to Rust —DatafusionReduceSink.coerceToDeclaredSchemawas deleted in favour of atypesMatchtripwire that treats any twoTimestamptypes as matching, and the native side picks up the lowered precision from substrait at registration time viaderive_schema_from_partial_plan.The Java-side commit is therefore obsolete and has been dropped on rebase. Only the IT remains.
Validation
UnionCommandITis run againstupstream/main(post-#21690) with no Java-side coercion patch:UnionCommandIT(new)DatafusionReduceSinkTests(existing, post-#21690)This validates @sandeshkr419's claim that the Java-side patch is no longer needed: the union surface, including the
Timestampcross-precision scenario that originally motivated the patch, works end-to-end on the Rust-side coercion alone.What the IT covers
Seven tests against
POST /_analytics/pplon thecalcsdataset:testBasicUnionTwoSubsearches— two-subsearch shapetestUnionThreeSubsearches— three-subsearch shapetestUnionMidPipelineSingleExplicitDataset—search ... | union [search ...]testUnionPreservesDuplicates— three identical branches → 3× row counttestUnionWithEmptySubsearch— one branch returns 0 rowstestUnionWithAllEmptyDatasets— both branches emptytestUnionWithSingleSubsearchThrowsError— validation error surfacesAssertions are dataset-independent (sums of branch counts, not hardcoded totals) so the suite stays resilient to
calcsbulk-data changes.calcscarriesdate/time/datetimecolumns, so each branch's partial output schema includesTimestamptypes — the reduce sink's loose-match tripwire onTimestampis exercised on every test here even when the final projection is| stats count(), making this IT the end-to-end regression net for theTimestamphandling that #21690 introduced.