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 2020/06/10 15:28:39 UTC
[calcite] branch master updated: [CALCITE-4018] Support trait
propagation for EnumerableValues
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
The following commit(s) were added to refs/heads/master by this push:
new 7c5c7e3 [CALCITE-4018] Support trait propagation for EnumerableValues
7c5c7e3 is described below
commit 7c5c7e3b77b6a7606e1295dd7c47815cbbe10871
Author: Haisheng Yuan <h....@alibaba-inc.com>
AuthorDate: Tue Jun 9 19:20:50 2020 -0500
[CALCITE-4018] Support trait propagation for EnumerableValues
In addition, add code snippet to demonstrate how to generate IndexScan on
demand by passing required collation through TableScan.
---
.../adapter/enumerable/EnumerableTableScan.java | 22 +++++++++++++
.../adapter/enumerable/EnumerableValues.java | 37 ++++++++++++++++++++++
.../calcite/rel/metadata/RelMdCollation.java | 2 +-
.../org/apache/calcite/test/TopDownOptTest.java | 12 +++++++
.../org/apache/calcite/test/TopDownOptTest.xml | 37 ++++++++++++++++++++++
5 files changed, 109 insertions(+), 1 deletion(-)
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java
index fe10098..1381463 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableTableScan.java
@@ -29,6 +29,7 @@ import org.apache.calcite.linq4j.tree.MethodCallExpression;
import org.apache.calcite.linq4j.tree.ParameterExpression;
import org.apache.calcite.linq4j.tree.Primitive;
import org.apache.calcite.linq4j.tree.Types;
+import org.apache.calcite.plan.DeriveMode;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelOptUtil;
@@ -73,6 +74,27 @@ public class EnumerableTableScan
: "EnumerableTableScan can't implement " + table + ", see EnumerableTableScan#canHandle";
}
+ /**
+ * Code snippet to demonstrate how to generate IndexScan on demand
+ * by passing required collation through TableScan.
+ *
+ * @return IndexScan if there is index available on collation keys
+ */
+ @Override public RelNode passThrough(final RelTraitSet required) {
+/*
+ keys = required.getCollation().getKeys();
+ if (table has index on keys) {
+ direction = forward or backward;
+ return new IndexScan(table, indexInfo, direction);
+ }
+*/
+ return null;
+ }
+
+ @Override public DeriveMode getDeriveMode() {
+ return DeriveMode.PROHIBITED;
+ }
+
/** Creates an EnumerableTableScan. */
public static EnumerableTableScan create(RelOptCluster cluster,
RelOptTable relOptTable) {
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableValues.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableValues.java
index 97b6554..8c6fa5c 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableValues.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableValues.java
@@ -21,10 +21,13 @@ import org.apache.calcite.linq4j.tree.BlockBuilder;
import org.apache.calcite.linq4j.tree.Expression;
import org.apache.calcite.linq4j.tree.Expressions;
import org.apache.calcite.linq4j.tree.Primitive;
+import org.apache.calcite.plan.DeriveMode;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelDistributionTraitDef;
+import org.apache.calcite.rel.RelFieldCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Values;
import org.apache.calcite.rel.metadata.RelMdCollation;
@@ -37,6 +40,7 @@ import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.Pair;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Ordering;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -70,6 +74,39 @@ public class EnumerableValues extends Values implements EnumerableRel {
return new EnumerableValues(getCluster(), rowType, tuples, traitSet);
}
+ @Override public RelNode passThrough(final RelTraitSet required) {
+ RelCollation collation = required.getCollation();
+ if (collation == null || collation.isDefault()) {
+ return null;
+ }
+
+ // A Values with 0 or 1 rows can be ordered by any collation.
+ if (tuples.size() > 1) {
+ Ordering<List<RexLiteral>> ordering = null;
+ // Generate ordering comparator according to the required collations.
+ for (RelFieldCollation fc : collation.getFieldCollations()) {
+ Ordering<List<RexLiteral>> comparator = RelMdCollation.comparator(fc);
+ if (ordering == null) {
+ ordering = comparator;
+ } else {
+ ordering = ordering.compound(comparator);
+ }
+ }
+ // Check whether the tuples are sorted by required collations.
+ if (!ordering.isOrdered(tuples)) {
+ return null;
+ }
+ }
+
+ // The tuples order satisfies the collation, we just create a new
+ // relnode with required collation info.
+ return copy(traitSet.replace(collation), ImmutableList.of());
+ }
+
+ @Override public DeriveMode getDeriveMode() {
+ return DeriveMode.PROHIBITED;
+ }
+
public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
/*
return Linq4j.asEnumerable(
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 1a5b42b..4923bfc 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
@@ -405,7 +405,7 @@ public class RelMdCollation
return list;
}
- private static Ordering<List<RexLiteral>> comparator(
+ public static Ordering<List<RexLiteral>> comparator(
RelFieldCollation fieldCollation) {
final int nullComparison = fieldCollation.nullDirection.nullComparison;
final int x = fieldCollation.getFieldIndex();
diff --git a/core/src/test/java/org/apache/calcite/test/TopDownOptTest.java b/core/src/test/java/org/apache/calcite/test/TopDownOptTest.java
index 6b6ceb6..28950fd 100644
--- a/core/src/test/java/org/apache/calcite/test/TopDownOptTest.java
+++ b/core/src/test/java/org/apache/calcite/test/TopDownOptTest.java
@@ -73,6 +73,18 @@ import java.util.List;
* </ol>
*/
class TopDownOptTest extends RelOptTestBase {
+ @Test void testValuesTraitRequest() {
+ final String sql = "SELECT * from (values (1, 1), (2, 1), (1, 2), (2, 2))\n"
+ + "as t(a, b) order by b, a";
+ Query.create(sql).check();
+ }
+
+ @Test void testValuesTraitRequestNeg() {
+ final String sql = "SELECT * from (values (1, 1), (2, 1), (3, 2), (2, 2))\n"
+ + "as t(a, b) order by b, a";
+ Query.create(sql).check();
+ }
+
@Test void testSortAgg() {
final String sql = "select mgr, count(*) from sales.emp\n"
+ "group by mgr order by mgr desc nulls last limit 5";
diff --git a/core/src/test/resources/org/apache/calcite/test/TopDownOptTest.xml b/core/src/test/resources/org/apache/calcite/test/TopDownOptTest.xml
index 8dc333c..eb266ba 100644
--- a/core/src/test/resources/org/apache/calcite/test/TopDownOptTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/TopDownOptTest.xml
@@ -1192,4 +1192,41 @@ EnumerableCorrelate(correlation=[$cor2], joinType=[semi], requiredColumns=[{0}])
]]>
</Resource>
</TestCase>
+ <TestCase name="testValuesTraitRequest">
+ <Resource name="sql">
+ <![CDATA[SELECT * from (values (1, 1), (2, 1), (1, 2), (2, 2))
+as t(a, b) order by b, a]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalSort(sort0=[$1], sort1=[$0], dir0=[ASC], dir1=[ASC])
+ LogicalProject(A=[$0], B=[$1])
+ LogicalValues(tuples=[[{ 1, 1 }, { 2, 1 }, { 1, 2 }, { 2, 2 }]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+EnumerableValues(tuples=[[{ 1, 1 }, { 2, 1 }, { 1, 2 }, { 2, 2 }]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testValuesTraitRequestNeg">
+ <Resource name="sql">
+ <![CDATA[SELECT * from (values (1, 1), (2, 1), (3, 2), (2, 2))
+as t(a, b) order by b, a]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalSort(sort0=[$1], sort1=[$0], dir0=[ASC], dir1=[ASC])
+ LogicalProject(A=[$0], B=[$1])
+ LogicalValues(tuples=[[{ 1, 1 }, { 2, 1 }, { 3, 2 }, { 2, 2 }]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+EnumerableSort(sort0=[$1], sort1=[$0], dir0=[ASC], dir1=[ASC])
+ EnumerableValues(tuples=[[{ 1, 1 }, { 2, 1 }, { 3, 2 }, { 2, 2 }]])
+]]>
+ </Resource>
+ </TestCase>
</Root>