Repository: phoenix Updated Branches: refs/heads/calcite 145db4a20 -> 500e85cc1
Add test cases that verify SortJoinTransposeRule; Code refine Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/500e85cc Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/500e85cc Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/500e85cc Branch: refs/heads/calcite Commit: 500e85cc1894eb1e8474dd162fd398c059d30f3f Parents: 145db4a Author: maryannxue <[email protected]> Authored: Wed Oct 21 10:36:52 2015 -0400 Committer: maryannxue <[email protected]> Committed: Wed Oct 21 10:36:52 2015 -0400 ---------------------------------------------------------------------- .../org/apache/phoenix/calcite/CalciteIT.java | 16 +++++ .../apache/phoenix/calcite/CalciteUtils.java | 15 ---- .../apache/phoenix/calcite/PhoenixTable.java | 2 +- .../calcite/jdbc/PhoenixPrepareImpl.java | 3 - .../phoenix/calcite/rel/PhoenixLimit.java | 17 ++--- .../phoenix/calcite/rel/PhoenixTableScan.java | 24 ++----- .../calcite/rules/PhoenixAddScanLimitRule.java | 73 -------------------- .../calcite/rules/PhoenixConverterRules.java | 4 -- .../rules/PhoenixFilterScanMergeRule.java | 4 +- 9 files changed, 31 insertions(+), 127 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/500e85cc/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java index f8641da..5987b32 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteIT.java @@ -584,6 +584,22 @@ public class CalciteIT extends BaseClientManagedTimeIT { " PhoenixServerProject(supplier_id=[$0], NAME=[$1])\n" + " PhoenixTableScan(table=[[phoenix, Join, SupplierTable]])\n") .close(); + + start(false).sql("SELECT \"order_id\", i.name, i.price, discount2, quantity FROM " + JOIN_ORDER_TABLE_FULL_NAME + " o LEFT JOIN " + + JOIN_ITEM_TABLE_FULL_NAME + " i ON o.\"item_id\" = i.\"item_id\" limit 2") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixClientProject(order_id=[$0], NAME=[$4], PRICE=[$5], DISCOUNT2=[$6], QUANTITY=[$2])\n" + + " PhoenixLimit(fetch=[2])\n" + + " PhoenixClientJoin(condition=[=($1, $3)], joinType=[left])\n" + + " PhoenixClientSort(sort0=[$1], dir0=[ASC])\n" + + " PhoenixLimit(fetch=[2])\n" + + " PhoenixToClientConverter\n" + + " PhoenixServerProject(order_id=[$0], item_id=[$2], QUANTITY=[$4])\n" + + " PhoenixTableScan(table=[[phoenix, Join, OrderTable]])\n" + + " PhoenixToClientConverter\n" + + " PhoenixServerProject(item_id=[$0], NAME=[$1], PRICE=[$2], DISCOUNT2=[$4])\n" + + " PhoenixTableScan(table=[[phoenix, Join, ItemTable]])\n") + .close(); } @Test public void testMultiJoin() throws Exception { http://git-wip-us.apache.org/repos/asf/phoenix/blob/500e85cc/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java index e5a2372..27062cf 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java @@ -864,21 +864,6 @@ public class CalciteUtils { return (AggregateFunction) (fFactory.newFunction(aggFunc, exprs)); } - public static Object evaluateStatelessExpression(RexNode node) { - try { - Expression expression = toExpression(node, null); - if (expression.isStateless() && expression.getDeterminism() == Determinism.ALWAYS) { - ImmutableBytesWritable ptr = new ImmutableBytesWritable(); - expression.evaluate(null, ptr); - return expression.getDataType().toObject(ptr); - } - } catch (Exception e) { - // Expression is not stateless. do nothing. - } - - return null; - } - public static interface ExpressionFactory { public Expression newExpression(RexNode node, Implementor implementor); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/500e85cc/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java index 2cfe345..4be7450 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTable.java @@ -104,7 +104,7 @@ public class PhoenixTable extends AbstractTable implements TranslatableTable { final RelOptCluster cluster = context.getCluster(); // TODO Is there a better place to do this? cluster.setMetadataProvider(PhoenixRel.METADATA_PROVIDER); - return PhoenixTableScan.create(cluster, relOptTable, null, null); + return PhoenixTableScan.create(cluster, relOptTable, null); } @Override http://git-wip-us.apache.org/repos/asf/phoenix/blob/500e85cc/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java index d3ed709..fc7406b 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/jdbc/PhoenixPrepareImpl.java @@ -24,7 +24,6 @@ import org.apache.phoenix.calcite.PhoenixSchema; import org.apache.phoenix.calcite.metadata.PhoenixRelMetadataProvider; import org.apache.phoenix.calcite.parse.SqlCreateView; import org.apache.phoenix.calcite.parser.PhoenixParserImpl; -import org.apache.phoenix.calcite.rules.PhoenixAddScanLimitRule; import org.apache.phoenix.calcite.rules.PhoenixCompactClientSortRule; import org.apache.phoenix.calcite.rules.PhoenixFilterScanMergeRule; import org.apache.phoenix.calcite.rules.PhoenixInnerSortRemoveRule; @@ -70,8 +69,6 @@ public class PhoenixPrepareImpl extends CalcitePrepareImpl { planner.addRule(rule); } planner.addRule(PhoenixFilterScanMergeRule.INSTANCE); - planner.addRule(PhoenixAddScanLimitRule.LIMIT_SCAN); - planner.addRule(PhoenixAddScanLimitRule.LIMIT_SERVERPROJECT_SCAN); planner.addRule(PhoenixCompactClientSortRule.SORT_SERVERAGGREGATE); planner.addRule(PhoenixJoinSingleValueAggregateMergeRule.INSTANCE); planner.addRule(PhoenixInnerSortRemoveRule.INSTANCE); http://git-wip-us.apache.org/repos/asf/phoenix/blob/500e85cc/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java index ab182b0..fc7637e 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixLimit.java @@ -13,8 +13,8 @@ import org.apache.calcite.rel.RelWriter; import org.apache.calcite.rel.SingleRel; import org.apache.calcite.rel.metadata.RelMdCollation; import org.apache.calcite.rel.metadata.RelMetadataQuery; +import org.apache.calcite.rex.RexLiteral; import org.apache.calcite.rex.RexNode; -import org.apache.phoenix.calcite.CalciteUtils; import org.apache.phoenix.compile.QueryPlan; import org.apache.phoenix.compile.RowProjector; import org.apache.phoenix.compile.OrderByCompiler.OrderBy; @@ -25,7 +25,6 @@ import com.google.common.base.Supplier; public class PhoenixLimit extends SingleRel implements PhoenixRel { public final RexNode offset; public final RexNode fetch; - public final Integer statelessFetch; public static PhoenixLimit create(final RelNode input, RexNode offset, RexNode fetch) { RelOptCluster cluster = input.getCluster(); @@ -44,8 +43,6 @@ public class PhoenixLimit extends SingleRel implements PhoenixRel { super(cluster, traits, input); this.offset = offset; this.fetch = fetch; - Object value = fetch == null ? null : CalciteUtils.evaluateStatelessExpression(fetch); - this.statelessFetch = value == null ? null : ((Number) value).intValue(); } @Override @@ -79,23 +76,19 @@ public class PhoenixLimit extends SingleRel implements PhoenixRel { @Override public double getRows() { double rows = super.getRows(); - // TODO Should we apply a factor to ensure that a limit can be propagated to - // lower nodes as much as possible? - if (this.statelessFetch == null) - return rows; - - return Math.min(this.statelessFetch, rows); + return Math.min(RexLiteral.intValue(fetch), rows); } @Override public QueryPlan implement(Implementor implementor) { QueryPlan plan = implementor.visitInput(0, (PhoenixRel) getInput()); + int fetchValue = RexLiteral.intValue(fetch); if (plan.getLimit() == null) { - return plan.limit(statelessFetch); + return plan.limit(fetchValue); } return new ClientScanPlan(plan.getContext(), plan.getStatement(), implementor.getTableRef(), RowProjector.EMPTY_PROJECTOR, - statelessFetch, null, OrderBy.EMPTY_ORDER_BY, plan); + fetchValue, null, OrderBy.EMPTY_ORDER_BY, plan); } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/500e85cc/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java index 4d7445a..bef650d 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java @@ -59,15 +59,9 @@ public class PhoenixTableScan extends TableScan implements PhoenixRel { public final RexNode filter; private final ScanRanges scanRanges; - - /** - * This will not make a difference in implement(), but rather give a more accurate - * estimate of the row count. - */ - public final Integer statelessFetch; - + public static PhoenixTableScan create(RelOptCluster cluster, final RelOptTable table, - RexNode filter, Integer statelessFetch) { + RexNode filter) { final RelTraitSet traits = cluster.traitSetOf(PhoenixRel.SERVER_CONVENTION) .replaceIfs(RelCollationTraitDef.INSTANCE, @@ -79,13 +73,12 @@ public class PhoenixTableScan extends TableScan implements PhoenixRel { return ImmutableList.of(); } }); - return new PhoenixTableScan(cluster, traits, table, filter, statelessFetch); + return new PhoenixTableScan(cluster, traits, table, filter); } - private PhoenixTableScan(RelOptCluster cluster, RelTraitSet traits, RelOptTable table, RexNode filter, Integer statelessFetch) { + private PhoenixTableScan(RelOptCluster cluster, RelTraitSet traits, RelOptTable table, RexNode filter) { super(cluster, traits, table); this.filter = filter; - this.statelessFetch = statelessFetch; ScanRanges scanRanges = null; if (filter != null) { @@ -136,8 +129,7 @@ public class PhoenixTableScan extends TableScan implements PhoenixRel { @Override public RelWriter explainTerms(RelWriter pw) { return super.explainTerms(pw) - .itemIf("filter", filter, filter != null) - .itemIf("statelessFetch", statelessFetch, statelessFetch != null); + .itemIf("filter", filter, filter != null); } @Override @@ -168,11 +160,9 @@ public class PhoenixTableScan extends TableScan implements PhoenixRel { double rows = super.getRows(); if (filter != null && !filter.isAlwaysTrue()) { rows = rows * RelMetadataQuery.getSelectivity(this, filter); - } - if (statelessFetch == null) - return rows; + } - return Math.min(statelessFetch, rows); + return rows; } @Override http://git-wip-us.apache.org/repos/asf/phoenix/blob/500e85cc/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixAddScanLimitRule.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixAddScanLimitRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixAddScanLimitRule.java deleted file mode 100644 index 9abf3dc..0000000 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixAddScanLimitRule.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.apache.phoenix.calcite.rules; - -import java.util.Collections; - -import org.apache.calcite.plan.RelOptRule; -import org.apache.calcite.plan.RelOptRuleCall; -import org.apache.calcite.plan.RelOptRuleOperand; -import org.apache.calcite.rel.RelNode; -import org.apache.phoenix.calcite.rel.PhoenixLimit; -import org.apache.phoenix.calcite.rel.PhoenixRel; -import org.apache.phoenix.calcite.rel.PhoenixServerProject; -import org.apache.phoenix.calcite.rel.PhoenixTableScan; - -import com.google.common.base.Predicate; - -public class PhoenixAddScanLimitRule extends RelOptRule { - - /** Predicate that returns true if a limit's fetch is stateless. */ - private static final Predicate<PhoenixLimit> IS_FETCH_STATELESS = - new Predicate<PhoenixLimit>() { - @Override - public boolean apply(PhoenixLimit phoenixLimit) { - return phoenixLimit.statelessFetch != null; - } - }; - - /** Predicate that returns true if a table scan has no stateless fetch. */ - private static final Predicate<PhoenixTableScan> NO_STATELESSFETCH = - new Predicate<PhoenixTableScan>() { - @Override - public boolean apply(PhoenixTableScan phoenixTableScan) { - return phoenixTableScan.statelessFetch == null; - } - }; - - public static final PhoenixAddScanLimitRule LIMIT_SCAN = - new PhoenixAddScanLimitRule( - "PhoenixAddScanLimitRule:limit_scan", - operand(PhoenixTableScan.class, null, NO_STATELESSFETCH, any())); - - public static final PhoenixAddScanLimitRule LIMIT_SERVERPROJECT_SCAN = - new PhoenixAddScanLimitRule( - "PhoenixAddScanLimitRule:limit_serverproject_scan", - operand(PhoenixServerProject.class, - operand(PhoenixTableScan.class, null, NO_STATELESSFETCH, any()))); - - private PhoenixAddScanLimitRule(String description, RelOptRuleOperand input) { - super( - operand(PhoenixLimit.class, null, IS_FETCH_STATELESS, input), description); - } - - @Override - public void onMatch(RelOptRuleCall call) { - int relCount = call.getRelList().size(); - PhoenixLimit limit = call.rel(0); - PhoenixServerProject project = null; - if (relCount > 2) { - project = call.rel(1); - } - PhoenixTableScan scan = call.rel(relCount - 1); - assert limit.statelessFetch != null : "predicate should have ensured fetch is stateless"; - assert scan.statelessFetch == null : "predicate should have ensured table scan has no stateless fetch"; - PhoenixTableScan newScan = PhoenixTableScan.create( - scan.getCluster(), scan.getTable(), scan.filter, limit.statelessFetch); - PhoenixRel newInput = project == null ? - newScan - : project.copy(project.getTraitSet(), newScan, - project.getProjects(), project.getRowType()); - call.transformTo(limit.copy(limit.getTraitSet(), - Collections.<RelNode>singletonList(newInput))); - } - -} http://git-wip-us.apache.org/repos/asf/phoenix/blob/500e85cc/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java index bab9036..6ad544d 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixConverterRules.java @@ -983,10 +983,6 @@ public class PhoenixConverterRules { if (sort.offset != null) return false; - if (sort.fetch != null - && CalciteUtils.evaluateStatelessExpression(sort.fetch) == null) - return false; - return true; } http://git-wip-us.apache.org/repos/asf/phoenix/blob/500e85cc/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixFilterScanMergeRule.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixFilterScanMergeRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixFilterScanMergeRule.java index f846d45..ba303a6 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixFilterScanMergeRule.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rules/PhoenixFilterScanMergeRule.java @@ -40,7 +40,7 @@ public class PhoenixFilterScanMergeRule extends RelOptRule { Filter filter = call.rel(0); PhoenixTableScan scan = call.rel(1); assert scan.filter == null : "predicate should have ensured no filter"; - call.transformTo(PhoenixTableScan.create(scan.getCluster(), - scan.getTable(), filter.getCondition(), scan.statelessFetch)); + call.transformTo(PhoenixTableScan.create( + scan.getCluster(), scan.getTable(), filter.getCondition())); } }
