Skip to content

fix: [bug] PPL query with mvindex() fails when plugins.calcite.pushdown.enabled=true (#5660) - #5689

Open
AjimelecGonzalez wants to merge 1 commit into
opensearch-project:mainfrom
AjimelecGonzalez:fix/mvindex
Open

fix: [bug] PPL query with mvindex() fails when plugins.calcite.pushdown.enabled=true (#5660)#5689
AjimelecGonzalez wants to merge 1 commit into
opensearch-project:mainfrom
AjimelecGonzalez:fix/mvindex

Conversation

@AjimelecGonzalez

Copy link
Copy Markdown
Contributor

Description

Fix Calcite pushdown CompileException where arithmetic in array index expressions (e.g., mvindex(entity, 1)) produces long instead of int at runtime.

RexStandardizer widens arithmetic operands to BIGINT for doc-value compatibility, but PLUS nodes do not have their type serialized in JSON (unlike CAST/MINUS). On deserialization the type is re-derived from BIGINT operands, breaking operators like ITEM that expect int.

Fix: Wrap arithmetic results in an explicit CAST(INTEGER) in RexStandardizer.visitCall() when the original type is narrower than BIGINT. CAST nodes always serialize their type, so INTEGER is preserved through serialization and deserialization.

Related Issues

Resolves #5660
See also: #5670 (alternative plan-layer fix that is ineffective because the serialization layer overrides it)

Check List

  • New functionality includes testing.
  • New functionality has been documented.
  • New functionality has javadoc added.
  • New functionality has a user manual doc added.
  • New PPL command checklist all confirmed.
  • API changes companion pull request created.
  • Commits are signed per the DCO using --signoff or -s.
  • Public documentation issue/PR created.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

(Review updated until commit ee33606)

Here are some key observations to aid the review process:

🧪 PR contains tests
🔒 No security concerns identified
✅ No TODO sections
🔀 No multiple PR themes
⚡ Recommended focus areas for review

Type Mismatch Risk

The condition checks call.getType() is not BIGINT, but then casts the result back to call.getType(). If operands were widened to BIGINT during standardization, result may already have BIGINT type from makeCall(), making the cast to the original narrower type potentially lossy. This could cause runtime failures if the actual value exceeds the target type's range (e.g., casting a BIGINT value that doesn't fit into INTEGER).

if (allowNumericTypeWiden
    && SqlTypeUtil.isExactNumeric(call.getType())
    && !call.getType().getSqlTypeName().equals(SqlTypeName.BIGINT)) {
  RelDataType targetType =
      OpenSearchTypeFactory.TYPE_FACTORY.createTypeWithNullability(
          call.getType(), call.getType().isNullable());
  result = helper.rexBuilder.makeCast(targetType, result);

…hdown.enabled=true` (opensearch-project#5660)

Signed-off-by: Ajimelec Gonzalez <ajimelec@amazon.com>
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit ee33606

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Redundant cast to same type

The cast operation creates a targetType that is identical to call.getType() with the
same nullability, making the cast redundant. Consider either removing the cast
entirely or defining a different target type (e.g., BIGINT) if type widening is the
intended behavior.

opensearch/src/main/java/org/opensearch/sql/opensearch/storage/serde/RexStandardizer.java [89-96]

 if (allowNumericTypeWiden
     && SqlTypeUtil.isExactNumeric(call.getType())
     && !call.getType().getSqlTypeName().equals(SqlTypeName.BIGINT)) {
   RelDataType targetType =
-      OpenSearchTypeFactory.TYPE_FACTORY.createTypeWithNullability(
-          call.getType(), call.getType().isNullable());
+      OpenSearchTypeFactory.TYPE_FACTORY.createSqlType(SqlTypeName.BIGINT);
   result = helper.rexBuilder.makeCast(targetType, result);
 }
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a critical logic error where targetType is created with the same type as call.getType(), making the cast operation redundant and defeating the purpose of type widening. The improved code properly widens to BIGINT type, which aligns with the condition checking that the type is not already BIGINT.

High

@ahkcs ahkcs added the bugFix label Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] PPL query with mvindex() fails when plugins.calcite.pushdown.enabled=true

2 participants