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 2017/11/16 06:47:51 UTC
calcite git commit: [CALCITE-2039] AssertionError when pushing
project to ProjectableFilterableTable
Repository: calcite
Updated Branches:
refs/heads/master f7933c7cb -> 051809b4d
[CALCITE-2039] AssertionError when pushing project to ProjectableFilterableTable
Test case from Enrico Olivelli.
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/051809b4
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/051809b4
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/051809b4
Branch: refs/heads/master
Commit: 051809b4dc580bda04c401e861a62b52553c2418
Parents: f7933c7
Author: Julian Hyde <jh...@apache.org>
Authored: Wed Nov 15 17:17:17 2017 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Wed Nov 15 17:17:17 2017 -0800
----------------------------------------------------------------------
.../org/apache/calcite/rel/core/Project.java | 3 +
.../apache/calcite/test/ScannableTableTest.java | 24 ++++
.../apache/calcite/tools/FrameworksTest.java | 143 +++++++++++++++++++
3 files changed, 170 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/051809b4/core/src/main/java/org/apache/calcite/rel/core/Project.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/Project.java b/core/src/main/java/org/apache/calcite/rel/core/Project.java
index 953eb8e..c3a2c2b 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/Project.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/Project.java
@@ -273,6 +273,9 @@ public abstract class Project extends SingleRel {
*/
public static Mappings.TargetMapping getMapping(int inputFieldCount,
List<? extends RexNode> projects) {
+ if (inputFieldCount < projects.size()) {
+ return null; // surjection is not possible
+ }
Mappings.TargetMapping mapping =
Mappings.create(MappingType.INVERSE_SURJECTION,
inputFieldCount, projects.size());
http://git-wip-us.apache.org/repos/asf/calcite/blob/051809b4/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java b/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
index 7065f1f..ae18bc6 100644
--- a/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
+++ b/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
@@ -319,6 +319,30 @@ public class ScannableTableTest {
}
/** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-2039">[CALCITE-2039]
+ * AssertionError when pushing project to ProjectableFilterableTable</a>.
+ * Cannot push down a project if it is not a permutation of columns; in this
+ * case, it contains a literal. */
+ @Test public void testCannotPushProject() throws Exception {
+ final StringBuilder buf = new StringBuilder();
+ final Table table = new BeatlesProjectableFilterableTable(buf, true);
+ final String explain = "PLAN="
+ + "EnumerableCalc(expr#0..2=[{inputs}], expr#3=[3], k=[$t2], j=[$t1], "
+ + "i=[$t0], EXPR$3=[$t3])\n"
+ + " EnumerableInterpreter\n"
+ + " BindableTableScan(table=[[s, beatles]])";
+ CalciteAssert.that()
+ .with(newSchema("s", "beatles", table))
+ .query("select \"k\",\"j\",\"i\",3 from \"s\".\"beatles\"")
+ .explainContains(explain)
+ .returnsUnordered("k=1940; j=John; i=4; EXPR$3=3",
+ "k=1940; j=Ringo; i=5; EXPR$3=3",
+ "k=1942; j=Paul; i=4; EXPR$3=3",
+ "k=1943; j=George; i=6; EXPR$3=3");
+ assertThat(buf.toString(), is("returnCount=4"));
+ }
+
+ /** Test case for
* <a href="https://issues.apache.org/jira/browse/CALCITE-1031">[CALCITE-1031]
* In prepared statement, CsvScannableTable.scan is called twice</a>. */
@Test public void testPrepared2() throws SQLException {
http://git-wip-us.apache.org/repos/asf/calcite/blob/051809b4/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java b/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
index 6a89266..684cfe7 100644
--- a/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
+++ b/core/src/test/java/org/apache/calcite/tools/FrameworksTest.java
@@ -16,17 +16,32 @@
*/
package org.apache.calcite.tools;
+import org.apache.calcite.DataContext;
import org.apache.calcite.adapter.enumerable.EnumerableConvention;
import org.apache.calcite.adapter.enumerable.EnumerableTableScan;
import org.apache.calcite.jdbc.CalciteConnection;
+import org.apache.calcite.linq4j.Enumerable;
+import org.apache.calcite.linq4j.QueryProvider;
+import org.apache.calcite.linq4j.Queryable;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.plan.ConventionTraitDef;
import org.apache.calcite.plan.RelOptAbstractTable;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptSchema;
+import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.plan.RelTraitDef;
import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.plan.volcano.AbstractConverter;
+import org.apache.calcite.prepare.CalcitePrepareImpl;
+import org.apache.calcite.prepare.Prepare;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelDistributionTraitDef;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.TableModify;
import org.apache.calcite.rel.logical.LogicalFilter;
+import org.apache.calcite.rel.logical.LogicalTableModify;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeSystem;
@@ -34,10 +49,15 @@ import org.apache.calcite.rel.type.RelDataTypeSystemImpl;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.schema.ModifiableTable;
import org.apache.calcite.schema.Path;
+import org.apache.calcite.schema.ProjectableFilterableTable;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.Schemas;
+import org.apache.calcite.schema.Statistic;
+import org.apache.calcite.schema.Statistics;
import org.apache.calcite.schema.Table;
+import org.apache.calcite.schema.impl.AbstractSchema;
import org.apache.calcite.schema.impl.AbstractTable;
import org.apache.calcite.server.CalciteServerStatement;
import org.apache.calcite.sql.SqlExplainFormat;
@@ -45,15 +65,23 @@ import org.apache.calcite.sql.SqlExplainLevel;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.dialect.AnsiSqlDialect;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.test.CalciteAssert;
+import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.Util;
import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
import org.junit.Test;
+import java.lang.reflect.Type;
import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
@@ -279,6 +307,121 @@ public class FrameworksTest {
});
}
+ /** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-2039">[CALCITE-2039]
+ * AssertionError when pushing project to ProjectableFilterableTable</a>
+ * using UPDATE via {@link Frameworks}. */
+ @Test public void testUpdate() throws Exception {
+ Table table = new TableImpl();
+ final SchemaPlus rootSchema = Frameworks.createRootSchema(true);
+ SchemaPlus schema = rootSchema.add("x", new AbstractSchema());
+ schema.add("MYTABLE", table);
+ List<RelTraitDef> traitDefs = new ArrayList<>();
+ traitDefs.add(ConventionTraitDef.INSTANCE);
+ traitDefs.add(RelDistributionTraitDef.INSTANCE);
+ SqlParser.Config parserConfig =
+ SqlParser.configBuilder(SqlParser.Config.DEFAULT)
+ .setCaseSensitive(false)
+ .build();
+
+ final FrameworkConfig config = Frameworks.newConfigBuilder()
+ .parserConfig(parserConfig)
+ .defaultSchema(schema)
+ .traitDefs(traitDefs)
+ // define the rules you want to apply
+ .ruleSets(
+ RuleSets.ofList(AbstractConverter.ExpandConversionRule.INSTANCE))
+ .programs(Programs.ofRules(Programs.RULE_SET))
+ .build();
+ executeQuery(config, " UPDATE MYTABLE set id=7 where id=1",
+ CalcitePrepareImpl.DEBUG);
+ }
+
+ private void executeQuery(FrameworkConfig config,
+ @SuppressWarnings("SameParameterValue") String query, boolean debug)
+ throws RelConversionException, SqlParseException, ValidationException {
+ Planner planner = Frameworks.getPlanner(config);
+ if (debug) {
+ System.out.println("Query:" + query);
+ }
+ SqlNode n = planner.parse(query);
+ n = planner.validate(n);
+ RelNode root = planner.rel(n).project();
+ if (debug) {
+ System.out.println(
+ RelOptUtil.dumpPlan("-- Logical Plan", root, SqlExplainFormat.TEXT,
+ SqlExplainLevel.DIGEST_ATTRIBUTES));
+ }
+ RelOptCluster cluster = root.getCluster();
+ final RelOptPlanner optPlanner = cluster.getPlanner();
+
+ RelTraitSet desiredTraits =
+ cluster.traitSet().replace(EnumerableConvention.INSTANCE);
+ final RelNode newRoot = optPlanner.changeTraits(root, desiredTraits);
+ if (debug) {
+ System.out.println(
+ RelOptUtil.dumpPlan("-- Mid Plan", newRoot, SqlExplainFormat.TEXT,
+ SqlExplainLevel.DIGEST_ATTRIBUTES));
+ }
+ optPlanner.setRoot(newRoot);
+ RelNode bestExp = optPlanner.findBestExp();
+ if (debug) {
+ System.out.println(
+ RelOptUtil.dumpPlan("-- Best Plan", bestExp, SqlExplainFormat.TEXT,
+ SqlExplainLevel.DIGEST_ATTRIBUTES));
+ }
+ }
+
+ /** Modifiable, filterable table. */
+ private static class TableImpl extends AbstractTable
+ implements ModifiableTable, ProjectableFilterableTable {
+ TableImpl() {}
+
+ public RelDataType getRowType(RelDataTypeFactory typeFactory) {
+ return typeFactory.builder()
+ .add("id", typeFactory.createSqlType(SqlTypeName.INTEGER))
+ .add("name", typeFactory.createSqlType(SqlTypeName.INTEGER))
+ .build();
+ }
+
+ public Statistic getStatistic() {
+ return Statistics.of(15D,
+ ImmutableList.of(ImmutableBitSet.of(0)),
+ ImmutableList.<RelCollation>of());
+ }
+
+ public Enumerable<Object[]> scan(DataContext root, List<RexNode> filters,
+ int[] projects) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Collection getModifiableCollection() {
+ throw new UnsupportedOperationException();
+ }
+
+ public TableModify toModificationRel(RelOptCluster cluster,
+ RelOptTable table, Prepare.CatalogReader catalogReader, RelNode child,
+ TableModify.Operation operation, List<String> updateColumnList,
+ List<RexNode> sourceExpressionList, boolean flattened) {
+ return LogicalTableModify.create(table, catalogReader, child, operation,
+ updateColumnList, sourceExpressionList, flattened);
+ }
+
+ public <T> Queryable<T> asQueryable(QueryProvider queryProvider,
+ SchemaPlus schema, String tableName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Type getElementType() {
+ return Object.class;
+ }
+
+ public Expression getExpression(SchemaPlus schema, String tableName,
+ Class clazz) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
/** Dummy type system, similar to Hive's, accessed via an INSTANCE member. */
public static class HiveLikeTypeSystem extends RelDataTypeSystemImpl {
public static final RelDataTypeSystem INSTANCE = new HiveLikeTypeSystem();