You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by hy...@apache.org on 2019/06/30 20:29:43 UTC
[calcite] 01/01: [CALCITE-3151] RexCall's Monotonicity is not
considered in determining a Calc's collation
This is an automated email from the ASF dual-hosted git repository.
hyuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
commit 914e2127b096dd40d6c8a5f5c05ddad89b2e0863
Author: Zhenghua Gao <do...@gmail.com>
AuthorDate: Thu Jun 27 19:55:52 2019 +0800
[CALCITE-3151] RexCall's Monotonicity is not considered in determining a Calc's collation
---
.../calcite/rel/metadata/RelMdCollation.java | 9 +++-
.../org/apache/calcite/test/RelOptRulesTest.java | 53 ++++++++++++++++++++++
2 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
index 6da79ce..b669229 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
@@ -65,6 +65,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.stream.Collectors;
/**
* RelMdCollation supplies a default implementation of
@@ -240,7 +241,13 @@ public class RelMdCollation
* {@link org.apache.calcite.rel.core.Calc}'s collation. */
public static List<RelCollation> calc(RelMetadataQuery mq, RelNode input,
RexProgram program) {
- return program.getCollations(mq.collations(input));
+ final List<RexNode> projects =
+ program
+ .getProjectList()
+ .stream()
+ .map((p) -> program.expandLocalRef(p))
+ .collect(Collectors.toList());
+ return project(mq, input, projects);
}
/** Helper method to determine a {@link Project}'s collation. */
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 2e33132..337ce66 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -131,13 +131,18 @@ import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rex.RexCall;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.runtime.Hook;
+import org.apache.calcite.sql.SqlFunction;
+import org.apache.calcite.sql.SqlFunctionCategory;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlOperatorBinding;
import org.apache.calcite.sql.SqlSpecialOperator;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.type.OperandTypes;
import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.sql.validate.SqlMonotonicity;
import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql2rel.SqlToRelConverter;
import org.apache.calcite.test.catalog.MockCatalogReader;
@@ -168,6 +173,7 @@ import static org.apache.calcite.plan.RelOptRule.operand;
import static org.apache.calcite.plan.RelOptRule.operandJ;
import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
/**
@@ -5620,6 +5626,53 @@ public class RelOptRulesTest extends RelOptTestBase {
.withPre(preProgram).with(program).check();
}
+ /** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-3151">[CALCITE-3151]
+ * RexCall's Monotonicity is not considered in determining a Calc's collation</a>
+ */
+ @Test public void testMonotonicityUDF() throws Exception {
+ final SqlFunction monotonicityFun =
+ new SqlFunction("MONOFUN", SqlKind.OTHER_FUNCTION, ReturnTypes.BIGINT, null,
+ OperandTypes.NILADIC, SqlFunctionCategory.USER_DEFINED_FUNCTION) {
+ @Override public boolean isDeterministic() {
+ return false;
+ }
+
+ @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
+ return SqlMonotonicity.INCREASING;
+ }
+ };
+
+ // Build a tree equivalent to the SQL
+ // SELECT sal, MONOFUN() AS n FROM emp
+ final RelBuilder builder =
+ RelBuilder.create(RelBuilderTest.config().build());
+ final RelNode root =
+ builder.scan("EMP")
+ .project(builder.field("SAL"),
+ builder.alias(builder.call(monotonicityFun), "M"))
+ .build();
+
+ HepProgram preProgram = new HepProgramBuilder().build();
+ HepPlanner prePlanner = new HepPlanner(preProgram);
+ prePlanner.setRoot(root);
+ final RelNode relBefore = prePlanner.findBestExp();
+ final RelCollation collationBefore =
+ relBefore.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE);
+
+ HepProgram hepProgram = new HepProgramBuilder()
+ .addRuleInstance(ProjectToCalcRule.INSTANCE)
+ .build();
+
+ HepPlanner hepPlanner = new HepPlanner(hepProgram);
+ hepPlanner.setRoot(root);
+ final RelNode relAfter = hepPlanner.findBestExp();
+ final RelCollation collationAfter =
+ relAfter.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE);
+
+ assertEquals(collationBefore, collationAfter);
+ }
+
/**
* Custom implementation of {@link Filter} for use
* in test case to verify that {@link FilterMultiJoinMergeRule}