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

Jackie-Jiang 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 5e914c979b3 Support optional parameters argument for tuple sketch 
aggregations in the multi-stage engine (#19312)
5e914c979b3 is described below

commit 5e914c979b355c0e8c9fd4cd6f401f5f899594b5
Author: David Cromberge <[email protected]>
AuthorDate: Thu Aug 27 19:23:30 2026 +0200

    Support optional parameters argument for tuple sketch aggregations in the 
multi-stage engine (#19312)
---
 .../IntegerTupleSketchAggregationFunction.java     |  6 ++---
 .../integration/tests/custom/TupleSketchTest.java  | 15 +++++++++++
 .../pinot/segment/spi/AggregationFunctionType.java | 18 ++++++++++---
 .../segment/spi/AggregationFunctionTypeTest.java   | 30 ++++++++++++++++++++++
 4 files changed, 62 insertions(+), 7 deletions(-)

diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/IntegerTupleSketchAggregationFunction.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/IntegerTupleSketchAggregationFunction.java
index a56ce257f71..c7366e8227b 100644
--- 
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/IntegerTupleSketchAggregationFunction.java
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/IntegerTupleSketchAggregationFunction.java
@@ -59,16 +59,16 @@ import org.apache.pinot.spi.utils.CommonConstants;
 /// Usage examples:
 ///
 /// - Simple union (1 or 2 arguments): main expression to aggregate on, 
followed by an optional Tuple sketch size
-///   argument. The second argument is the sketch lgK – the given log_base2 of 
k, and defaults to 16.
+///   argument. The second argument is the nominal entries, and defaults to 
16384.
 ///   The "raw" equivalents return serialised sketches in base64-encoded 
strings.
 ///
 ///   DISTINCT_COUNT_TUPLE_SKETCH(col)
 ///
-///   DISTINCT_COUNT_TUPLE_SKETCH(col, 12)
+///   DISTINCT_COUNT_TUPLE_SKETCH(col, 16384)
 ///
 ///   DISTINCT_COUNT_RAW_INTEGER_SUM_TUPLE_SKETCH(col)
 ///
-///   DISTINCT_COUNT_RAW_INTEGER_SUM_TUPLE_SKETCH(col, 12)
+///   DISTINCT_COUNT_RAW_INTEGER_SUM_TUPLE_SKETCH(col, 16384)
 /// - Extracting a cardinality estimate from a CPC sketch:
 ///
 ///   GET_INT_TUPLE_SKETCH_ESTIMATE(sketch_bytes)
diff --git 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/TupleSketchTest.java
 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/TupleSketchTest.java
index 15789c501bf..000c7b26d96 100644
--- 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/TupleSketchTest.java
+++ 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/TupleSketchTest.java
@@ -71,6 +71,21 @@ public class TupleSketchTest extends 
CustomDataQueryClusterIntegrationTest {
     assertEquals(Double.valueOf(deserializedSketch.getEstimate()).longValue(), 
distinctCount);
     assertTrue(jsonNode.get("resultTable").get("rows").get(0).get(2).asLong() 
> 0);
     assertTrue(jsonNode.get("resultTable").get("rows").get(0).get(3).asLong() 
> 0);
+
+    String parameterizedQuery =
+        String.format(
+            "SELECT DISTINCT_COUNT_TUPLE_SKETCH(%s, 
'nominalEntries=16384;accumulatorThreshold=10'), "
+                + "DISTINCT_COUNT_RAW_INTEGER_SUM_TUPLE_SKETCH(%s, 
'nominalEntries=16384;accumulatorThreshold=10'), "
+                + "SUM_VALUES_INTEGER_SUM_TUPLE_SKETCH(%s, 
'nominalEntries=16384;accumulatorThreshold=10'), "
+                + "AVG_VALUE_INTEGER_SUM_TUPLE_SKETCH(%s, 
'nominalEntries=16384;accumulatorThreshold=10') FROM %s",
+            MET_TUPLE_SKETCH_BYTES, MET_TUPLE_SKETCH_BYTES, 
MET_TUPLE_SKETCH_BYTES, MET_TUPLE_SKETCH_BYTES,
+            getTableName());
+    jsonNode = postQuery(parameterizedQuery);
+    assertTrue(jsonNode.get("resultTable").get("rows").get(0).get(0).asLong() 
> 0);
+    assertTrue(ObjectSerDeUtils.DATA_SKETCH_INT_TUPLE_SER_DE.deserialize(
+        
Base64.getDecoder().decode(jsonNode.get("resultTable").get("rows").get(0).get(1).asText())).getEstimate()
 > 0);
+    assertTrue(jsonNode.get("resultTable").get("rows").get(0).get(2).asLong() 
> 0);
+    assertTrue(jsonNode.get("resultTable").get("rows").get(0).get(3).asLong() 
> 0);
   }
 
   @Test(dataProvider = "useV2QueryEngine")
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 a6e9900759e..080138b3a32 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
@@ -107,12 +107,13 @@ public enum AggregationFunctionType {
   DISTINCTCOUNTTHETASKETCH("distinctCountThetaSketch", ReturnTypes.BIGINT, 
OperandTypes.ONE_OR_MORE, SqlTypeName.OTHER),
   DISTINCTCOUNTRAWTHETASKETCH("distinctCountRawThetaSketch", 
ReturnTypes.VARCHAR, OperandTypes.ONE_OR_MORE,
       SqlTypeName.OTHER),
-  DISTINCTCOUNTTUPLESKETCH("distinctCountTupleSketch", ReturnTypes.BIGINT, 
OperandTypes.BINARY, SqlTypeName.OTHER),
+  DISTINCTCOUNTTUPLESKETCH("distinctCountTupleSketch", ReturnTypes.BIGINT, 
TupleSketchOperands.CHECKER,
+      SqlTypeName.OTHER),
   
DISTINCTCOUNTRAWINTEGERSUMTUPLESKETCH("distinctCountRawIntegerSumTupleSketch", 
ReturnTypes.VARCHAR,
-      OperandTypes.BINARY, SqlTypeName.OTHER),
-  SUMVALUESINTEGERSUMTUPLESKETCH("sumValuesIntegerSumTupleSketch", 
ReturnTypes.BIGINT, OperandTypes.BINARY,
+      TupleSketchOperands.CHECKER, SqlTypeName.OTHER),
+  SUMVALUESINTEGERSUMTUPLESKETCH("sumValuesIntegerSumTupleSketch", 
ReturnTypes.BIGINT, TupleSketchOperands.CHECKER,
       SqlTypeName.OTHER),
-  AVGVALUEINTEGERSUMTUPLESKETCH("avgValueIntegerSumTupleSketch", 
ReturnTypes.BIGINT, OperandTypes.BINARY,
+  AVGVALUEINTEGERSUMTUPLESKETCH("avgValueIntegerSumTupleSketch", 
ReturnTypes.BIGINT, TupleSketchOperands.CHECKER,
       SqlTypeName.OTHER),
   DISTINCTCOUNTCPCSKETCH("distinctCountCPCSketch", ReturnTypes.BIGINT,
       OperandTypes.family(List.of(SqlTypeFamily.ANY, SqlTypeFamily.ANY), i -> 
i == 1), SqlTypeName.OTHER),
@@ -241,6 +242,15 @@ public enum AggregationFunctionType {
       SqlTypeName.OTHER),
   TIMESERIESAGGREGATE("timeSeriesAggregate", SqlTypeName.OTHER, 
SqlTypeName.OTHER);
 
+  /// Nested because an enum constant's arguments cannot reference a static 
field of its own enum.
+  private static final class TupleSketchOperands {
+    static final SqlOperandTypeChecker CHECKER = OperandTypes.or(
+        OperandTypes.family(SqlTypeFamily.BINARY),
+        OperandTypes.family(SqlTypeFamily.BINARY, SqlTypeFamily.CHARACTER),
+        OperandTypes.family(SqlTypeFamily.BINARY, SqlTypeFamily.INTEGER)
+    );
+  }
+
   private static final Set<String> NAMES = Arrays.stream(values())
       .flatMap(func -> Stream.of(func.name(), func.getName(), 
func.getName().toLowerCase()))
       .collect(Collectors.toSet());
diff --git 
a/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/AggregationFunctionTypeTest.java
 
b/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/AggregationFunctionTypeTest.java
index 09de660eebd..183458395cc 100644
--- 
a/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/AggregationFunctionTypeTest.java
+++ 
b/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/AggregationFunctionTypeTest.java
@@ -18,8 +18,12 @@
  */
 package org.apache.pinot.segment.spi;
 
+import org.apache.calcite.sql.SqlOperandCountRange;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.type.SqlOperandTypeChecker;
 import org.testng.annotations.Test;
 
+import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
@@ -38,4 +42,30 @@ public class AggregationFunctionTypeTest {
     
assertTrue(AggregationFunctionType.isAggregationFunction("percentileest90"));
     
assertFalse(AggregationFunctionType.isAggregationFunction("toEpochSeconds"));
   }
+
+  @Test
+  public void testTupleSketchOperandTypes() {
+    AggregationFunctionType[] tupleSketchFunctions = {
+        AggregationFunctionType.DISTINCTCOUNTTUPLESKETCH,
+        AggregationFunctionType.DISTINCTCOUNTRAWINTEGERSUMTUPLESKETCH,
+        AggregationFunctionType.SUMVALUESINTEGERSUMTUPLESKETCH,
+        AggregationFunctionType.AVGVALUEINTEGERSUMTUPLESKETCH
+    };
+
+    for (AggregationFunctionType functionType : tupleSketchFunctions) {
+      SqlOperandTypeChecker operandTypeChecker = 
functionType.getOperandTypeChecker();
+
+      SqlOperandCountRange countRange = 
operandTypeChecker.getOperandCountRange();
+      assertEquals(countRange.getMin(), 1, functionType.name());
+      assertEquals(countRange.getMax(), 2, functionType.name());
+      assertFalse(countRange.isValidCount(3), functionType.name());
+
+      String signatures =
+          operandTypeChecker.getAllowedSignatures(SqlStdOperatorTable.COUNT, 
functionType.name());
+      assertTrue(signatures.contains("BINARY"), functionType.name() + ": " + 
signatures);
+      assertTrue(signatures.contains("CHARACTER"), functionType.name() + ": " 
+ signatures);
+      assertTrue(signatures.contains("INTEGER"), functionType.name() + ": " + 
signatures);
+      assertFalse(signatures.contains("ANY"), functionType.name() + ": " + 
signatures);
+    }
+  }
 }


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

Reply via email to