You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2016/01/15 00:05:31 UTC
[09/13] calcite git commit: [CALCITE-1058] Add method
RelBuilder.empty, and rewrite LIMIT 0 to it
[CALCITE-1058] Add method RelBuilder.empty, and rewrite LIMIT 0 to it
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/ee283cad
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/ee283cad
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/ee283cad
Branch: refs/heads/branch-1.6
Commit: ee283cadf17d8add8e8ea2bf1f8dd5735f05dc1d
Parents: 3cba705
Author: Julian Hyde <jh...@apache.org>
Authored: Wed Jan 13 21:37:27 2016 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jan 14 13:51:44 2016 -0800
----------------------------------------------------------------------
.../org/apache/calcite/tools/RelBuilder.java | 21 +++++++++++++
.../org/apache/calcite/test/RelBuilderTest.java | 33 ++++++++++++++++++++
2 files changed, 54 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/ee283cad/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
index 00ce6d1..cf9fcb6 100644
--- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
+++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
@@ -1155,6 +1155,24 @@ public class RelBuilder {
return true;
}
+ /** Creates a relational expression that reads from an input and throws
+ * all of the rows away.
+ *
+ * <p>Note that this method always pops one relational expression from the
+ * stack. {@code values}, in contrast, does not pop any relational
+ * expressions, and always produces a leaf.
+ *
+ * <p>The default implementation creates a {@link Values} with the same
+ * specified row type as the input, and ignores the input entirely.
+ * But schema-on-query systems such as Drill might override this method to
+ * create a relation expression that retains the input, just to read its
+ * schema.
+ */
+ public RelBuilder empty() {
+ final Frame frame = Stacks.pop(stack);
+ return values(frame.rel.getRowType());
+ }
+
/** Creates a {@link Values} with a specified row type.
*
* <p>This method can handle cases that {@link #values(String[], Object...)}
@@ -1274,6 +1292,9 @@ public class RelBuilder {
}
final RexNode offsetNode = offset <= 0 ? null : literal(offset);
final RexNode fetchNode = fetch < 0 ? null : literal(fetch);
+ if (offsetNode == null && fetch == 0) {
+ return empty();
+ }
if (offsetNode == null && fetchNode == null && fieldCollations.isEmpty()) {
return this; // sort is trivial
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/ee283cad/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
index 0b232f4..db13a02 100644
--- a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
@@ -873,6 +873,25 @@ public class RelBuilderTest {
assertThat(str(root), is(expected));
}
+ @Test public void testEmpty() {
+ // Equivalent SQL:
+ // SELECT deptno, true FROM dept LIMIT 0
+ // optimized to
+ // VALUES
+ final RelBuilder builder = RelBuilder.create(config().build());
+ RelNode root =
+ builder.scan("DEPT")
+ .project(builder.field(0), builder.literal(false))
+ .empty()
+ .build();
+ final String expected =
+ "LogicalValues(tuples=[[]])\n";
+ assertThat(str(root), is(expected));
+ final String expectedType =
+ "RecordType(TINYINT NOT NULL DEPTNO, BOOLEAN NOT NULL $f1) NOT NULL";
+ assertThat(root.getRowType().getFullTypeString(), is(expectedType));
+ }
+
@Test public void testValues() {
// Equivalent SQL:
// VALUES (true, 1), (false, -50) AS t(a, b)
@@ -1071,6 +1090,20 @@ public class RelBuilderTest {
assertThat(str(root), is(expected));
}
+ @Test public void testSortLimit0() {
+ // Equivalent SQL:
+ // SELECT *
+ // FROM emp
+ // ORDER BY deptno DESC FETCH 0
+ final RelBuilder builder = RelBuilder.create(config().build());
+ final RelNode root =
+ builder.scan("EMP")
+ .sortLimit(-1, 0, builder.desc(builder.field("DEPTNO")))
+ .build();
+ final String expected = "LogicalValues(tuples=[[]])\n";
+ assertThat(str(root), is(expected));
+ }
+
/** Tests that a sort on a field followed by a limit gives the same
* effect as calling sortLimit.
*