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