You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jc...@apache.org on 2017/06/19 16:49:32 UTC
calcite git commit: [CALCITE-1846] Metadata pulled up predicates
should skip non-deterministic calls (Ted Xu)
Repository: calcite
Updated Branches:
refs/heads/master d47191e8c -> 86a5cc9a4
[CALCITE-1846] Metadata pulled up predicates should skip non-deterministic calls (Ted Xu)
Close apache/calcite#475
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/86a5cc9a
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/86a5cc9a
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/86a5cc9a
Branch: refs/heads/master
Commit: 86a5cc9a45b28bdc6b60d27d6bb018f441109f66
Parents: d47191e
Author: Ted Xu <fr...@gmail.com>
Authored: Sun Jun 18 10:49:24 2017 +0800
Committer: Jesus Camacho Rodriguez <jc...@apache.org>
Committed: Mon Jun 19 17:23:22 2017 +0100
----------------------------------------------------------------------
.../calcite/rel/metadata/RelMdPredicates.java | 6 +-
.../java/org/apache/calcite/rex/RexUtil.java | 10 ++++
.../apache/calcite/test/RelMetadataTest.java | 60 ++++++++++++++++++++
.../org/apache/calcite/test/RexProgramTest.java | 24 ++++++++
4 files changed, 98 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/86a5cc9a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
index 5c3a35e..8c826fb 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
@@ -286,7 +286,8 @@ public class RelMdPredicates
return Util.first(inputInfo, RelOptPredicateList.EMPTY)
.union(rexBuilder,
RelOptPredicateList.of(rexBuilder,
- RelOptUtil.conjunctions(filter.getCondition())));
+ RexUtil.retainDeterministic(
+ RelOptUtil.conjunctions(filter.getCondition()))));
}
/** Infers predicates for a {@link org.apache.calcite.rel.core.SemiJoin}. */
@@ -646,7 +647,8 @@ public class RelMdPredicates
pulledUpPredicates = Iterables.concat(
RelOptUtil.conjunctions(leftChildPredicates),
RelOptUtil.conjunctions(rightChildPredicates),
- RelOptUtil.conjunctions(joinRel.getCondition()),
+ RexUtil.retainDeterministic(
+ RelOptUtil.conjunctions(joinRel.getCondition())),
inferredPredicates);
}
return RelOptPredicateList.of(rexBuilder, pulledUpPredicates,
http://git-wip-us.apache.org/repos/asf/calcite/blob/86a5cc9a/core/src/main/java/org/apache/calcite/rex/RexUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexUtil.java b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
index df82fc9..94a3119 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexUtil.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
@@ -564,6 +564,16 @@ public class RexUtil {
}
}
+ public static List<RexNode> retainDeterministic(List<RexNode> list) {
+ List<RexNode> conjuctions = Lists.newArrayList();
+ for (RexNode x : list) {
+ if (isDeterministic(x)) {
+ conjuctions.add(x);
+ }
+ }
+ return conjuctions;
+ }
+
/**
* Returns whether a given node contains a RexCall with a specified operator
*
http://git-wip-us.apache.org/repos/asf/calcite/blob/86a5cc9a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
index 6f9af88..3109b89 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -78,8 +78,12 @@ import org.apache.calcite.rex.RexTableInputRef;
import org.apache.calcite.rex.RexTableInputRef.RelTableRef;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlSpecialOperator;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.tools.FrameworkConfig;
import org.apache.calcite.tools.Frameworks;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.util.ImmutableBitSet;
@@ -2183,6 +2187,62 @@ public class RelMetadataTest extends SqlToRelTestBase {
checkNodeTypeCount(sql, expected);
}
+ private static final SqlOperator NONDETERMINISTIC_OP = new SqlSpecialOperator(
+ "NDC",
+ SqlKind.OTHER_FUNCTION,
+ 0,
+ false,
+ ReturnTypes.BOOLEAN,
+ null, null) {
+ @Override public boolean isDeterministic() {
+ return false;
+ }
+ };
+
+ @Test public void testGetPredicatesForJoin() throws Exception {
+ final FrameworkConfig config = RelBuilderTest.config().build();
+ final RelBuilder builder = RelBuilder.create(config);
+ RelNode join = builder
+ .scan("EMP")
+ .scan("DEPT")
+ .join(JoinRelType.INNER, builder.call(NONDETERMINISTIC_OP))
+ .build();
+ RelMetadataQuery mq = RelMetadataQuery.instance();
+ assertTrue(mq.getPulledUpPredicates(join).pulledUpPredicates.isEmpty());
+
+ RelNode join1 = builder
+ .scan("EMP")
+ .scan("DEPT")
+ .join(JoinRelType.INNER,
+ builder.call(SqlStdOperatorTable.EQUALS,
+ builder.field(2, 0, 0),
+ builder.field(2, 1, 0)))
+ .build();
+ assertEquals("=($0, $8)",
+ mq.getPulledUpPredicates(join1).pulledUpPredicates.get(0).toString());
+ }
+
+ @Test public void testGetPredicatesForFilter() throws Exception {
+ final FrameworkConfig config = RelBuilderTest.config().build();
+ final RelBuilder builder = RelBuilder.create(config);
+ RelNode filter = builder
+ .scan("EMP")
+ .filter(builder.call(NONDETERMINISTIC_OP))
+ .build();
+ RelMetadataQuery mq = RelMetadataQuery.instance();
+ assertTrue(mq.getPulledUpPredicates(filter).pulledUpPredicates.isEmpty());
+
+ RelNode filter1 = builder
+ .scan("EMP")
+ .filter(
+ builder.call(SqlStdOperatorTable.EQUALS,
+ builder.field(1, 0, 0),
+ builder.field(1, 0, 1)))
+ .build();
+ assertEquals("=($0, $1)",
+ mq.getPulledUpPredicates(filter1).pulledUpPredicates.get(0).toString());
+ }
+
/**
* Matcher that succeeds for any collection that, when converted to strings
* and sorted on those strings, matches the given reference string.
http://git-wip-us.apache.org/repos/asf/calcite/blob/86a5cc9a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
index f889347..fce0294 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -19,6 +19,7 @@ package org.apache.calcite.test;
import org.apache.calcite.adapter.java.JavaTypeFactory;
import org.apache.calcite.avatica.util.ByteString;
import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
+import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.plan.Strong;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
@@ -34,8 +35,11 @@ import org.apache.calcite.rex.RexProgram;
import org.apache.calcite.rex.RexProgramBuilder;
import org.apache.calcite.rex.RexSimplify;
import org.apache.calcite.rex.RexUtil;
+import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlSpecialOperator;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.type.SqlTypeAssignmentRules;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.util.DateString;
@@ -65,6 +69,8 @@ import java.util.TreeMap;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
/**
@@ -1550,6 +1556,24 @@ public class RexProgramTest {
checkSimplifyUnchanged(le(literalAbc, literalZero));
}
+ @Test public void testIsDeterministic() {
+ SqlOperator ndc = new SqlSpecialOperator(
+ "NDC",
+ SqlKind.OTHER_FUNCTION,
+ 0,
+ false,
+ ReturnTypes.BOOLEAN,
+ null, null) {
+ @Override public boolean isDeterministic() {
+ return false;
+ }
+ };
+ RexNode n = rexBuilder.makeCall(ndc);
+ assertFalse(RexUtil.isDeterministic(n));
+ assertEquals(0,
+ RexUtil.retainDeterministic(RelOptUtil.conjunctions(n)).size());
+ }
+
private Calendar cal(int y, int m, int d, int h, int mm, int s) {
final Calendar c = Util.calendar();
c.set(Calendar.YEAR, y);