Repository: calcite Updated Branches: refs/heads/master 11ff06120 -> fcc8bf7f4
[CALCITE-2669] RelMdTableReferences should check whether references inferred from input are null for Union/Join operators Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/fcc8bf7f Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/fcc8bf7f Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/fcc8bf7f Branch: refs/heads/master Commit: fcc8bf7f44f92efb3c9a1e1f51ffc1a09cab27b9 Parents: 11ff061 Author: Jesus Camacho Rodriguez <[email protected]> Authored: Tue Nov 13 14:00:17 2018 -0800 Committer: Jesus Camacho Rodriguez <[email protected]> Committed: Tue Nov 13 14:45:06 2018 -0800 ---------------------------------------------------------------------- .../rel/metadata/RelMdTableReferences.java | 21 ++++++++-- .../apache/calcite/test/RelMetadataTest.java | 44 ++++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/fcc8bf7f/core/src/main/java/org/apache/calcite/rel/metadata/RelMdTableReferences.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdTableReferences.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdTableReferences.java index 6c2395f..6e4f153 100644 --- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdTableReferences.java +++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdTableReferences.java @@ -108,7 +108,12 @@ public class RelMdTableReferences // Gather table references, left input references remain unchanged final Multimap<List<String>, RelTableRef> leftQualifiedNamesToRefs = HashMultimap.create(); - for (RelTableRef leftRef : mq.getTableReferences(leftInput)) { + final Set<RelTableRef> leftTableRefs = mq.getTableReferences(leftInput); + if (leftTableRefs == null) { + // We could not infer the table refs from left input + return null; + } + for (RelTableRef leftRef : leftTableRefs) { assert !result.contains(leftRef); result.add(leftRef); leftQualifiedNamesToRefs.put(leftRef.getQualifiedName(), leftRef); @@ -116,7 +121,12 @@ public class RelMdTableReferences // Gather table references, right input references might need to be // updated if there are table names clashes with left input - for (RelTableRef rightRef : mq.getTableReferences(rightInput)) { + final Set<RelTableRef> rightTableRefs = mq.getTableReferences(rightInput); + if (rightTableRefs == null) { + // We could not infer the table refs from right input + return null; + } + for (RelTableRef rightRef : rightTableRefs) { int shift = 0; Collection<RelTableRef> lRefs = leftQualifiedNamesToRefs.get(rightRef.getQualifiedName()); if (lRefs != null) { @@ -145,7 +155,12 @@ public class RelMdTableReferences final Multimap<List<String>, RelTableRef> qualifiedNamesToRefs = HashMultimap.create(); for (RelNode input : rel.getInputs()) { final Map<RelTableRef, RelTableRef> currentTablesMapping = new HashMap<>(); - for (RelTableRef tableRef : mq.getTableReferences(input)) { + final Set<RelTableRef> inputTableRefs = mq.getTableReferences(input); + if (inputTableRefs == null) { + // We could not infer the table refs from input + return null; + } + for (RelTableRef tableRef : inputTableRefs) { int shift = 0; Collection<RelTableRef> lRefs = qualifiedNamesToRefs.get( tableRef.getQualifiedName()); http://git-wip-us.apache.org/repos/asf/calcite/blob/fcc8bf7f/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 1c5140f..4ee5881 100644 --- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java @@ -22,6 +22,7 @@ import org.apache.calcite.plan.RelOptCluster; import org.apache.calcite.plan.RelOptPlanner; import org.apache.calcite.plan.RelOptPredicateList; import org.apache.calcite.plan.RelOptTable; +import org.apache.calcite.plan.RelTraitSet; import org.apache.calcite.rel.InvalidRelException; import org.apache.calcite.rel.RelCollation; import org.apache.calcite.rel.RelCollationTraitDef; @@ -31,6 +32,7 @@ import org.apache.calcite.rel.RelDistributions; import org.apache.calcite.rel.RelFieldCollation; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.RelRoot; +import org.apache.calcite.rel.SingleRel; import org.apache.calcite.rel.core.Aggregate; import org.apache.calcite.rel.core.AggregateCall; import org.apache.calcite.rel.core.Correlate; @@ -2076,6 +2078,21 @@ public class RelMetadataTest extends SqlToRelTestBase { equalTo("[true, =([CATALOG, SALES, EMP].#1.$0, 5), true]")); } + @Test public void testTableReferencesJoinUnknownNode() { + final String sql = "select * from emp limit 10"; + final RelNode node = convertSql(sql); + final RelNode nodeWithUnknown = new DummyRelNode( + node.getCluster(), node.getTraitSet(), node); + final RexBuilder rexBuilder = node.getCluster().getRexBuilder(); + // Join + final LogicalJoin join = + LogicalJoin.create(nodeWithUnknown, node, rexBuilder.makeLiteral(true), + ImmutableSet.of(), JoinRelType.INNER); + final RelMetadataQuery mq = RelMetadataQuery.instance(); + final Set<RelTableRef> tableReferences = mq.getTableReferences(join); + assertNull(tableReferences); + } + @Test public void testAllPredicatesUnionMultiTable() { final String sql = "select x.sal from\n" + "(select a.deptno, a.sal from (select * from emp) as a\n" @@ -2095,6 +2112,20 @@ public class RelMetadataTest extends SqlToRelTestBase { equalTo("[=([CATALOG, SALES, EMP].#2.$0, 5)]")); } + @Test public void testTableReferencesUnionUnknownNode() { + final String sql = "select * from emp limit 10"; + final RelNode node = convertSql(sql); + final RelNode nodeWithUnknown = new DummyRelNode( + node.getCluster(), node.getTraitSet(), node); + // Union + final LogicalUnion union = + LogicalUnion.create(ImmutableList.of(nodeWithUnknown, node), + true); + final RelMetadataQuery mq = RelMetadataQuery.instance(); + final Set<RelTableRef> tableReferences = mq.getTableReferences(union); + assertNull(tableReferences); + } + private void checkNodeTypeCount(String sql, Map<Class<? extends RelNode>, Integer> expected) { final RelNode rel = convertSql(sql); final RelMetadataQuery mq = RelMetadataQuery.instance(); @@ -2505,6 +2536,19 @@ public class RelMetadataTest extends SqlToRelTestBase { } } } + + /** + * Dummy rel node used for testing. + */ + private class DummyRelNode extends SingleRel { + + /** + * Creates a <code>DummyRelNode</code>. + */ + DummyRelNode(RelOptCluster cluster, RelTraitSet traits, RelNode input) { + super(cluster, traits, input); + } + } } // End RelMetadataTest.java
