This is an automated email from the ASF dual-hosted git repository.

yashmayya pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new ad850480ef2 Revert "Map DECIMAL(p, 0) to a type that holds all its 
values in the multi-stage engine (#19790)" (#19949)
ad850480ef2 is described below

commit ad850480ef2ea656a8c921b625578017b7d5e9ab
Author: Yash Mayya <[email protected]>
AuthorDate: Mon Oct 19 15:11:52 2026 -0700

    Revert "Map DECIMAL(p, 0) to a type that holds all its values in the 
multi-stage engine (#19790)" (#19949)
    
    This reverts commit dc7837cb617645ff48aa8146c71c0f23b6ef83e4.
---
 .../rel/rules/PinotEvaluateLiteralRule.java        |   7 +-
 .../planner/logical/RelToPlanNodeConverter.java    |  40 +------
 .../query/planner/logical/RexExpressionUtils.java  |  44 ++-----
 .../physical/v2/PRelToPlanNodeConverter.java       |   8 +-
 .../logical/RelToPlanNodeConverterTest.java        |  53 +--------
 .../planner/logical/RexExpressionUtilsTest.java    |  36 +-----
 .../physical/v2/PRelToPlanNodeConverterTest.java   |  28 -----
 .../src/test/resources/queries/AggregatePlans.json |  26 -----
 .../runtime/operator/operands/FilterOperand.java   |  40 +------
 .../query/runtime/operator/FilterOperatorTest.java |  36 ------
 .../src/test/resources/queries/NumericTypes.json   | 127 ---------------------
 .../pinot/segment/spi/AggregationFunctionType.java | 111 +-----------------
 12 files changed, 20 insertions(+), 536 deletions(-)

diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotEvaluateLiteralRule.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotEvaluateLiteralRule.java
index cee1ec9d50f..856b776c966 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotEvaluateLiteralRule.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotEvaluateLiteralRule.java
@@ -189,12 +189,7 @@ public class PinotEvaluateLiteralRule {
       // to is determined by the operator's return type. Pinot's CAST function 
implementation requires two arguments:
       // the value to be cast and the target type.
       argumentTypes = new ColumnDataType[]{argumentTypes[0], 
ColumnDataType.STRING};
-      // A CAST to some DECIMAL types converts through LONG to drop the 
fraction, as at runtime (see
-      // RexExpressionUtils.handleCast()). The LONG result converts to the 
type of the CAST after the call.
-      ColumnDataType castType =
-          RelToPlanNodeConverter.isCastThroughLong(rexCall.getType(), 
operands.get(0).getType()) ? ColumnDataType.LONG
-              : 
RelToPlanNodeConverter.convertToColumnDataType(rexCall.getType());
-      arguments = new Object[]{arguments[0], castType.name()};
+      arguments = new Object[]{arguments[0], 
RelToPlanNodeConverter.convertToColumnDataType(rexCall.getType()).name()};
     }
     String canonicalName = 
FunctionRegistry.canonicalize(PinotRuleUtils.extractFunctionName(rexCall));
     FunctionInfo functionInfo = 
FunctionRegistry.lookupFunctionInfo(canonicalName, argumentTypes);
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverter.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverter.java
index 48165051996..6198f1cbcb0 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverter.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverter.java
@@ -1103,6 +1103,7 @@ public final class RelToPlanNodeConverter {
   /// the proper primitive type for Pinot.
   /// TODO: Revisit this method:
   ///  - Currently we are converting exact value to approximate value
+  ///  - Integer can only cover all values with precision 9; Long can only 
cover all values with precision 18
   ///
   /// [org.apache.pinot.common.utils.request.RequestUtils#getLiteralExpression(
 ///     org.apache.calcite.sql.SqlLiteral)]
@@ -1114,12 +1115,9 @@ public final class RelToPlanNodeConverter {
     int precision = relDataType.getPrecision();
     int scale = relDataType.getScale();
     if (scale == 0) {
-      // Pick the type by the precision, so that it holds every value of the 
DECIMAL type: INT holds every number with
-      // up to 9 digits, and LONG every number with up to 18 digits. For 
example, Calcite gives an integer literal
-      // beyond the BIGINT range the type DECIMAL(p, 0) with p >= 19, which 
LONG would wrap around.
-      if (precision <= 9) {
+      if (precision <= 10) {
         return isArray ? ColumnDataType.INT_ARRAY : ColumnDataType.INT;
-      } else if (precision <= 18) {
+      } else if (precision <= 38) {
         return isArray ? ColumnDataType.LONG_ARRAY : ColumnDataType.LONG;
       } else {
         // TODO: Modify it to return ColumnDataType.BIG_DECIMAL_ARRAY after 
`1.6.0` release
@@ -1139,38 +1137,6 @@ public final class RelToPlanNodeConverter {
     }
   }
 
-  /// Returns whether a CAST of a value of the operand type to the target type 
converts the value to LONG first.
-  ///
-  /// [#resolveDecimal] gives DECIMAL(p, 0) with 19 <= p <= 38 the type 
BIG_DECIMAL, which keeps the fraction of a
-  /// value. A CAST to these types from a type that is not an integer type 
(e.g. DOUBLE) converts the value through
-  /// LONG, as it did when the planner gave these types the type LONG, so that 
the result is an integer. As before, such
-  /// a CAST does not hold values beyond the LONG range: a DOUBLE saturates, a 
BIG_DECIMAL wraps around, and a STRING
-  /// fails to parse. A CAST to DECIMAL(p, 0) with p > 38 keeps the fraction, 
as before.
-  public static boolean isCastThroughLong(RelDataType targetType, RelDataType 
operandType) {
-    if (targetType.getSqlTypeName() != SqlTypeName.DECIMAL || 
targetType.getScale() != 0) {
-      return false;
-    }
-    int precision = targetType.getPrecision();
-    if (precision <= 18 || precision > 38) {
-      return false;
-    }
-    switch (operandType.getSqlTypeName()) {
-      case TINYINT:
-      case SMALLINT:
-      case INTEGER:
-      case BIGINT:
-      case UTINYINT:
-      case USMALLINT:
-      case UINTEGER:
-      case UBIGINT:
-        return false;
-      case DECIMAL:
-        return operandType.getScale() != 0;
-      default:
-        return true;
-    }
-  }
-
   public static String getTableNameFromTableScan(TableScan tableScan) {
     return getTableNameFromRelTable(tableScan.getTable());
   }
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpressionUtils.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpressionUtils.java
index 9777cbc4ad0..8bcf2bf6b63 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpressionUtils.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpressionUtils.java
@@ -367,18 +367,9 @@ public class RexExpressionUtils {
     // CAST is being rewritten into "rexCall.CAST<targetType>(inputValue)",
     //   - e.g. result type has already been converted into the CAST RexCall, 
so we assert single operand.
     assert rexCall.operands.size() == 1;
-    RexNode operand = rexCall.operands.get(0);
-    RexExpression value = fromRexNode(operand);
-    if (RelToPlanNodeConverter.isCastThroughLong(rexCall.type, 
operand.getType())) {
-      // Drop the fraction, which a CAST to BIG_DECIMAL keeps
-      value = cast(value, ColumnDataType.LONG);
-    }
-    return cast(value, 
RelToPlanNodeConverter.convertToColumnDataType(rexCall.type));
-  }
-
-  private static RexExpression.FunctionCall cast(RexExpression value, 
ColumnDataType castType) {
     List<RexExpression> operands = new ArrayList<>(2);
-    operands.add(value);
+    operands.add(fromRexNode(rexCall.operands.get(0)));
+    ColumnDataType castType = 
RelToPlanNodeConverter.convertToColumnDataType(rexCall.type);
     operands.add(new RexExpression.Literal(ColumnDataType.STRING, 
castType.name()));
     return new RexExpression.FunctionCall(castType, SqlKind.CAST.name(), 
operands);
   }
@@ -397,20 +388,15 @@ public class RexExpressionUtils {
       if (leftOperand instanceof RexLiteral) {
         return evaluateLiteralIn((RexLiteral) leftOperand, 
sarg.rangeSet.asRanges(), sarg.nullAs);
       }
-      RexExpression inExpr = dataType == ColumnDataType.BIG_DECIMAL
-          ? convertPoints(SqlKind.OR, SqlKind.EQUALS, leftOperand, 
sarg.rangeSet.asRanges(), dataType)
-          : new RexExpression.FunctionCall(ColumnDataType.BOOLEAN, 
SqlKind.IN.name(),
-              toSearchFunctionOperands(leftOperand, sarg.rangeSet.asRanges(), 
dataType));
+      RexExpression inExpr = new 
RexExpression.FunctionCall(ColumnDataType.BOOLEAN, SqlKind.IN.name(),
+          toSearchFunctionOperands(leftOperand, sarg.rangeSet.asRanges(), 
dataType));
       return addNullCheckIfRequired(leftOperand, sarg.nullAs, inExpr);
     } else if (sarg.isComplementedPoints()) {
       if (leftOperand instanceof RexLiteral) {
         return evaluateLiteralNotIn((RexLiteral) leftOperand, 
sarg.rangeSet.complement().asRanges(), sarg.nullAs);
       }
-      Set<Range> points = sarg.rangeSet.complement().asRanges();
-      RexExpression notInExpr = dataType == ColumnDataType.BIG_DECIMAL
-          ? convertPoints(SqlKind.AND, SqlKind.NOT_EQUALS, leftOperand, 
points, dataType)
-          : new RexExpression.FunctionCall(ColumnDataType.BOOLEAN, 
SqlKind.NOT_IN.name(),
-              toSearchFunctionOperands(leftOperand, points, dataType));
+      RexExpression notInExpr = new 
RexExpression.FunctionCall(ColumnDataType.BOOLEAN, SqlKind.NOT_IN.name(),
+          toSearchFunctionOperands(leftOperand, 
sarg.rangeSet.complement().asRanges(), dataType));
       return addNullCheckIfRequired(leftOperand, sarg.nullAs, notInExpr);
     } else {
       if (leftOperand instanceof RexLiteral) {
@@ -435,7 +421,8 @@ public class RexExpressionUtils {
   ///   result is `AND(NOT_IN(x, <list>), x > 0)`.
   /// - When both forms apply, the one with fewer values is used.
   ///
-  /// `BIG_DECIMAL` ranges always become comparisons, like single 
`BIG_DECIMAL` values (see [#convertPoints]).
+  /// `BIG_DECIMAL` ranges always become comparisons: an intermediate stage 
matches `IN` values with `equals`, which
+  /// depends on the scale of the value.
   private static RexExpression convertRanges(ColumnDataType dataType, RexNode 
leftOperand, RangeSet rangeSet) {
     Set<Range> ranges = rangeSet.asRanges();
     if (dataType == ColumnDataType.BIG_DECIMAL) {
@@ -476,21 +463,6 @@ public class RexExpressionUtils {
     return convertRangesToOr(dataType, leftOperand, ranges);
   }
 
-  /// Converts single values to one comparison each, e.g. `OR(x = 1, x = 2)` 
for `x IN (1, 2)` and
-  /// `AND(x <> 1, x <> 2)` for `x NOT IN (1, 2)`. Used for `BIG_DECIMAL` 
values: an intermediate stage of an older
-  /// server matches `IN` values with `equals`, which depends on the scale of 
the value (1.0 does not equal 1), and a
-  /// comparison does not.
-  private static RexExpression convertPoints(SqlKind combineKind, SqlKind 
comparisonKind, RexNode leftOperand,
-      Set<Range> points, ColumnDataType dataType) {
-    RexExpression convertedLeftOperand = fromRexNode(leftOperand);
-    List<RexExpression> terms = new ArrayList<>(points.size());
-    for (Range point : points) {
-      terms.add(new RexExpression.FunctionCall(ColumnDataType.BOOLEAN, 
comparisonKind.name(),
-          List.of(convertedLeftOperand, fromRexLiteralValue(dataType, 
point.lowerEndpoint()))));
-    }
-    return combine(combineKind, terms);
-  }
-
   private static RexExpression combine(SqlKind kind, List<RexExpression> 
terms) {
     if (terms.size() == 1) {
       return terms.get(0);
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/physical/v2/PRelToPlanNodeConverter.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/physical/v2/PRelToPlanNodeConverter.java
index a37f2f2a0f3..cc9d4416593 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/physical/v2/PRelToPlanNodeConverter.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/physical/v2/PRelToPlanNodeConverter.java
@@ -363,6 +363,7 @@ public class PRelToPlanNodeConverter {
   /// the proper primitive type for Pinot.
   /// TODO: Revisit this method:
   ///  - Currently we are converting exact value to approximate value
+  ///  - Integer can only cover all values with precision 9; Long can only 
cover all values with precision 18
   ///
   /// [org.apache.pinot.common.utils.request.RequestUtils#getLiteralExpression(
 ///     org.apache.calcite.sql.SqlLiteral)]
@@ -374,12 +375,9 @@ public class PRelToPlanNodeConverter {
     int precision = relDataType.getPrecision();
     int scale = relDataType.getScale();
     if (scale == 0) {
-      // Pick the type by the precision, so that it holds every value of the 
DECIMAL type: INT holds every number with
-      // up to 9 digits, and LONG every number with up to 18 digits. For 
example, Calcite gives an integer literal
-      // beyond the BIGINT range the type DECIMAL(p, 0) with p >= 19, which 
LONG would wrap around.
-      if (precision <= 9) {
+      if (precision <= 10) {
         return isArray ? ColumnDataType.INT_ARRAY : ColumnDataType.INT;
-      } else if (precision <= 18) {
+      } else if (precision <= 38) {
         return isArray ? ColumnDataType.LONG_ARRAY : ColumnDataType.LONG;
       } else {
         // TODO: Modify it to return ColumnDataType.BIG_DECIMAL_ARRAY after 
`1.6.0` release
diff --git 
a/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverterTest.java
 
b/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverterTest.java
index e6d9cff5a48..69d6acca0cd 100644
--- 
a/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverterTest.java
+++ 
b/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverterTest.java
@@ -115,34 +115,15 @@ public class RelToPlanNodeConverterTest {
 
   @Test
   public void testBigDecimal() {
-    // DECIMAL(p, 0) maps to the narrowest type that holds every value: INT up 
to 9 digits, LONG up to 18 digits
-    Assert.assertEquals(RelToPlanNodeConverter.convertToColumnDataType(
-            new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 
9)),
-        DataSchema.ColumnDataType.INT);
     Assert.assertEquals(RelToPlanNodeConverter.convertToColumnDataType(
             new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 
10)),
-        DataSchema.ColumnDataType.LONG);
-    Assert.assertEquals(RelToPlanNodeConverter.convertToColumnDataType(
-            new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 
18)),
-        DataSchema.ColumnDataType.LONG);
-    Assert.assertEquals(RelToPlanNodeConverter.convertToColumnDataType(
-            new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 
19)),
-        DataSchema.ColumnDataType.BIG_DECIMAL);
+        DataSchema.ColumnDataType.INT);
     Assert.assertEquals(RelToPlanNodeConverter.convertToColumnDataType(
             new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 
38)),
-        DataSchema.ColumnDataType.BIG_DECIMAL);
+        DataSchema.ColumnDataType.LONG);
     Assert.assertEquals(RelToPlanNodeConverter.convertToColumnDataType(
             new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 
39)),
         DataSchema.ColumnDataType.BIG_DECIMAL);
-    Assert.assertEquals(RelToPlanNodeConverter.convertToColumnDataType(
-            new ArraySqlType(new BasicSqlType(RelDataTypeSystem.DEFAULT, 
SqlTypeName.DECIMAL, 9), true)),
-        DataSchema.ColumnDataType.INT_ARRAY);
-    Assert.assertEquals(RelToPlanNodeConverter.convertToColumnDataType(
-            new ArraySqlType(new BasicSqlType(RelDataTypeSystem.DEFAULT, 
SqlTypeName.DECIMAL, 18), true)),
-        DataSchema.ColumnDataType.LONG_ARRAY);
-    Assert.assertEquals(RelToPlanNodeConverter.convertToColumnDataType(
-            new ArraySqlType(new BasicSqlType(RelDataTypeSystem.DEFAULT, 
SqlTypeName.DECIMAL, 19), true)),
-        DataSchema.ColumnDataType.DOUBLE_ARRAY);
 
     Assert.assertEquals(RelToPlanNodeConverter.convertToColumnDataType(
             new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 
14, 10)),
@@ -155,36 +136,6 @@ public class RelToPlanNodeConverterTest {
         DataSchema.ColumnDataType.BIG_DECIMAL);
   }
 
-  @Test
-  public void testIsCastThroughLong() {
-    RelDataType doubleType = new BasicSqlType(RelDataTypeSystem.DEFAULT, 
SqlTypeName.DOUBLE);
-    RelDataType decimal19 = new BasicSqlType(RelDataTypeSystem.DEFAULT, 
SqlTypeName.DECIMAL, 19);
-    RelDataType decimal38 = new BasicSqlType(RelDataTypeSystem.DEFAULT, 
SqlTypeName.DECIMAL, 38);
-    // Types that can have a fraction convert through LONG to DECIMAL(p, 0) 
with 19 <= p <= 38
-    Assert.assertTrue(RelToPlanNodeConverter.isCastThroughLong(decimal19, 
doubleType));
-    Assert.assertTrue(RelToPlanNodeConverter.isCastThroughLong(decimal38, 
doubleType));
-    Assert.assertTrue(RelToPlanNodeConverter.isCastThroughLong(decimal19,
-        new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 10, 
2)));
-    Assert.assertTrue(RelToPlanNodeConverter.isCastThroughLong(decimal19,
-        new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.VARCHAR)));
-    // Integer types convert directly
-    Assert.assertFalse(RelToPlanNodeConverter.isCastThroughLong(decimal19,
-        new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.INTEGER)));
-    Assert.assertFalse(RelToPlanNodeConverter.isCastThroughLong(decimal19,
-        new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.BIGINT)));
-    Assert.assertFalse(RelToPlanNodeConverter.isCastThroughLong(decimal19,
-        new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 20)));
-    // Other target types: LONG drops the fraction itself, and BIG_DECIMAL 
beyond 38 digits keeps it as before
-    Assert.assertFalse(RelToPlanNodeConverter.isCastThroughLong(
-        new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 18), 
doubleType));
-    Assert.assertFalse(RelToPlanNodeConverter.isCastThroughLong(
-        new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 39), 
doubleType));
-    Assert.assertFalse(RelToPlanNodeConverter.isCastThroughLong(
-        new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 20, 
2), doubleType));
-    Assert.assertFalse(RelToPlanNodeConverter.isCastThroughLong(
-        new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.BIGINT), 
doubleType));
-  }
-
   @Test
   public void testConvertToColumnDataTypeForArray() {
     Assert.assertEquals(RelToPlanNodeConverter.convertToColumnDataType(
diff --git 
a/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/logical/RexExpressionUtilsTest.java
 
b/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/logical/RexExpressionUtilsTest.java
index 313940e7b2b..536b2ecb948 100644
--- 
a/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/logical/RexExpressionUtilsTest.java
+++ 
b/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/logical/RexExpressionUtilsTest.java
@@ -697,7 +697,7 @@ public class RexExpressionUtilsTest {
             call(SqlKind.LESS_THAN_OR_EQUAL, ref(), intLiteral(10)))));
   }
 
-  /// BIG_DECIMAL points next to a range stay comparisons, because older 
servers match IN values with `equals`.
+  /// BIG_DECIMAL points next to a range stay comparisons, because 
intermediate stages match IN values with `equals`.
   @Test
   public void testHandleSearchBigDecimalPointsAndRange() {
     RexInputRef inputRef = 
_rexBuilder.makeInputRef(_typeFactory.createSqlType(SqlTypeName.DECIMAL, 38, 
2), 0);
@@ -716,26 +716,6 @@ public class RexExpressionUtilsTest {
     }
   }
 
-  /// `x IN (1, 2)` on BIG_DECIMAL values becomes `x = 1 OR x = 2`, because 
older servers match IN values with
-  /// `equals`, which depends on the scale of the value (e.g. a SUM of 1.0 
does not equal 1).
-  @Test
-  public void testHandleSearchBigDecimalPoints() {
-    RexExpression points = call(SqlKind.OR, call(SqlKind.EQUALS, ref(), 
bigDecimalLiteral(1)),
-        call(SqlKind.EQUALS, ref(), bigDecimalLiteral(2)));
-    Assert.assertEquals(convertBigDecimalSearch(RexUnknownAs.UNKNOWN, 
points(1, 2)), points);
-    Assert.assertEquals(convertBigDecimalSearch(RexUnknownAs.FALSE, points(1, 
2)),
-        call(SqlKind.AND, points, call(SqlKind.IS_NOT_NULL, ref())));
-  }
-
-  /// `x NOT IN (1, 2)` on BIG_DECIMAL values becomes `x <> 1 AND x <> 2`.
-  @Test
-  public void testHandleSearchBigDecimalComplementedPoints() {
-    ImmutableRangeSet<BigDecimal> rangeSet = 
ImmutableRangeSet.copyOf(points(1, 2).complement());
-    Assert.assertEquals(convertBigDecimalSearch(RexUnknownAs.UNKNOWN, 
rangeSet),
-        call(SqlKind.AND, call(SqlKind.NOT_EQUALS, ref(), 
bigDecimalLiteral(1)),
-            call(SqlKind.NOT_EQUALS, ref(), bigDecimalLiteral(2))));
-  }
-
   /// Point ranges for the values `from` to `to`, both included.
   private static ImmutableRangeSet<BigDecimal> points(int from, int to) {
     ImmutableRangeSet.Builder<BigDecimal> builder = 
ImmutableRangeSet.builder();
@@ -769,20 +749,6 @@ public class RexExpressionUtilsTest {
     return call(kind, operands);
   }
 
-  private RexExpression convertBigDecimalSearch(RexUnknownAs nullAs, 
ImmutableRangeSet<BigDecimal> rangeSet) {
-    // DECIMAL(19, 0) is a BIG_DECIMAL type
-    RexInputRef inputRef = 
_rexBuilder.makeInputRef(_typeFactory.createSqlType(SqlTypeName.DECIMAL, 19, 
0), 0);
-    Sarg<BigDecimal> sarg = Sarg.of(nullAs, rangeSet);
-    RexLiteral searchLiteral =
-        _rexBuilder.makeSearchArgumentLiteral(sarg, 
_typeFactory.createSqlType(SqlTypeName.DECIMAL, 19, 0));
-    return RexExpressionUtils.fromRexCall(
-        (RexCall) _rexBuilder.makeCall(SqlStdOperatorTable.SEARCH, inputRef, 
searchLiteral));
-  }
-
-  private static RexExpression bigDecimalLiteral(int value) {
-    return new RexExpression.Literal(ColumnDataType.BIG_DECIMAL, 
BigDecimal.valueOf(value));
-  }
-
   private RexExpression convertIntSearch(RexUnknownAs nullAs, 
ImmutableRangeSet<BigDecimal> rangeSet) {
     RexInputRef inputRef = 
_rexBuilder.makeInputRef(_typeFactory.createSqlType(SqlTypeName.INTEGER), 0);
     Sarg<BigDecimal> sarg = Sarg.of(nullAs, rangeSet);
diff --git 
a/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/physical/v2/PRelToPlanNodeConverterTest.java
 
b/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/physical/v2/PRelToPlanNodeConverterTest.java
index ade062753d7..e2ea5affb79 100644
--- 
a/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/physical/v2/PRelToPlanNodeConverterTest.java
+++ 
b/pinot-query-planner/src/test/java/org/apache/pinot/query/planner/physical/v2/PRelToPlanNodeConverterTest.java
@@ -18,10 +18,8 @@
  */
 package org.apache.pinot.query.planner.physical.v2;
 
-import org.apache.calcite.rel.type.RelDataTypeSystem;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.type.ArraySqlType;
-import org.apache.calcite.sql.type.BasicSqlType;
 import org.apache.calcite.sql.type.ObjectSqlType;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.pinot.common.utils.DataSchema;
@@ -62,32 +60,6 @@ public class PRelToPlanNodeConverterTest {
         new ArraySqlType(new ObjectSqlType(SqlTypeName.UBIGINT, 
SqlIdentifier.STAR, true, null, null), true)));
   }
 
-  @Test
-  public void testConvertDecimalTypes() {
-    // DECIMAL(p, 0) maps to the narrowest type that holds every value: INT up 
to 9 digits, LONG up to 18 digits
-    Assert.assertEquals(PRelToPlanNodeConverter.convertToColumnDataType(
-            new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 
9)),
-        DataSchema.ColumnDataType.INT);
-    Assert.assertEquals(PRelToPlanNodeConverter.convertToColumnDataType(
-            new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 
10)),
-        DataSchema.ColumnDataType.LONG);
-    Assert.assertEquals(PRelToPlanNodeConverter.convertToColumnDataType(
-            new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 
18)),
-        DataSchema.ColumnDataType.LONG);
-    Assert.assertEquals(PRelToPlanNodeConverter.convertToColumnDataType(
-            new BasicSqlType(RelDataTypeSystem.DEFAULT, SqlTypeName.DECIMAL, 
19)),
-        DataSchema.ColumnDataType.BIG_DECIMAL);
-    Assert.assertEquals(PRelToPlanNodeConverter.convertToColumnDataType(
-            new ArraySqlType(new BasicSqlType(RelDataTypeSystem.DEFAULT, 
SqlTypeName.DECIMAL, 9), true)),
-        DataSchema.ColumnDataType.INT_ARRAY);
-    Assert.assertEquals(PRelToPlanNodeConverter.convertToColumnDataType(
-            new ArraySqlType(new BasicSqlType(RelDataTypeSystem.DEFAULT, 
SqlTypeName.DECIMAL, 18), true)),
-        DataSchema.ColumnDataType.LONG_ARRAY);
-    Assert.assertEquals(PRelToPlanNodeConverter.convertToColumnDataType(
-            new ArraySqlType(new BasicSqlType(RelDataTypeSystem.DEFAULT, 
SqlTypeName.DECIMAL, 19), true)),
-        DataSchema.ColumnDataType.DOUBLE_ARRAY);
-  }
-
   @Test
   public void testConvertUuidTypes() {
     Assert.assertEquals(PRelToPlanNodeConverter.convertToColumnDataType(
diff --git a/pinot-query-planner/src/test/resources/queries/AggregatePlans.json 
b/pinot-query-planner/src/test/resources/queries/AggregatePlans.json
index a3fe22031c8..364a54fda9d 100644
--- a/pinot-query-planner/src/test/resources/queries/AggregatePlans.json
+++ b/pinot-query-planner/src/test/resources/queries/AggregatePlans.json
@@ -1,32 +1,6 @@
 {
   "aggregates_planning_tests": {
     "queries": [
-      {
-        "description": "ARRAY_AGG as BIG_DECIMAL casts only DECIMAL values 
that the planner gives INT or LONG",
-        "sql": "EXPLAIN PLAN FOR SELECT ARRAY_AGG(col4, 'BIG_DECIMAL'), 
ARRAY_AGG(CAST(col7 AS DECIMAL(20, 0)), 'BIG_DECIMAL'), ARRAY_AGG(CAST(col3 AS 
DECIMAL(5, 0)), 'BIG_DECIMAL') FROM a",
-        "output": [
-          "Execution Plan",
-          "\nPinotLogicalAggregate(group=[{}], agg#0=[ARRAYAGG($0, 
_UTF-8'BIG_DECIMAL')], agg#1=[ARRAYAGG($1, _UTF-8'BIG_DECIMAL')], 
agg#2=[ARRAYAGG($2, _UTF-8'BIG_DECIMAL')], aggType=[FINAL])",
-          "\n  PinotLogicalExchange(distribution=[hash])",
-          "\n    PinotLogicalAggregate(group=[{}], agg#0=[ARRAYAGG($0, 
_UTF-8'BIG_DECIMAL')], agg#1=[ARRAYAGG($2, _UTF-8'BIG_DECIMAL')], 
agg#2=[ARRAYAGG($3, _UTF-8'BIG_DECIMAL')], aggType=[LEAF])",
-          "\n      LogicalProject(col4=[$3], $f1=[_UTF-8'BIG_DECIMAL'], 
$f2=[CAST($6):DECIMAL(20, 0) NOT NULL], $f3=[CAST(CAST($2):DECIMAL(5, 0) NOT 
NULL):DECIMAL(2000, 1000) NOT NULL])",
-          "\n        PinotLogicalTableScan(table=[[default, a]])",
-          "\n"
-        ]
-      },
-      {
-        "description": "ARRAY_AGG casts its value to its data type, so that 
the result type is the type of the array that it returns",
-        "sql": "EXPLAIN PLAN FOR SELECT ARRAY_AGG(col3, 'LONG'), 
ARRAY_AGG(col7, 'LONG'), ARRAY_AGG(col3, 'INT') FROM a",
-        "output": [
-          "Execution Plan",
-          "\nPinotLogicalAggregate(group=[{}], agg#0=[ARRAYAGG($0, 
_UTF-8'LONG')], agg#1=[ARRAYAGG($1, _UTF-8'LONG')], agg#2=[ARRAYAGG($2, 
_UTF-8'INT')], aggType=[FINAL])",
-          "\n  PinotLogicalExchange(distribution=[hash])",
-          "\n    PinotLogicalAggregate(group=[{}], agg#0=[ARRAYAGG($0, 
_UTF-8'LONG')], agg#1=[ARRAYAGG($2, _UTF-8'LONG')], agg#2=[ARRAYAGG($3, 
_UTF-8'INT')], aggType=[LEAF])",
-          "\n      LogicalProject($f0=[CAST($2):BIGINT NOT NULL], 
$f1=[_UTF-8'LONG'], col7=[$6], col3=[$2], $f4=[_UTF-8'INT'])",
-          "\n        PinotLogicalTableScan(table=[[default, a]])",
-          "\n"
-        ]
-      },
       {
         "description": "Select AVG aggregation for a BIG_DECIMAL column, 
TODO:(No need to cast in LogicalProject)",
         "sql": "EXPLAIN PLAN FOR SELECT AVG(a.col4) as avg FROM a WHERE a.col3 
>= (SELECT AVG(a.col4) FROM a)",
diff --git 
a/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/operands/FilterOperand.java
 
b/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/operands/FilterOperand.java
index 7dbcebb79dc..ea4f7903203 100644
--- 
a/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/operands/FilterOperand.java
+++ 
b/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/operands/FilterOperand.java
@@ -20,7 +20,6 @@ package org.apache.pinot.query.runtime.operator.operands;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Ordering;
-import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.IntPredicate;
@@ -133,49 +132,12 @@ public abstract class FilterOperand implements 
TransformOperand {
         if (result == null) {
           return null;
         }
-        if (valuesEqual(firstResult, result)) {
+        if (firstResult.equals(result)) {
           return _isNotIn ? 0 : 1;
         }
       }
       return _isNotIn ? 1 : 0;
     }
-
-    /// Compares numbers by value, like a comparison does and like the 
single-stage engine does for IN. `equals()` also
-    /// compares the scale of a BigDecimal, so 1.0 (e.g. a SUM, which is a 
DOUBLE) does not equal 1, and the class of a
-    /// number, so a LONG does not equal the same INT. The planner gives the 
values of an IN the same type, so the
-    /// classes differ only if that changes.
-    private static boolean valuesEqual(Object value1, Object value2) {
-      if (value1 instanceof Number && value2 instanceof Number
-          && (value1 instanceof BigDecimal || value1.getClass() != 
value2.getClass())) {
-        return numbersEqual((Number) value1, (Number) value2);
-      }
-      return value1.equals(value2);
-    }
-
-    private static boolean numbersEqual(Number value1, Number value2) {
-      if (value1 instanceof BigDecimal || value2 instanceof BigDecimal) {
-        BigDecimal bigDecimal1 = toBigDecimal(value1);
-        BigDecimal bigDecimal2 = toBigDecimal(value2);
-        return bigDecimal1 != null && bigDecimal2 != null && 
bigDecimal1.compareTo(bigDecimal2) == 0;
-      }
-      if (value1 instanceof Double || value1 instanceof Float || value2 
instanceof Double || value2 instanceof Float) {
-        return Double.compare(value1.doubleValue(), value2.doubleValue()) == 0;
-      }
-      return value1.longValue() == value2.longValue();
-    }
-
-    /// Returns the BigDecimal of a number, or `null` for NaN and the 
infinities, which have none.
-    @Nullable
-    private static BigDecimal toBigDecimal(Number value) {
-      if (value instanceof BigDecimal) {
-        return (BigDecimal) value;
-      }
-      if (value instanceof Double || value instanceof Float) {
-        double doubleValue = value.doubleValue();
-        return Double.isFinite(doubleValue) ? BigDecimal.valueOf(doubleValue) 
: null;
-      }
-      return BigDecimal.valueOf(value.longValue());
-    }
   }
 
   public static class IsTrue extends FilterOperand {
diff --git 
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/FilterOperatorTest.java
 
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/FilterOperatorTest.java
index 03f9d97c464..b39a2d7fabb 100644
--- 
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/FilterOperatorTest.java
+++ 
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/FilterOperatorTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.pinot.query.runtime.operator;
 
-import java.math.BigDecimal;
 import java.util.List;
 import org.apache.calcite.sql.SqlKind;
 import org.apache.pinot.common.utils.DataSchema;
@@ -203,41 +202,6 @@ public class FilterOperatorTest {
     assertEquals(resultRows.get(0), new Object[]{3, 2});
   }
 
-  @Test
-  public void shouldCompareBigDecimalsByValueInInFilter() {
-    DataSchema inputSchema = new DataSchema(new String[]{"bigDecimal0"}, new 
ColumnDataType[]{
-        ColumnDataType.BIG_DECIMAL
-    });
-    when(_input.nextBlock()).thenReturn(OperatorTestUtil.block(inputSchema, 
new Object[]{new BigDecimal("1.0")},
-        new Object[]{new BigDecimal("2.5")}, new Object[]{new 
BigDecimal("3")}));
-    // 1.0 has another scale than 1, and 3 is a LONG
-    RexExpression.FunctionCall in = new 
RexExpression.FunctionCall(ColumnDataType.BOOLEAN, SqlKind.IN.name(),
-        List.of(new RexExpression.InputRef(0),
-            new RexExpression.Literal(ColumnDataType.BIG_DECIMAL, new 
BigDecimal("1")),
-            new RexExpression.Literal(ColumnDataType.LONG, 3L)));
-    FilterOperator operator = getOperator(inputSchema, in);
-    List<Object[]> resultRows = ((MseBlock.Data) 
operator.nextBlock()).asRowHeap().getRows();
-    assertEquals(resultRows.size(), 2);
-    assertEquals(resultRows.get(0), new Object[]{new BigDecimal("1.0")});
-    assertEquals(resultRows.get(1), new Object[]{new BigDecimal("3")});
-  }
-
-  @Test
-  public void shouldCompareNumbersOfOtherClassesInNotInFilter() {
-    DataSchema inputSchema = new DataSchema(new String[]{"long0"}, new 
ColumnDataType[]{
-        ColumnDataType.LONG
-    });
-    when(_input.nextBlock()).thenReturn(
-        OperatorTestUtil.block(inputSchema, new Object[]{1L}, new 
Object[]{2L}, new Object[]{3L}));
-    RexExpression.FunctionCall notIn = new 
RexExpression.FunctionCall(ColumnDataType.BOOLEAN, SqlKind.NOT_IN.name(),
-        List.of(new RexExpression.InputRef(0), new 
RexExpression.Literal(ColumnDataType.INT, 1),
-            new RexExpression.Literal(ColumnDataType.DOUBLE, 3.0)));
-    FilterOperator operator = getOperator(inputSchema, notIn);
-    List<Object[]> resultRows = ((MseBlock.Data) 
operator.nextBlock()).asRowHeap().getRows();
-    assertEquals(resultRows.size(), 1);
-    assertEquals(resultRows.get(0), new Object[]{2L});
-  }
-
   @Test
   public void shouldHandleBooleanFunction() {
     DataSchema inputSchema = new DataSchema(new String[]{"string1"}, new 
ColumnDataType[]{
diff --git a/pinot-query-runtime/src/test/resources/queries/NumericTypes.json 
b/pinot-query-runtime/src/test/resources/queries/NumericTypes.json
index 75b728a7e62..a5cc4e4e782 100644
--- a/pinot-query-runtime/src/test/resources/queries/NumericTypes.json
+++ b/pinot-query-runtime/src/test/resources/queries/NumericTypes.json
@@ -113,132 +113,5 @@
         "sql": "SELECT floatv + 1, doublev + 1 FROM {floats}"
       }
     ]
-  },
-  "exact_literals_beyond_int_and_long": {
-    "comment": "Calcite gives an integer literal beyond the BIGINT range, and 
CAST(... AS DECIMAL(p, 0)), the type DECIMAL(p, 0). 7766279631452241919 is 
99999999999999999999 wrapped around to a LONG, and -1294967296 is 3000000000 
wrapped around to an INT. The fractions of doubleCol and bigDecimalCol are 
below 0.5, because Pinot drops the fraction in a CAST to an integer type, and 
H2 rounds it.",
-    "tables": {
-      "tbl": {
-        "schema": [
-          {"name": "intCol", "type": "INT"},
-          {"name": "longCol", "type": "LONG"},
-          {"name": "doubleCol", "type": "DOUBLE"},
-          {"name": "bigDecimalCol", "type": "BIG_DECIMAL"}
-        ],
-        "inputs": [
-          [1, 1, 1.2, "2.25"],
-          [100, 7766279631452241919, -1.3, "-7.1"],
-          [-1294967296, -2, 0.4, "0"],
-          [2147483647, 5, 2.25, "3.3"]
-        ]
-      }
-    },
-    "queries": [
-      {
-        "description": "equality with a literal beyond the BIGINT range in the 
leaf stage",
-        "sql": "SELECT intCol FROM {tbl} WHERE longCol = 99999999999999999999"
-      },
-      {
-        "description": "range filter with a literal beyond the BIGINT range in 
the leaf stage",
-        "sql": "SELECT intCol FROM {tbl} WHERE longCol < 9223372036854775808"
-      },
-      {
-        "description": "IN filter with a literal beyond the BIGINT range in 
the leaf stage",
-        "sql": "SELECT intCol FROM {tbl} WHERE longCol IN (1, 
99999999999999999999)"
-      },
-      {
-        "description": "range filter with a negative literal beyond the BIGINT 
range in the leaf stage",
-        "sql": "SELECT intCol FROM {tbl} WHERE longCol > -9223372036854775809"
-      },
-      {
-        "description": "arithmetic with a literal beyond the BIGINT range in 
the leaf stage",
-        "sql": "SELECT intCol + 99999999999999999999 FROM {tbl}"
-      },
-      {
-        "description": "comparison with a literal beyond the BIGINT range in 
an intermediate stage",
-        "sql": "SELECT longCol, longCol < 9223372036854775808, longCol = 
99999999999999999999 FROM (SELECT longCol FROM {tbl} GROUP BY longCol)"
-      },
-      {
-        "description": "arithmetic with a literal beyond the BIGINT range in 
an intermediate stage",
-        "sql": "SELECT intCol + 99999999999999999999 FROM (SELECT intCol FROM 
{tbl} GROUP BY intCol)"
-      },
-      {
-        "description": "arithmetic with a literal beyond the BIGINT range that 
is evaluated during planning",
-        "sql": "SELECT intCol, 99999999999999999999 + 1, 99999999999999999999 
* 2 FROM {tbl}"
-      },
-      {
-        "description": "BIGINT value promoted to DECIMAL(19, 0) keeps its 
exact value",
-        "sql": "SELECT intCol, COALESCE(longCol, CAST(1 AS DECIMAL(5, 0))) 
FROM {tbl}"
-      },
-      {
-        "description": "BIGINT value promoted to DECIMAL(19, 0) in an 
intermediate stage keeps its exact value",
-        "sql": "SELECT longCol, COALESCE(longCol, CAST(1 AS DECIMAL(5, 0))) 
FROM (SELECT longCol FROM {tbl} GROUP BY longCol)"
-      },
-      {
-        "description": "group by a value that can be a literal beyond the 
BIGINT range",
-        "sql": "SELECT CASE WHEN intCol > 0 THEN longCol ELSE 
99999999999999999999 END AS v, COUNT(*) FROM {tbl} GROUP BY CASE WHEN intCol > 
0 THEN longCol ELSE 99999999999999999999 END"
-      },
-      {
-        "description": "equality with a DECIMAL(10, 0) literal beyond the INT 
range in the leaf stage",
-        "sql": "SELECT longCol FROM {tbl} WHERE intCol = CAST(3000000000 AS 
DECIMAL(10, 0))"
-      },
-      {
-        "description": "range filter with a DECIMAL(10, 0) literal beyond the 
INT range in the leaf stage",
-        "sql": "SELECT longCol FROM {tbl} WHERE intCol < CAST(3000000000 AS 
DECIMAL(10, 0))"
-      },
-      {
-        "description": "comparison with a DECIMAL(10, 0) literal beyond the 
INT range in an intermediate stage",
-        "sql": "SELECT intCol, intCol < CAST(3000000000 AS DECIMAL(10, 0)), 
intCol = CAST(3000000000 AS DECIMAL(10, 0)) FROM (SELECT intCol FROM {tbl} 
GROUP BY intCol)"
-      },
-      {
-        "description": "aggregations of DECIMAL(p, 0) values beyond the INT 
range",
-        "sql": "SELECT SUM(CAST(intCol AS DECIMAL(10, 0))), SUM(CAST(intCol AS 
DECIMAL(20, 0))), MAX(CAST(intCol AS DECIMAL(20, 0))) FROM {tbl} WHERE intCol > 
0"
-      },
-      {
-        "description": "group by aggregation of DECIMAL(10, 0) values beyond 
the INT range",
-        "sql": "SELECT intCol > 0, SUM(CAST(intCol AS DECIMAL(10, 0))) FROM 
{tbl} GROUP BY intCol > 0"
-      },
-      {
-        "description": "IN on the SUM of DECIMAL(19, 0) values, which is a 
BIG_DECIMAL with a scale that the IN values do not have",
-        "sql": "SELECT SUM(CAST(intCol AS DECIMAL(19, 0))) IN (CAST(1 AS 
DECIMAL(19, 0)), CAST(2 AS DECIMAL(19, 0))) FROM {tbl} WHERE intCol = 1",
-        "h2Sql": "SELECT SUM(intCol) IN (1, 2) FROM {tbl} WHERE intCol = 1"
-      },
-      {
-        "description": "IN and NOT IN on the SUM of DECIMAL(p, 0) values in 
HAVING",
-        "sql": "SELECT intCol, SUM(CAST(intCol AS DECIMAL(19, 0))) IN (1, 
100), SUM(CAST(intCol AS DECIMAL(40, 0))) NOT IN (1, 100) FROM {tbl} GROUP BY 
intCol HAVING SUM(CAST(intCol AS DECIMAL(19, 0))) IN (1, 100, 2147483647)"
-      },
-      {
-        "description": "CAST of values with a fraction to DECIMAL(19, 0) and 
DECIMAL(38, 0) in the leaf stage drops the fraction",
-        "sql": "SELECT intCol, CAST(doubleCol AS DECIMAL(19, 0)), 
CAST(bigDecimalCol AS DECIMAL(38, 0)) FROM {tbl} WHERE doubleCol > 0"
-      },
-      {
-        "description": "CAST of values with a fraction to DECIMAL(19, 0) in an 
intermediate stage drops the fraction",
-        "sql": "SELECT doubleCol, CAST(doubleCol AS DECIMAL(19, 0)), 
CAST(bigDecimalCol AS DECIMAL(19, 0)) FROM (SELECT doubleCol, bigDecimalCol 
FROM {tbl} GROUP BY doubleCol, bigDecimalCol)"
-      },
-      {
-        "description": "CAST of a value with a fraction to DECIMAL(19, 0) that 
is evaluated during planning drops the fraction",
-        "sql": "SELECT intCol, CAST(roundDecimal(1.55, 1) AS DECIMAL(19, 0)) 
FROM {tbl}",
-        "h2Sql": "SELECT intCol, CAST(1 AS DECIMAL(19, 0)) FROM {tbl}"
-      },
-      {
-        "description": "ARRAY_AGG of DECIMAL(p, 0) values returns arrays of 
its data type",
-        "sql": "SELECT arraySumLong(ARRAY_AGG(CAST(longCol AS DECIMAL(19, 0)), 
'LONG')), arraySumInt(ARRAY_AGG(CAST(intCol AS DECIMAL(10, 0)), 'INT')) FROM 
{tbl} WHERE intCol < 1000",
-        "h2Sql": "SELECT SUM(longCol), SUM(intCol) FROM {tbl} WHERE intCol < 
1000"
-      },
-      {
-        "description": "ARRAY_AGG of DOUBLE values as FLOAT and BIG_DECIMAL 
keeps the fraction",
-        "sql": "SELECT arrayElementAtFloat(ARRAY_AGG(doubleCol, 'FLOAT'), 1), 
arrayElementAtDouble(ARRAY_AGG(doubleCol, 'BIG_DECIMAL'), 1) FROM {tbl} WHERE 
intCol = 1",
-        "h2Sql": "SELECT CAST(doubleCol AS REAL), doubleCol FROM {tbl} WHERE 
intCol = 1"
-      },
-      {
-        "description": "ARRAY_AGG of DECIMAL values as BIG_DECIMAL",
-        "sql": "SELECT arrayElementAtDouble(ARRAY_AGG(CAST(longCol AS 
DECIMAL(20, 0)), 'BIG_DECIMAL'), 1), 
arrayElementAtDouble(ARRAY_AGG(CAST(doubleCol AS DECIMAL(10, 2)), 
'BIG_DECIMAL'), 1), arrayElementAtDouble(ARRAY_AGG(CAST(intCol AS DECIMAL(5, 
0)), 'BIG_DECIMAL'), 1) FROM {tbl} WHERE intCol = 1",
-        "h2Sql": "SELECT CAST(longCol AS DOUBLE), doubleCol, CAST(intCol AS 
DOUBLE) FROM {tbl} WHERE intCol = 1"
-      },
-      {
-        "description": "ARRAY_AGG of values of another type returns arrays of 
its data type",
-        "sql": "SELECT arraySumLong(ARRAY_AGG(intCol, 'LONG')), 
ARRAYLENGTH(ARRAY_AGG(doubleCol, 'FLOAT')), ARRAYLENGTH(ARRAY_AGG(longCol, 
'BIG_DECIMAL', true)) FROM {tbl}",
-        "h2Sql": "SELECT SUM(intCol), COUNT(*), COUNT(DISTINCT longCol) FROM 
{tbl}"
-      }
-    ]
   }
 }
diff --git 
a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/AggregationFunctionType.java
 
b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/AggregationFunctionType.java
index 9430d81c5d1..06d04efbb00 100644
--- 
a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/AggregationFunctionType.java
+++ 
b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/AggregationFunctionType.java
@@ -26,23 +26,14 @@ import java.util.stream.Stream;
 import javax.annotation.Nullable;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
-import org.apache.calcite.sql.SqlCall;
-import org.apache.calcite.sql.SqlCallBinding;
 import org.apache.calcite.sql.SqlKind;
-import org.apache.calcite.sql.SqlNode;
-import org.apache.calcite.sql.SqlOperandCountRange;
-import org.apache.calcite.sql.SqlOperator;
 import org.apache.calcite.sql.SqlOperatorBinding;
-import org.apache.calcite.sql.fun.SqlStdOperatorTable;
-import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.calcite.sql.type.OperandTypes;
 import org.apache.calcite.sql.type.ReturnTypes;
-import org.apache.calcite.sql.type.SqlOperandCountRanges;
 import org.apache.calcite.sql.type.SqlOperandTypeChecker;
 import org.apache.calcite.sql.type.SqlReturnTypeInference;
 import org.apache.calcite.sql.type.SqlTypeFamily;
 import org.apache.calcite.sql.type.SqlTypeName;
-import org.apache.calcite.sql.type.SqlTypeUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.Strings;
 import org.apache.pinot.spi.utils.CommonConstants;
@@ -198,7 +189,7 @@ public enum AggregationFunctionType {
       ReturnTypes.ARG1, OperandTypes.VARIADIC, SqlTypeName.OTHER, 
SqlTypeName.BIGINT),
 
   // Array aggregate functions
-  ARRAYAGG("arrayAgg", new ArrayOfComponentReturnTypeInference(), new 
ArrayAggOperandTypeChecker(), SqlTypeName.OTHER),
+  ARRAYAGG("arrayAgg", new ArrayOfComponentReturnTypeInference(), 
OperandTypes.VARIADIC, SqlTypeName.OTHER),
   LISTAGG("listAgg", SqlTypeName.OTHER, SqlTypeName.VARCHAR),
 
   SUMARRAYLONG("sumArrayLong", new 
ArrayReturnTypeInference(SqlTypeName.BIGINT), OperandTypes.ARRAY, 
SqlTypeName.OTHER),
@@ -465,106 +456,6 @@ public enum AggregationFunctionType {
     }
   }
 
-  /// Casts the value of `ARRAY_AGG(value, 'dataType'[, isDistinct])` to the 
data type, so that the return type that
-  /// [ArrayOfComponentReturnTypeInference] infers from the value is the type 
of the returned array. The function picks
-  /// its accumulator by the data type, not by the type of the value: for 
example, `ARRAY_AGG(intCol, 'LONG')` returns
-  /// longs. The cast changes the operand instead of the return type 
inference, because Calcite infers the type of an
-  /// aggregate call again after the validation (e.g. 
`Aggregate.typeMatchesInferred()`), and it cannot read the value
-  /// of a literal operand then.
-  private static class ArrayAggOperandTypeChecker implements 
SqlOperandTypeChecker {
-    @Override
-    public boolean checkOperandTypes(SqlCallBinding callBinding, boolean 
throwOnFailure) {
-      if (callBinding.getOperandCount() < 2 || 
!callBinding.isOperandLiteral(1, false)
-          || !SqlTypeUtil.inCharFamily(callBinding.getOperandType(1))) {
-        // The function fails at runtime without a data type
-        return true;
-      }
-      String dataTypeName = callBinding.getOperandLiteralValue(1, 
String.class);
-      if (dataTypeName == null) {
-        return true;
-      }
-      RelDataTypeFactory typeFactory = callBinding.getTypeFactory();
-      RelDataType dataType = toRelDataType(dataTypeName, typeFactory);
-      RelDataType valueType = callBinding.getOperandType(0);
-      // Keep multi-value columns, for which the return type inference uses 
the type of the elements. If the validation
-      // checks the call again, the value already has the data type, so 
needsCast() prevents a second cast.
-      if (dataType == null || valueType.getComponentType() != null || 
!needsCast(valueType, dataType)) {
-        return true;
-      }
-      RelDataType castType = typeFactory.createTypeWithNullability(dataType, 
valueType.isNullable());
-      SqlCall call = callBinding.getCall();
-      SqlNode cast = SqlStdOperatorTable.CAST.createCall(SqlParserPos.ZERO, 
call.operand(0),
-          
SqlTypeUtil.convertTypeToSpec(castType).withNullable(castType.isNullable()));
-      call.setOperand(0, cast);
-      callBinding.getValidator().setValidatedNodeType(cast, castType);
-      return true;
-    }
-
-    /// Returns the SQL type of a Pinot data type name, or `null` when it is 
not a data type that ARRAY_AGG supports.
-    @Nullable
-    private static RelDataType toRelDataType(String dataTypeName, 
RelDataTypeFactory typeFactory) {
-      switch (dataTypeName.toUpperCase()) {
-        case "INT":
-          return typeFactory.createSqlType(SqlTypeName.INTEGER);
-        case "LONG":
-          return typeFactory.createSqlType(SqlTypeName.BIGINT);
-        case "FLOAT":
-          return typeFactory.createSqlType(SqlTypeName.REAL);
-        case "DOUBLE":
-          return typeFactory.createSqlType(SqlTypeName.DOUBLE);
-        case "BIG_DECIMAL":
-          return typeFactory.createSqlType(SqlTypeName.DECIMAL);
-        case "BOOLEAN":
-          return typeFactory.createSqlType(SqlTypeName.BOOLEAN);
-        case "TIMESTAMP":
-          return typeFactory.createSqlType(SqlTypeName.TIMESTAMP);
-        case "STRING":
-        case "JSON":
-          return typeFactory.createSqlType(SqlTypeName.VARCHAR);
-        case "BYTES":
-          return typeFactory.createSqlType(SqlTypeName.VARBINARY);
-        case "UUID":
-          return typeFactory.createSqlType(SqlTypeName.UUID);
-        default:
-          return null;
-      }
-    }
-
-    private static boolean needsCast(RelDataType valueType, RelDataType 
dataType) {
-      SqlTypeName valueTypeName = valueType.getSqlTypeName();
-      switch (valueTypeName) {
-        case ANY:
-        case OTHER:
-          // The type is not known, so a cast cannot help
-          return false;
-        case CHAR:
-        case BINARY:
-          // Arrays of CHAR and BINARY values are STRING and BYTES arrays, 
like arrays of VARCHAR and VARBINARY values
-          return valueTypeName.getFamily() != 
dataType.getSqlTypeName().getFamily();
-        case DECIMAL:
-          if (dataType.getSqlTypeName() != SqlTypeName.DECIMAL) {
-            return true;
-          }
-          // The multi-stage engine converts the BIG_DECIMAL values of 
ARRAY_AGG to the array type of the plan. It can
-          // do this for the array type of every DECIMAL value, except 
DECIMAL(p, 0) with p <= 18, whose array type is
-          // an INT or LONG array (see 
RelToPlanNodeConverter.resolveDecimal()).
-          return valueType.getScale() == 0 && valueType.getPrecision() <= 18;
-        default:
-          return valueTypeName != dataType.getSqlTypeName();
-      }
-    }
-
-    @Override
-    public SqlOperandCountRange getOperandCountRange() {
-      return SqlOperandCountRanges.any();
-    }
-
-    @Override
-    public String getAllowedSignatures(SqlOperator op, String opName) {
-      return opName + "(<VALUE>, <DATA_TYPE>[, <IS_DISTINCT>])";
-    }
-  }
-
   /// Used for aggregation functions that always return BIGINT. The "IfEmpty" 
logic ensures that the return type is
   /// nullable for pure aggregation queries (no group-by) and filtered 
aggregation queries. Return values can be null
   /// if there are no matching rows (even if the operand type is not nullable).


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to