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

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


The following commit(s) were added to refs/heads/master by this push:
     new cfc53e0ad97 perf(sql): reduce temporary allocations for large IN 
filters (#20362)
cfc53e0ad97 is described below

commit cfc53e0ad97d78c8682900f7cf0cd0a9d43c5624
Author: Frank Chen <[email protected]>
AuthorDate: Sat Oct 17 09:46:05 2026 +0800

    perf(sql): reduce temporary allocations for large IN filters (#20362)
---
 .../druid/benchmark/query/InPlanningBenchmark.java | 31 ++++++++++++++++++++++
 .../builtin/ScalarInArrayOperatorConversion.java   | 15 +++++++++++
 2 files changed, 46 insertions(+)

diff --git 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/InPlanningBenchmark.java
 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/InPlanningBenchmark.java
index 44f9ba6c757..eb51af5fda7 100644
--- 
a/benchmarks/src/test/java/org/apache/druid/benchmark/query/InPlanningBenchmark.java
+++ 
b/benchmarks/src/test/java/org/apache/druid/benchmark/query/InPlanningBenchmark.java
@@ -135,6 +135,8 @@ public class InPlanningBenchmark
   private SqlEngine engine;
   @Nullable
   private PlannerFactory plannerFactory;
+  private String planOnlyLongSql;
+  private String planOnlyStringSql;
   private final Closer closer = Closer.create();
 
   @Setup(Level.Trial)
@@ -211,6 +213,9 @@ public class InPlanningBenchmark
         new DruidHookDispatcher()
     );
 
+    planOnlyLongSql = createQuery("select long1 from foo where long1 in ", 
inClauseLiteralsCount, ValueType.LONG);
+    planOnlyStringSql = createQuery("select string1 from foo where string1 in 
", inClauseLiteralsCount, ValueType.STRING);
+
     String prefix = ("explain plan for select long1 from foo where long1 in ");
     final String sql = createQuery(prefix, inClauseLiteralsCount, 
ValueType.LONG);
 
@@ -240,6 +245,22 @@ public class InPlanningBenchmark
     getPlan(sql, blackhole);
   }
 
+  @Benchmark
+  @BenchmarkMode(Mode.AverageTime)
+  @OutputTimeUnit(TimeUnit.MILLISECONDS)
+  public void queryLongInSqlPlanOnly(Blackhole blackhole)
+  {
+    planOnly(planOnlyLongSql, blackhole);
+  }
+
+  @Benchmark
+  @BenchmarkMode(Mode.AverageTime)
+  @OutputTimeUnit(TimeUnit.MILLISECONDS)
+  public void queryStringInSqlPlanOnly(Blackhole blackhole)
+  {
+    planOnly(planOnlyStringSql, blackhole);
+  }
+
   @Benchmark
   @BenchmarkMode(Mode.AverageTime)
   @OutputTimeUnit(TimeUnit.MILLISECONDS)
@@ -345,4 +366,14 @@ public class InPlanningBenchmark
       return resultSequence;
     }
   }
+
+  private void planOnly(final String sql, final Blackhole blackhole)
+  {
+    final Map<String, Object> context = ImmutableMap.of(
+        "inSubQueryThreshold", inSubQueryThreshold, "useCache", false);
+
+    try (final DruidPlanner planner = 
plannerFactory.createPlannerForTesting(engine, sql, context)) {
+      blackhole.consume(planner.plan());
+    }
+  }
 }
diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ScalarInArrayOperatorConversion.java
 
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ScalarInArrayOperatorConversion.java
index 33e49697f52..98e2994f92a 100644
--- 
a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ScalarInArrayOperatorConversion.java
+++ 
b/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/ScalarInArrayOperatorConversion.java
@@ -21,11 +21,13 @@ package org.apache.druid.sql.calcite.expression.builtin;
 
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.type.OperandTypes;
 import org.apache.calcite.sql.type.ReturnTypes;
 import org.apache.calcite.sql.type.SqlTypeFamily;
+import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.druid.math.expr.Evals;
 import org.apache.druid.query.extraction.ExtractionFn;
 import org.apache.druid.query.filter.DimFilter;
@@ -111,6 +113,19 @@ public class ScalarInArrayOperatorConversion extends 
DirectOperatorConversion
       final List<Object> arrayElementLiteralValues = new 
ArrayList<>(arrayElements.size());
 
       for (final RexNode arrayElement : arrayElements) {
+        // Extract non-null integer and string RexLiterals directly to avoid 
temporary
+        // DruidLiteral allocations for large IN lists.
+        if (arrayElement instanceof RexLiteral && 
!RexLiteral.isNullLiteral(arrayElement)) {
+          final SqlTypeName sqlTypeName = 
arrayElement.getType().getSqlTypeName();
+          if (SqlTypeName.INT_TYPES.contains(sqlTypeName)) {
+            arrayElementLiteralValues.add(((Number) 
RexLiteral.value(arrayElement)).longValue());
+            continue;
+          } else if (SqlTypeName.STRING_TYPES.contains(sqlTypeName)) {
+            
arrayElementLiteralValues.add(RexLiteral.stringValue(arrayElement));
+            continue;
+          }
+        }
+
         final DruidLiteral arrayElementEval = 
Expressions.calciteLiteralToDruidLiteral(plannerContext, arrayElement);
         if (arrayElementEval == null) {
           return null;


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

Reply via email to