[CALCITE-2720] RelMetadataQuery.getTableOrigin throws IndexOutOfBoundsException 
if RelNode has no columns (Zoltan Haindrich)

An example is an Aggregate with empty groupKey an no aggregate
functions. Occurs during LoptOptimizeJoinRule.

Close apache/calcite#949


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/7f8556e6
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/7f8556e6
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/7f8556e6

Branch: refs/heads/master
Commit: 7f8556e6520ea692550c9540559e548126208dad
Parents: de9a716
Author: Zoltan Haindrich <[email protected]>
Authored: Fri Nov 30 15:49:15 2018 +0100
Committer: Julian Hyde <[email protected]>
Committed: Fri Nov 30 21:05:45 2018 -0800

----------------------------------------------------------------------
 .../calcite/rel/metadata/RelMetadataQuery.java       |  3 +++
 .../org/apache/calcite/test/RelMetadataTest.java     | 15 +++++++++++++++
 2 files changed, 18 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/7f8556e6/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java 
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
index d8f3dd2..e1c37e6 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
@@ -412,6 +412,9 @@ public class RelMetadataQuery {
     // Determine the simple origin of the first column in the
     // RelNode.  If it's simple, then that means that the underlying
     // table is also simple, even if the column itself is derived.
+    if (rel.getRowType().getFieldCount() == 0) {
+      return null;
+    }
     final Set<RelColumnOrigin> colOrigins = getColumnOrigins(rel, 0);
     if (colOrigins == null || colOrigins.size() == 0) {
       return null;

http://git-wip-us.apache.org/repos/asf/calcite/blob/7f8556e6/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 4ee5881..4628875 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -87,6 +87,7 @@ 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.tools.RelBuilder.AggCall;
 import org.apache.calcite.util.BuiltInMethod;
 import org.apache.calcite.util.ImmutableBitSet;
 import org.apache.calcite.util.ImmutableIntList;
@@ -2385,6 +2386,20 @@ public class RelMetadataTest extends SqlToRelTestBase {
     }
   };
 
+  /** Tests calling {@link RelMetadataQuery#getTableOrigin} for
+   * an aggregate with no columns. Previously threw. */
+  @Test public void testEmptyAggregateTableOrigin() {
+    final FrameworkConfig config = RelBuilderTest.config().build();
+    final RelBuilder builder = RelBuilder.create(config);
+    RelMetadataQuery mq = RelMetadataQuery.instance();
+    RelNode agg = builder
+        .scan("EMP")
+        .aggregate(builder.groupKey())
+        .build();
+    final RelOptTable tableOrigin = mq.getTableOrigin(agg);
+    assertThat(tableOrigin, nullValue());
+  }
+
   @Test public void testGetPredicatesForJoin() throws Exception {
     final FrameworkConfig config = RelBuilderTest.config().build();
     final RelBuilder builder = RelBuilder.create(config);

Reply via email to