You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by gi...@apache.org on 2021/11/16 23:41:14 UTC

[druid] branch master updated: sql skip reduce of complex literal expressions (#11928)

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

gian 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 54fead3  sql skip reduce of complex literal expressions (#11928)
54fead3 is described below

commit 54fead354612c6bd013a90665c8417426d401a74
Author: Clint Wylie <cw...@apache.org>
AuthorDate: Tue Nov 16 15:40:42 2021 -0800

    sql skip reduce of complex literal expressions (#11928)
---
 .../sql/calcite/planner/DruidRexExecutor.java      |   4 +
 .../sql/calcite/planner/DruidRexExecutorTest.java  | 139 +++++++++++++++++++++
 2 files changed, 143 insertions(+)

diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidRexExecutor.java b/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidRexExecutor.java
index ff61050..1fae32d 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidRexExecutor.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidRexExecutor.java
@@ -34,6 +34,7 @@ import org.apache.druid.math.expr.Parser;
 import org.apache.druid.segment.column.RowSignature;
 import org.apache.druid.sql.calcite.expression.DruidExpression;
 import org.apache.druid.sql.calcite.expression.Expressions;
+import org.apache.druid.sql.calcite.table.RowSignatures;
 
 import java.math.BigDecimal;
 import java.util.Arrays;
@@ -145,6 +146,9 @@ public class DruidRexExecutor implements RexExecutor
         } else if (sqlTypeName == SqlTypeName.ARRAY) {
           assert exprResult.isArray();
           literal = rexBuilder.makeLiteral(Arrays.asList(exprResult.asArray()), constExp.getType(), true);
+        } else if (sqlTypeName == SqlTypeName.OTHER && constExp.getType() instanceof RowSignatures.ComplexSqlType) {
+          // complex constant is not reducible, so just leave it as an expression
+          literal = constExp;
         } else {
           literal = rexBuilder.makeLiteral(exprResult.value(), constExp.getType(), true);
         }
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/planner/DruidRexExecutorTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/planner/DruidRexExecutorTest.java
new file mode 100644
index 0000000..a44995e
--- /dev/null
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/planner/DruidRexExecutorTest.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.sql.calcite.planner;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.sql.SqlFunctionCategory;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.type.ReturnTypes;
+import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
+import org.apache.calcite.sql.type.SqlTypeFamily;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.druid.java.util.common.StringUtils;
+import org.apache.druid.segment.column.ColumnType;
+import org.apache.druid.segment.column.RowSignature;
+import org.apache.druid.sql.calcite.expression.DirectOperatorConversion;
+import org.apache.druid.sql.calcite.expression.DruidExpression;
+import org.apache.druid.sql.calcite.expression.Expressions;
+import org.apache.druid.sql.calcite.expression.OperatorConversions;
+import org.apache.druid.sql.calcite.schema.DruidSchema;
+import org.apache.druid.sql.calcite.schema.DruidSchemaCatalog;
+import org.apache.druid.sql.calcite.schema.NamedDruidSchema;
+import org.apache.druid.sql.calcite.schema.NamedViewSchema;
+import org.apache.druid.sql.calcite.schema.ViewSchema;
+import org.apache.druid.sql.calcite.table.RowSignatures;
+import org.apache.druid.sql.calcite.util.CalciteTests;
+import org.apache.druid.testing.InitializedNullHandlingTest;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class DruidRexExecutorTest extends InitializedNullHandlingTest
+{
+  private static final SqlOperator OPERATOR = OperatorConversions
+      .operatorBuilder(StringUtils.toUpperCase("hyper_unique"))
+      .operandTypes(SqlTypeFamily.ANY)
+      .requiredOperands(0)
+      .returnTypeInference(
+          ReturnTypes.explicit(
+              new RowSignatures.ComplexSqlType(SqlTypeName.OTHER, ColumnType.ofComplex("hyperUnique"), true)
+          )
+      )
+      .functionCategory(SqlFunctionCategory.USER_DEFINED_FUNCTION)
+      .build();
+
+  private static final PlannerContext PLANNER_CONTEXT = PlannerContext.create(
+      new DruidOperatorTable(
+          Collections.emptySet(),
+          ImmutableSet.of(new DirectOperatorConversion(OPERATOR, "hyper_unique"))
+      ),
+      CalciteTests.createExprMacroTable(),
+      new PlannerConfig(),
+      new DruidSchemaCatalog(
+          EasyMock.createMock(SchemaPlus.class),
+          ImmutableMap.of(
+              "druid", new NamedDruidSchema(EasyMock.createMock(DruidSchema.class), "druid"),
+              NamedViewSchema.NAME, new NamedViewSchema(EasyMock.createMock(ViewSchema.class))
+          )
+      ),
+      ImmutableMap.of()
+  );
+
+  private final RexBuilder rexBuilder = new RexBuilder(new JavaTypeFactoryImpl());
+
+  private final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(DruidTypeSystem.INSTANCE);
+
+  @Test
+  public void testLongsReduced()
+  {
+    RexNode call = rexBuilder.makeCall(
+        SqlStdOperatorTable.MULTIPLY,
+        rexBuilder.makeLiteral(
+            new BigDecimal(10L),
+            typeFactory.createSqlType(SqlTypeName.BIGINT), true
+        ),
+        rexBuilder.makeLiteral(
+            new BigDecimal(3L),
+            typeFactory.createSqlType(SqlTypeName.BIGINT), true
+        )
+    );
+
+    DruidRexExecutor rexy = new DruidRexExecutor(PLANNER_CONTEXT);
+    List<RexNode> reduced = new ArrayList<>();
+    rexy.reduce(rexBuilder, ImmutableList.of(call), reduced);
+    Assert.assertEquals(1, reduced.size());
+    Assert.assertEquals(SqlKind.LITERAL, reduced.get(0).getKind());
+    Assert.assertEquals(new BigDecimal(30L), ((RexLiteral) reduced.get(0)).getValue());
+  }
+
+  @Test
+  public void testComplexNotReduced()
+  {
+    DruidRexExecutor rexy = new DruidRexExecutor(PLANNER_CONTEXT);
+    RexNode call = rexBuilder.makeCall(OPERATOR);
+    List<RexNode> reduced = new ArrayList<>();
+    rexy.reduce(rexBuilder, ImmutableList.of(call), reduced);
+    Assert.assertEquals(1, reduced.size());
+    Assert.assertEquals(SqlKind.OTHER_FUNCTION, reduced.get(0).getKind());
+    Assert.assertEquals(
+        DruidExpression.fromExpression("hyper_unique()"),
+        Expressions.toDruidExpression(
+            PLANNER_CONTEXT,
+            RowSignature.builder().build(),
+            reduced.get(0)
+        )
+    );
+  }
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org