Fix ClassCastException in PPL multisearch on indexes with @timestamp alias field#5577
Open
gingeekrishna wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes a Calcite planning/runtime ClassCastException triggered by | multisearch on indices where @timestamp is a field-type alias. The fix corrects collation trait handling on scan nodes so the collation trait is replaced (not composed) during sort/project pushdown.
Changes:
- Replace
RelTraitSet.plus(RelCollations.of(...))withRelTraitSet.replace(RelCollations.of(...))in sort pushdown to avoid creatingRelCompositeTrait. - Replace
RelTraitSet.plus(...)withreplace(...)when reindexing collations after project pushdown. - Add an integration regression test covering multisearch against an index with an alias-mapped
@timestamp.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| opensearch/src/main/java/org/opensearch/sql/opensearch/storage/scan/CalciteLogicalIndexScan.java | Uses RelTraitSet.replace() when reindexing collations after project pushdown. |
| opensearch/src/main/java/org/opensearch/sql/opensearch/storage/scan/AbstractCalciteIndexScan.java | Uses RelTraitSet.replace() when setting collations during sort pushdown. |
| integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalciteMultisearchCommandIT.java | Adds regression IT for multisearch on an index where @timestamp is an alias field. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
5cd23cd to
a7a1d9a
Compare
a7a1d9a to
d87f33f
Compare
Collaborator
|
@gingeekrishna thanks for taking care of this issue, could you please check CI failures? |
…alias field Fixes opensearch-project#5533. When `@timestamp` is defined as a field-type alias in the index mapping, multisearch queries threw: ClassCastException: RelCompositeTrait cannot be cast to RelCollation Root cause: `reIndexCollations()` in `CalciteLogicalIndexScan` and `pushDownSort()` in `AbstractCalciteIndexScan` both called `RelTraitSet.plus()` to update the collation trait on a scan node. `plus()` *composes* traits — if the trait set already contains a `RelCollation`, it merges the old and new collations into a `RelCompositeTrait`. Calcite's `RelTraitSet.getCollation()` then does an unchecked cast `(RelCollation) getTrait(...)` which fails at runtime for `RelCompositeTrait`. The `@timestamp` alias path specifically triggers this because `wrapProjectForAliasFields()` adds a project on top of each sub-scan which is later pushed back down via `pushDownProject()`. `pushDownProject()` calls `reIndexCollations()` to remap field indices inside an existing collation — but re-using `plus()` here composes the existing sort collation with the re-indexed one, producing the bad composite. Fix: use `RelTraitSet.replace()` in both locations. `replace()` substitutes the collation trait in-place regardless of what was there before, which is the correct semantics for "this scan is now sorted by these columns". Added a regression IT (`testMultisearchWithTimestampAliasFieldDoesNotThrow`) that runs a multisearch against `TEST_INDEX_ALIAS`, whose mapping defines `@timestamp` as an alias for `original_date`. Signed-off-by: Radhakrishnan Pachyappan <gingeekrishna@gmail.com>
d87f33f to
7fb0d69
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #5533.
When
@timestampis defined as a field-type alias in the index mapping (e.g."@timestamp": {"type": "alias", "path": "timestamp"}), running a| multisearchcommand on that index throws:Root cause
reIndexCollations()(CalciteLogicalIndexScan) andpushDownSort()(AbstractCalciteIndexScan) both calledRelTraitSet.plus()to set the collation trait on a scan node.plus()composes traits — when the trait set already contains aRelCollation, it merges the old and new collations into aRelCompositeTrait. Calcite'sRelTraitSet.getCollation()then does an unchecked cast(RelCollation) getTrait(...)which fails at runtime forRelCompositeTrait.The
@timestampalias path specifically triggers this becausewrapProjectForAliasFields()adds aLogicalProjecton top of each sub-scan during multisearch plan building. Calcite's push-down rules later push this project back into the scan viapushDownProject()→reIndexCollations(), which usesplus()to remap an existing sort collation — producing the bad composite trait.Fix
Use
RelTraitSet.replace()in both locations instead ofplus().replace()substitutes the collation trait in-place regardless of what was already there, which is the correct semantics for "this scan is sorted by these columns".Files changed (3):
opensearch/.../AbstractCalciteIndexScan.java—pushDownSort():plus→replaceopensearch/.../CalciteLogicalIndexScan.java—reIndexCollations():plus→replaceinteg-test/.../CalciteMultisearchCommandIT.java— regression IT againstTEST_INDEX_ALIAS(which maps@timestampas a field-type alias tooriginal_date)Test plan
testMultisearchWithTimestampAliasFieldDoesNotThrowIT — runs a multisearch against an index where@timestampis a field-type alias; this would have crashed withClassCastExceptionbefore this fixCalciteMultisearchCommandITtests passOpenSearchIndexScanOptimizationTestand related unit tests pass (.replace()is correct semantics here — a scan's collation is always a full replacement, never a union of multiple sort orders)Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.