Repository: phoenix Updated Branches: refs/heads/calcite b01bdd172 -> f6ff11710
Remove PhoenixProjectScanMergeRule; Inject projection to server side plans whenever possible; Make aggregate+join merged server plans as in original Phoenix planning Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/f6ff1171 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/f6ff1171 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/f6ff1171 Branch: refs/heads/calcite Commit: f6ff117104d78c09ab691535c9cc0c40003e8636 Parents: b01bdd1 Author: maryannxue <wei....@intel.com> Authored: Thu Apr 2 23:56:26 2015 -0400 Committer: maryannxue <wei....@intel.com> Committed: Thu Apr 2 23:56:26 2015 -0400 ---------------------------------------------------------------------- .../org/apache/phoenix/calcite/CalciteTest.java | 41 ++++++++++++++----- .../apache/phoenix/calcite/CalciteUtils.java | 10 +++++ .../phoenix/calcite/PhoenixAggregate.java | 36 ++++++++-------- .../apache/phoenix/calcite/PhoenixFilter.java | 5 +++ .../calcite/PhoenixFilterScanMergeRule.java | 2 +- .../org/apache/phoenix/calcite/PhoenixJoin.java | 13 ++++-- .../apache/phoenix/calcite/PhoenixProject.java | 43 ++++++++++++++------ .../calcite/PhoenixProjectScanMergeRule.java | 37 ----------------- .../org/apache/phoenix/calcite/PhoenixRel.java | 23 ++++++++++- .../calcite/PhoenixRelImplementorImpl.java | 5 ++- .../org/apache/phoenix/calcite/PhoenixSort.java | 5 +++ .../apache/phoenix/calcite/PhoenixTable.java | 2 +- .../phoenix/calcite/PhoenixTableScan.java | 41 ++++++------------- .../calcite/PhoenixToEnumerableConverter.java | 26 +++++++++--- .../apache/phoenix/calcite/PhoenixUnion.java | 5 +++ .../apache/phoenix/calcite/PhoenixValues.java | 5 +++ .../GroupedAggregateRegionObserver.java | 3 +- .../coprocessor/HashJoinRegionScanner.java | 8 +++- .../phoenix/coprocessor/ScanRegionObserver.java | 3 +- .../UngroupedAggregateRegionObserver.java | 3 +- .../phoenix/execute/TupleProjectionPlan.java | 12 ------ .../apache/phoenix/execute/TupleProjector.java | 17 +++++++- .../java/org/apache/phoenix/util/TestUtil.java | 4 +- 23 files changed, 210 insertions(+), 139 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java index 333315c..f9e00ce 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteTest.java @@ -201,7 +201,8 @@ public class CalciteTest extends BaseClientManagedTimeIT { @Test public void testProject() throws Exception { start().sql("select entity_id, a_string, organization_id from aTable where a_string = 'a'") .explainIs("PhoenixToEnumerableConverter\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]], filter=[=($2, 'a')], project=[[$1, $2, $0]])\n") + " PhoenixProject(ENTITY_ID=[$1], A_STRING=[$2], ORGANIZATION_ID=[$0])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]], filter=[=($2, 'a')])\n") .resultIs(new Object[][] { {"00A123122312312", "a", "00D300000000XHP"}, {"00A223122312312", "a", "00D300000000XHP"}, @@ -215,8 +216,10 @@ public class CalciteTest extends BaseClientManagedTimeIT { .explainIs("PhoenixToEnumerableConverter\n" + " PhoenixProject(ENTITY_ID=[$4], A_STRING=[$2], ORGANIZATION_ID=[$3])\n" + " PhoenixJoin(condition=[AND(=($4, $1), =($3, $0))], joinType=[inner])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]], project=[[$0, $1, $2]])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]], filter=[=($2, 'a')], project=[[$0, $1, $2]])\n") + " PhoenixProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n" + + " PhoenixProject(ORGANIZATION_ID=[$0], ENTITY_ID=[$1], A_STRING=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]], filter=[=($2, 'a')])\n") .resultIs(new Object[][] { {"00A123122312312", "a", "00D300000000XHP"}, {"00A223122312312", "a", "00D300000000XHP"}, @@ -228,8 +231,10 @@ public class CalciteTest extends BaseClientManagedTimeIT { .explainIs("PhoenixToEnumerableConverter\n" + " PhoenixProject(item_id=[$0], NAME=[$1], supplier_id=[$3], NAME0=[$4])\n" + " PhoenixJoin(condition=[=($2, $3)], joinType=[inner])\n" + - " PhoenixTableScan(table=[[phoenix, ITEMTABLE]], project=[[$0, $1, $5]])\n" + - " PhoenixTableScan(table=[[phoenix, SUPPLIERTABLE]], project=[[$0, $1]])\n") + " PhoenixProject(item_id=[$0], NAME=[$1], supplier_id=[$5])\n" + + " PhoenixTableScan(table=[[phoenix, ITEMTABLE]])\n" + + " PhoenixProject(supplier_id=[$0], NAME=[$1])\n" + + " PhoenixTableScan(table=[[phoenix, SUPPLIERTABLE]])\n") .resultIs(new Object[][] { {"0000000001", "T1", "0000000001", "S1"}, {"0000000002", "T2", "0000000001", "S1"}, @@ -238,6 +243,17 @@ public class CalciteTest extends BaseClientManagedTimeIT { {"0000000005", "T5", "0000000005", "S5"}, {"0000000006", "T6", "0000000006", "S6"}}) .close(); + + start().sql("SELECT * FROM " + JOIN_ITEM_TABLE_FULL_NAME + " item JOIN " + JOIN_SUPPLIER_TABLE_FULL_NAME + " supp ON item.\"supplier_id\" = supp.\"supplier_id\" AND supp.name = 'S5'") + .explainIs("PhoenixToEnumerableConverter\n" + + " PhoenixProject(item_id=[$0], NAME=[$1], PRICE=[$2], DISCOUNT1=[$3], DISCOUNT2=[$4], supplier_id=[$5], DESCRIPTION=[$6], supplier_id0=[$7], NAME0=[$8], PHONE=[$9], ADDRESS=[$10], LOC_ID=[$11])\n" + + " PhoenixJoin(condition=[=($5, $7)], joinType=[inner])\n" + + " PhoenixTableScan(table=[[phoenix, ITEMTABLE]])\n" + + " PhoenixProject(supplier_id=[$0], NAME=[$1], PHONE=[$2], ADDRESS=[$3], LOC_ID=[$4], $f5=[CAST($1):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL])\n" + + " PhoenixTableScan(table=[[phoenix, SUPPLIERTABLE]], filter=[=(CAST($1):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, 'S5')])\n") + .resultIs(new Object[][] { + {"0000000005", "T5", 500, 8, 15, "0000000005", "Item T5", "0000000005", "S5", "888-888-5555", "505 YYY Street", "10005"}}) + .close(); } @Test public void testMultiJoin() throws Exception { @@ -282,7 +298,8 @@ public class CalciteTest extends BaseClientManagedTimeIT { start().sql("select a_string, count(entity_id) from atable group by a_string") .explainIs("PhoenixToEnumerableConverter\n" + " PhoenixAggregate(group=[{0}], EXPR$1=[COUNT()])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]], project=[[$2]])\n") + " PhoenixProject(A_STRING=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") .resultIs(new Object[][] { {"a", 4L}, {"b", 4L}, @@ -293,7 +310,8 @@ public class CalciteTest extends BaseClientManagedTimeIT { .explainIs("PhoenixToEnumerableConverter\n" + " PhoenixProject(EXPR$0=[$1], A_STRING=[$0])\n" + " PhoenixAggregate(group=[{0}], EXPR$0=[COUNT()])\n" + - " PhoenixTableScan(table=[[phoenix, ATABLE]], project=[[$2]])\n") + " PhoenixProject(A_STRING=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ATABLE]])\n") .resultIs(new Object[][] { {4L, "a"}, {4L, "b"}, @@ -305,8 +323,10 @@ public class CalciteTest extends BaseClientManagedTimeIT { " PhoenixAggregate(group=[{0}], EXPR$1=[COUNT()])\n" + " PhoenixProject(NAME=[$1])\n" + " PhoenixJoin(condition=[=($0, $2)], joinType=[inner])\n" + - " PhoenixTableScan(table=[[phoenix, SUPPLIERTABLE]], project=[[$0, $1]])\n" + - " PhoenixTableScan(table=[[phoenix, ITEMTABLE]], project=[[$5]])\n") + " PhoenixProject(supplier_id=[$0], NAME=[$1])\n" + + " PhoenixTableScan(table=[[phoenix, SUPPLIERTABLE]])\n" + + " PhoenixProject(supplier_id=[$5])\n" + + " PhoenixTableScan(table=[[phoenix, ITEMTABLE]])\n") .resultIs(new Object[][] { {"S1", 2L}, {"S2", 2L}, @@ -326,7 +346,8 @@ public class CalciteTest extends BaseClientManagedTimeIT { " PhoenixJoin(condition=[=($6, $2)], joinType=[inner])\n" + " PhoenixTableScan(table=[[phoenix, ORDERTABLE]])\n" + " PhoenixAggregate(group=[{0}])\n" + - " PhoenixTableScan(table=[[phoenix, ORDERTABLE]], project=[[$2]])\n") + " PhoenixProject(item_id=[$2])\n" + + " PhoenixTableScan(table=[[phoenix, ORDERTABLE]])\n") .close(); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/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 4962bb5..8146d6d 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 @@ -89,6 +89,16 @@ public class CalciteUtils { } }); + EXPRESSION_MAP.put(SqlKind.CAST, new ExpressionFactory() { + + @Override + public Expression newExpression(RexNode node, + Implementor implementor) { + // TODO replace with real implementation + return toExpression(((RexCall) node).getOperands().get(0), implementor); + } + + }); } private static final Map<String, FunctionFactory> FUNCTION_MAP = Maps http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixAggregate.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixAggregate.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixAggregate.java index 0c620c8..c3d4982 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixAggregate.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixAggregate.java @@ -14,8 +14,6 @@ import org.apache.calcite.rel.core.Aggregate; import org.apache.calcite.rel.core.AggregateCall; import org.apache.calcite.util.ImmutableBitSet; import org.apache.hadoop.hbase.client.Scan; -import org.apache.phoenix.compile.ColumnProjector; -import org.apache.phoenix.compile.ExpressionProjector; import org.apache.phoenix.compile.FromCompiler; import org.apache.phoenix.compile.QueryPlan; import org.apache.phoenix.compile.RowProjector; @@ -41,6 +39,7 @@ import org.apache.phoenix.parse.SelectStatement; import org.apache.phoenix.schema.PTable; import org.apache.phoenix.schema.RowKeyValueAccessor; import org.apache.phoenix.schema.TableRef; + import com.google.common.collect.Lists; /** @@ -48,7 +47,6 @@ import com.google.common.collect.Lists; * relational expression in Phoenix. */ public class PhoenixAggregate extends Aggregate implements PhoenixRel { - private static double SERVER_AGGREGATE_FACTOR = 0.2; public PhoenixAggregate(RelOptCluster cluster, RelTraitSet traits, RelNode child, boolean indicator, ImmutableBitSet groupSet, List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) throws InvalidRelException { super(cluster, traits, child, indicator, groupSet, groupSets, aggCalls); @@ -70,8 +68,8 @@ public class PhoenixAggregate extends Aggregate implements PhoenixRel { @Override public RelOptCost computeSelfCost(RelOptPlanner planner) { RelOptCost cost = super.computeSelfCost(planner); - if (isServerAggregate()) { - cost = cost.multiplyBy(SERVER_AGGREGATE_FACTOR); + if (isServerAggregateDoable()) { + cost = cost.multiplyBy(SERVER_FACTOR); } return cost.multiplyBy(PHOENIX_FACTOR); } @@ -147,9 +145,9 @@ public class PhoenixAggregate extends Aggregate implements PhoenixRel { SelectStatement select = SelectStatement.SELECT_STAR; QueryPlan aggPlan; if (basePlan == null) { - aggPlan = new ClientAggregatePlan(context, select, tableRef, implementor.createRowProjector(), null, null, OrderBy.EMPTY_ORDER_BY, groupBy, null, plan); + aggPlan = new ClientAggregatePlan(context, select, tableRef, RowProjector.EMPTY_PROJECTOR, null, null, OrderBy.EMPTY_ORDER_BY, groupBy, null, plan); } else { - aggPlan = new AggregatePlan(context, select, basePlan.getTableRef(), implementor.createRowProjector(), null, OrderBy.EMPTY_ORDER_BY, null, groupBy, null); + aggPlan = new AggregatePlan(context, select, basePlan.getTableRef(), RowProjector.EMPTY_PROJECTOR, null, OrderBy.EMPTY_ORDER_BY, null, groupBy, null); if (plan instanceof HashJoinPlan) { HashJoinPlan hashJoinPlan = (HashJoinPlan) plan; aggPlan = HashJoinPlan.create(select, aggPlan, hashJoinPlan.getJoinInfo(), hashJoinPlan.getSubPlans()); @@ -169,15 +167,7 @@ public class PhoenixAggregate extends Aggregate implements PhoenixRel { TupleProjector tupleProjector = implementor.project(exprs); PTable projectedTable = implementor.createProjectedTable(); implementor.setTableRef(new TableRef(projectedTable)); - return new TupleProjectionPlan(aggPlan, tupleProjector, null, implementor.createRowProjector()); - } - - public boolean isServerAggregate() { - RelNode rel = getInput(); - if (rel instanceof RelSubset) { - rel = ((RelSubset) rel).getBest(); - } - return (rel instanceof PhoenixTableScan) || (rel instanceof PhoenixJoin && ((PhoenixJoin) rel).isHashJoinDoable()); + return new TupleProjectionPlan(aggPlan, tupleProjector, null); } private static int getMinNullableIndex(List<SingleAggregateFunction> aggFuncs, boolean isUngroupedAggregation) { @@ -192,4 +182,18 @@ public class PhoenixAggregate extends Aggregate implements PhoenixRel { return minNullableIndex; } + private boolean isServerAggregateDoable() { + RelNode rel = getInput(); + if (rel instanceof RelSubset) { + rel = ((RelSubset) rel).getBest(); + } + + return rel instanceof PhoenixRel && ((PhoenixRel) rel).getPlanType() != PlanType.CLIENT_SERVER; + } + + @Override + public PlanType getPlanType() { + return PlanType.CLIENT_SERVER; + } + } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixFilter.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixFilter.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixFilter.java index 8163682..8925ead 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixFilter.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixFilter.java @@ -41,4 +41,9 @@ public class PhoenixFilter extends Filter implements PhoenixRel { return new ClientScanPlan(plan.getContext(), plan.getStatement(), plan.getTableRef(), plan.getProjector(), null, expr, OrderBy.EMPTY_ORDER_BY, plan); } + + @Override + public PlanType getPlanType() { + return PlanType.CLIENT_SERVER; + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixFilterScanMergeRule.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixFilterScanMergeRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixFilterScanMergeRule.java index d35abad..808fa99 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixFilterScanMergeRule.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixFilterScanMergeRule.java @@ -31,6 +31,6 @@ public class PhoenixFilterScanMergeRule extends RelOptRule { assert scan.filter == null : "predicate should have ensured no filter"; call.transformTo(new PhoenixTableScan(scan.getCluster(), scan.getTraitSet(), scan.getTable(), - filter.getCondition(), scan.projects, scan.getRowType())); + filter.getCondition())); } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixJoin.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixJoin.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixJoin.java index a1384a6..c316b5d 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixJoin.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixJoin.java @@ -78,7 +78,7 @@ public class PhoenixJoin extends Join implements PhoenixRel { JoinInfo joinInfo = JoinInfo.of(left, right, getCondition()); List<Expression> leftExprs = Lists.<Expression> newArrayList(); List<Expression> rightExprs = Lists.<Expression> newArrayList(); - implementor.pushContext(new ImplementorContext(implementor.getCurrentContext().isRetainPKColumns())); + implementor.pushContext(new ImplementorContext(implementor.getCurrentContext().isRetainPKColumns(), true)); QueryPlan leftPlan = implementor.visitInput(0, left); PTable leftTable = implementor.getTableRef().getTable(); for (Iterator<Integer> iter = joinInfo.leftKeys.iterator(); iter.hasNext();) { @@ -89,7 +89,7 @@ public class PhoenixJoin extends Join implements PhoenixRel { leftExprs.add(LiteralExpression.newConstant(0)); } implementor.popContext(); - implementor.pushContext(new ImplementorContext(false)); + implementor.pushContext(new ImplementorContext(false, true)); QueryPlan rightPlan = implementor.visitInput(1, right); PTable rightTable = implementor.getTableRef().getTable(); for (Iterator<Integer> iter = joinInfo.rightKeys.iterator(); iter.hasNext();) { @@ -123,13 +123,13 @@ public class PhoenixJoin extends Join implements PhoenixRel { return HashJoinPlan.create(SelectStatement.SELECT_STAR, leftPlan, hashJoinInfo, new HashJoinPlan.HashSubPlan[] {new HashJoinPlan.HashSubPlan(0, rightPlan, rightExprs, false, null, null)}); } - public boolean isHashJoinDoable() { + private boolean isHashJoinDoable() { // TODO check memory limit RelNode rel = getLeft(); if (rel instanceof RelSubset) { rel = ((RelSubset) rel).getBest(); } - return (rel instanceof PhoenixTableScan) && getJoinType() != JoinRelType.RIGHT; + return (rel instanceof PhoenixRel && ((PhoenixRel) rel).getPlanType() == PlanType.SERVER_ONLY_FLAT) && getJoinType() != JoinRelType.RIGHT; } private JoinType convertJoinType(JoinRelType type) { @@ -152,4 +152,9 @@ public class PhoenixJoin extends Join implements PhoenixRel { return ret; } + + @Override + public PlanType getPlanType() { + return PlanType.SERVER_ONLY_COMPLEX; + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixProject.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixProject.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixProject.java index 6b82f42..4f08968 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixProject.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixProject.java @@ -1,31 +1,23 @@ package org.apache.phoenix.calcite; -import java.sql.SQLException; -import java.util.Collections; import java.util.List; import org.apache.calcite.plan.RelOptCluster; import org.apache.calcite.plan.RelOptCost; import org.apache.calcite.plan.RelOptPlanner; import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.plan.volcano.RelSubset; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.Project; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rex.RexNode; -import org.apache.hadoop.hbase.HConstants; import org.apache.phoenix.compile.QueryPlan; -import org.apache.phoenix.coprocessor.MetaDataProtocol; +import org.apache.phoenix.compile.RowProjector; +import org.apache.phoenix.execute.ScanPlan; import org.apache.phoenix.execute.TupleProjectionPlan; import org.apache.phoenix.execute.TupleProjector; import org.apache.phoenix.expression.Expression; -import org.apache.phoenix.schema.KeyValueSchema; -import org.apache.phoenix.schema.PColumn; -import org.apache.phoenix.schema.PColumnImpl; -import org.apache.phoenix.schema.PName; -import org.apache.phoenix.schema.PNameFactory; import org.apache.phoenix.schema.PTable; -import org.apache.phoenix.schema.PTableImpl; -import org.apache.phoenix.schema.PTableType; import org.apache.phoenix.schema.TableRef; import com.google.common.collect.Lists; @@ -46,13 +38,19 @@ public class PhoenixProject extends Project implements PhoenixRel { } public RelOptCost computeSelfCost(RelOptPlanner planner) { - return super.computeSelfCost(planner).multiplyBy(PHOENIX_FACTOR); + RelOptCost cost = super.computeSelfCost(planner); + if (getPlanType() != PlanType.CLIENT_SERVER) { + cost = cost.multiplyBy(SERVER_FACTOR); + } + return cost.multiplyBy(PHOENIX_FACTOR); } @Override public QueryPlan implement(Implementor implementor) { assert getConvention() == getInput().getConvention(); + implementor.pushContext(new ImplementorContext(implementor.getCurrentContext().isRetainPKColumns(), false)); QueryPlan plan = implementor.visitInput(0, (PhoenixRel) getInput()); + implementor.popContext(); List<Expression> exprs = Lists.newArrayList(); for (RexNode project : getProjects()) { @@ -61,6 +59,25 @@ public class PhoenixProject extends Project implements PhoenixRel { TupleProjector tupleProjector = implementor.project(exprs); PTable projectedTable = implementor.createProjectedTable(); implementor.setTableRef(new TableRef(projectedTable)); - return new TupleProjectionPlan(plan, tupleProjector, null, implementor.createRowProjector()); + + boolean isScan = plan instanceof ScanPlan; + if (getPlanType() == PlanType.CLIENT_SERVER + || TupleProjector.hasProjector(plan.getContext().getScan(), isScan)) + return new TupleProjectionPlan(plan, tupleProjector, null); + + TupleProjector.serializeProjectorIntoScan(plan.getContext().getScan(), tupleProjector, isScan); + return plan; + } + + @Override + public PlanType getPlanType() { + RelNode rel = getInput(); + if (rel instanceof RelSubset) { + rel = ((RelSubset) rel).getBest(); + } + // TODO this is based on the assumption that there is no two Project + // in a row and Project can be pushed down to the input node if it is + // a server plan. + return !(rel instanceof PhoenixRel) ? PlanType.CLIENT_SERVER : ((PhoenixRel) rel).getPlanType(); } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixProjectScanMergeRule.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixProjectScanMergeRule.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixProjectScanMergeRule.java deleted file mode 100644 index d28159d..0000000 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixProjectScanMergeRule.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.apache.phoenix.calcite; - -import org.apache.calcite.plan.RelOptRule; -import org.apache.calcite.plan.RelOptRuleCall; -import org.apache.calcite.rel.core.Project; - -import com.google.common.base.Predicate; - -public class PhoenixProjectScanMergeRule extends RelOptRule { - - /** Predicate that returns true if a table scan has no project. */ - private static final Predicate<PhoenixTableScan> NO_PROJECT = - new Predicate<PhoenixTableScan>() { - @Override - public boolean apply(PhoenixTableScan phoenixTableScan) { - return phoenixTableScan.projects == null; - } - }; - - public static final PhoenixProjectScanMergeRule INSTANCE = new PhoenixProjectScanMergeRule(); - - private PhoenixProjectScanMergeRule() { - super( - operand(Project.class, - operand(PhoenixTableScan.class, null, NO_PROJECT, any()))); - } - - @Override - public void onMatch(RelOptRuleCall call) { - Project project = call.rel(0); - PhoenixTableScan scan = call.rel(1); - assert scan.projects == null : "predicate should have ensured no project"; - call.transformTo(new PhoenixTableScan(scan.getCluster(), - scan.getTraitSet(), scan.getTable(), - scan.filter, project.getProjects(), project.getRowType())); - } -} http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixRel.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixRel.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixRel.java index d89cdab..f5943da 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixRel.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixRel.java @@ -29,18 +29,39 @@ public interface PhoenixRel extends RelNode { */ double PHOENIX_FACTOR = 0.5; + /** Relative cost of server plan versus client plan. + * + * <p>Multiply by the value (which is less than unity), and you will get a cheaper cost. + * Server is cheaper. + */ + double SERVER_FACTOR = 0.2; + + enum PlanType { + SERVER_ONLY_FLAT, + SERVER_ONLY_COMPLEX, + CLIENT_SERVER, + } + + PlanType getPlanType(); + QueryPlan implement(Implementor implementor); class ImplementorContext { private boolean retainPKColumns; + private boolean forceProject; - public ImplementorContext(boolean retainPKColumns) { + public ImplementorContext(boolean retainPKColumns, boolean forceProject) { this.retainPKColumns = retainPKColumns; + this.forceProject = forceProject; } public boolean isRetainPKColumns() { return this.retainPKColumns; } + + public boolean forceProject() { + return this.forceProject; + } } /** Holds context for an traversal over a tree of relational expressions http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixRelImplementorImpl.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixRelImplementorImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixRelImplementorImpl.java index 67e1fd0..ec0277a 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixRelImplementorImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixRelImplementorImpl.java @@ -16,6 +16,7 @@ import org.apache.phoenix.coprocessor.MetaDataProtocol; import org.apache.phoenix.execute.TupleProjector; import org.apache.phoenix.expression.ColumnExpression; import org.apache.phoenix.expression.Expression; +import org.apache.phoenix.parse.ParseNodeFactory; import org.apache.phoenix.schema.ColumnRef; import org.apache.phoenix.schema.KeyValueSchema; import org.apache.phoenix.schema.PColumn; @@ -35,7 +36,7 @@ class PhoenixRelImplementorImpl implements PhoenixRel.Implementor { public PhoenixRelImplementorImpl() { this.contextStack = new Stack<ImplementorContext>(); - pushContext(new ImplementorContext(true)); + pushContext(new ImplementorContext(true, false)); } @Override @@ -105,8 +106,8 @@ class PhoenixRelImplementorImpl implements PhoenixRel.Implementor { KeyValueSchema.KeyValueSchemaBuilder builder = new KeyValueSchema.KeyValueSchemaBuilder(0); List<PColumn> columns = Lists.<PColumn>newArrayList(); for (int i = 0; i < exprs.size(); i++) { + String name = ParseNodeFactory.createTempAlias(); Expression expr = exprs.get(i); - String name = expr.toString(); builder.addField(expr); columns.add(new PColumnImpl(PNameFactory.newName(name), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), expr.getDataType(), expr.getMaxLength(), expr.getScale(), expr.isNullable(), http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSort.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSort.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSort.java index 4eccf5a..6d11231 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSort.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixSort.java @@ -29,4 +29,9 @@ public class PhoenixSort extends Sort implements PhoenixRel { implementor.visitInput(0, (PhoenixRel) getInput()); throw new UnsupportedOperationException(); } + + @Override + public PlanType getPlanType() { + return PlanType.CLIENT_SERVER; + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/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 b2fba0a..e18a57a 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 @@ -70,7 +70,7 @@ public class PhoenixTable extends AbstractTable implements TranslatableTable { @Override public RelNode toRel(RelOptTable.ToRelContext context, RelOptTable relOptTable) { final RelOptCluster cluster = context.getCluster(); - return new PhoenixTableScan(cluster, cluster.traitSetOf(PhoenixRel.CONVENTION), relOptTable, null, null, null); + return new PhoenixTableScan(cluster, cluster.traitSetOf(PhoenixRel.CONVENTION), relOptTable, null); } @Override http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTableScan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTableScan.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTableScan.java index e21d28f..8b437bc 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTableScan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixTableScan.java @@ -13,7 +13,6 @@ import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.RelWriter; import org.apache.calcite.rel.core.TableScan; import org.apache.calcite.rel.metadata.RelMetadataQuery; -import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rex.RexNode; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.client.Scan; @@ -46,15 +45,10 @@ import com.google.common.collect.Lists; */ public class PhoenixTableScan extends TableScan implements PhoenixRel { public final RexNode filter; - public final List<RexNode> projects; - protected PhoenixTableScan(RelOptCluster cluster, RelTraitSet traits, RelOptTable table, RexNode filter, List<RexNode> projects, RelDataType rowType) { + protected PhoenixTableScan(RelOptCluster cluster, RelTraitSet traits, RelOptTable table, RexNode filter) { super(cluster, traits, table); this.filter = filter; - this.projects = projects; - if (rowType != null) { - this.rowType = rowType; - } } @Override @@ -70,14 +64,12 @@ public class PhoenixTableScan extends TableScan implements PhoenixRel { planner.addRule(rule); } planner.addRule(PhoenixFilterScanMergeRule.INSTANCE); - planner.addRule(PhoenixProjectScanMergeRule.INSTANCE); } @Override public RelWriter explainTerms(RelWriter pw) { return super.explainTerms(pw) - .itemIf("filter", filter, filter != null) - .itemIf("project", projects, projects != null); + .itemIf("filter", filter, filter != null); } @Override @@ -87,10 +79,6 @@ public class PhoenixTableScan extends TableScan implements PhoenixRel { final Double selectivity = RelMetadataQuery.getSelectivity(this, filter); cost = cost.multiplyBy(selectivity); } - if (projects != null) { - final double projectFieldRatio = ((double) projects.size()) / getRowType().getFieldCount(); - cost = cost.multiplyBy(projectFieldRatio); - } return cost; } @@ -117,24 +105,16 @@ public class PhoenixTableScan extends TableScan implements PhoenixRel { WhereCompiler.setScanFilter(context, select, filterExpr, true, false); } projectAllColumnFamilies(context.getScan(), phoenixTable.getTable()); - TupleProjector tupleProjector; - if (projects == null) { - tupleProjector = createTupleProjector(implementor, phoenixTable.getTable()); - } else { - List<Expression> exprs = Lists.newArrayList(); - for (RexNode project : this.projects) { - exprs.add(CalciteUtils.toExpression(project, implementor)); - } - tupleProjector = implementor.project(exprs); + if (implementor.getCurrentContext().forceProject()) { + TupleProjector tupleProjector = createTupleProjector(implementor, phoenixTable.getTable()); + TupleProjector.serializeProjectorIntoScan(context.getScan(), tupleProjector); + PTable projectedTable = implementor.createProjectedTable(); + implementor.setTableRef(new TableRef(projectedTable)); } - TupleProjector.serializeProjectorIntoScan(context.getScan(), tupleProjector); - PTable projectedTable = implementor.createProjectedTable(); - implementor.setTableRef(new TableRef(projectedTable)); - RowProjector rowProjector = implementor.createRowProjector(); Integer limit = null; OrderBy orderBy = OrderBy.EMPTY_ORDER_BY; ParallelIteratorFactory iteratorFactory = null; - return new ScanPlan(context, select, tableRef, rowProjector, limit, orderBy, iteratorFactory, true); + return new ScanPlan(context, select, tableRef, RowProjector.EMPTY_PROJECTOR, limit, orderBy, iteratorFactory, true); } catch (SQLException e) { throw new RuntimeException(e); } @@ -161,4 +141,9 @@ public class PhoenixTableScan extends TableScan implements PhoenixRel { scan.addFamily(family.getName().getBytes()); } } + + @Override + public PlanType getPlanType() { + return PlanType.SERVER_ONLY_FLAT; + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixToEnumerableConverter.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixToEnumerableConverter.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixToEnumerableConverter.java index d1750e3..537e748 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixToEnumerableConverter.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixToEnumerableConverter.java @@ -1,5 +1,6 @@ package org.apache.phoenix.calcite; +import java.sql.SQLException; import java.util.List; import org.apache.calcite.adapter.enumerable.EnumerableRel; @@ -20,12 +21,11 @@ import org.apache.calcite.plan.RelTraitSet; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.convert.ConverterImpl; import org.apache.calcite.rel.type.RelDataType; -import org.apache.calcite.tools.FrameworkConfig; -import org.apache.calcite.tools.Frameworks; -import org.apache.calcite.tools.Planner; -import org.apache.calcite.tools.Program; -import org.apache.calcite.tools.Programs; +import org.apache.phoenix.compile.ExplainPlan; import org.apache.phoenix.compile.QueryPlan; +import org.apache.phoenix.compile.RowProjector; +import org.apache.phoenix.execute.DelegateQueryPlan; +import org.apache.phoenix.iterate.ResultIterator; /** * Scan of a Phoenix table. @@ -73,7 +73,21 @@ public class PhoenixToEnumerableConverter extends ConverterImpl implements Enume static QueryPlan makePlan(PhoenixRel rel) { final PhoenixRel.Implementor phoenixImplementor = new PhoenixRelImplementorImpl(); - return phoenixImplementor.visitInput(0, rel); + final QueryPlan plan = phoenixImplementor.visitInput(0, rel); + return new DelegateQueryPlan(plan) { + @Override + public ResultIterator iterator() throws SQLException { + return delegate.iterator(); + } + @Override + public ExplainPlan getExplainPlan() throws SQLException { + return delegate.getExplainPlan(); + } + @Override + public RowProjector getProjector() { + return phoenixImplementor.createRowProjector(); + } + }; } static Expression stash(EnumerableRelImplementor implementor, Object o, Class clazz) { http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixUnion.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixUnion.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixUnion.java index cc76334..c824246 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixUnion.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixUnion.java @@ -34,4 +34,9 @@ public class PhoenixUnion extends Union implements PhoenixRel { } throw new UnsupportedOperationException(); } + + @Override + public PlanType getPlanType() { + return PlanType.CLIENT_SERVER; + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixValues.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixValues.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixValues.java index 6e01abb..92bc676 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixValues.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/PhoenixValues.java @@ -34,4 +34,9 @@ public class PhoenixValues extends Values implements PhoenixRel { public QueryPlan implement(Implementor implementor) { throw new UnsupportedOperationException(); } + + @Override + public PlanType getPlanType() { + return PlanType.SERVER_ONLY_FLAT; + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java index 1f1ba36..180c895 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java @@ -147,8 +147,9 @@ public class GroupedAggregateRegionObserver extends BaseScannerRegionObserver { } if (j != null) { + TupleProjector postJoinProjector = TupleProjector.deserializeProjectorFromScan(scan, false); innerScanner = - new HashJoinRegionScanner(innerScanner, p, j, ScanUtil.getTenantId(scan), + new HashJoinRegionScanner(innerScanner, p, postJoinProjector, j, ScanUtil.getTenantId(scan), c.getEnvironment()); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java index cdfc771..f969ce9 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java @@ -60,11 +60,13 @@ public class HashJoinRegionScanner implements RegionScanner { private List<Tuple>[] tempTuples; private ValueBitSet tempDestBitSet; private ValueBitSet[] tempSrcBitSet; + private final TupleProjector postJoinProjector; @SuppressWarnings("unchecked") - public HashJoinRegionScanner(RegionScanner scanner, TupleProjector projector, HashJoinInfo joinInfo, ImmutableBytesWritable tenantId, RegionCoprocessorEnvironment env) throws IOException { + public HashJoinRegionScanner(RegionScanner scanner, TupleProjector projector, TupleProjector postJoinProjector, HashJoinInfo joinInfo, ImmutableBytesWritable tenantId, RegionCoprocessorEnvironment env) throws IOException { this.scanner = scanner; this.projector = projector; + this.postJoinProjector = postJoinProjector; this.joinInfo = joinInfo; this.resultQueue = new LinkedList<Tuple>(); this.hasMore = true; @@ -224,6 +226,10 @@ public class HashJoinRegionScanner implements RegionScanner { return false; Tuple tuple = resultQueue.poll(); + // post-join projection + if (postJoinProjector != null) { + tuple = postJoinProjector.projectResults(tuple); + } for (int i = 0; i < tuple.size(); i++) { results.add(tuple.getValue(i)); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java index ddde407..9b1ea0d 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java @@ -209,7 +209,8 @@ public class ScanRegionObserver extends BaseScannerRegionObserver { final ImmutableBytesWritable tenantId = ScanUtil.getTenantId(scan); if (j != null) { - innerScanner = new HashJoinRegionScanner(innerScanner, p, j, tenantId, c.getEnvironment()); + TupleProjector postJoinProjector = TupleProjector.deserializeProjectorFromScan(scan, false); + innerScanner = new HashJoinRegionScanner(innerScanner, p, postJoinProjector, j, tenantId, c.getEnvironment()); } final OrderedResultIterator iterator = deserializeFromScan(scan,innerScanner); http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java index 72a0a64..0cf2320 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java @@ -229,7 +229,8 @@ public class UngroupedAggregateRegionObserver extends BaseScannerRegionObserver{ } if (j != null) { - theScanner = new HashJoinRegionScanner(theScanner, p, j, ScanUtil.getTenantId(scan), c.getEnvironment()); + TupleProjector postJoinProjector = TupleProjector.deserializeProjectorFromScan(scan, false); + theScanner = new HashJoinRegionScanner(theScanner, p, postJoinProjector, j, ScanUtil.getTenantId(scan), c.getEnvironment()); } int batchSize = 0; http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjectionPlan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjectionPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjectionPlan.java index b2eba2c..c9cbd15 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjectionPlan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjectionPlan.java @@ -22,7 +22,6 @@ import java.util.List; import org.apache.phoenix.compile.ExplainPlan; import org.apache.phoenix.compile.QueryPlan; -import org.apache.phoenix.compile.RowProjector; import org.apache.phoenix.expression.Expression; import org.apache.phoenix.iterate.DelegateResultIterator; import org.apache.phoenix.iterate.FilterResultIterator; @@ -34,23 +33,12 @@ import com.google.common.collect.Lists; public class TupleProjectionPlan extends DelegateQueryPlan { private final TupleProjector tupleProjector; private final Expression postFilter; - private final RowProjector rowProjector; public TupleProjectionPlan(QueryPlan plan, TupleProjector tupleProjector, Expression postFilter) { - this(plan, tupleProjector, postFilter, plan.getProjector()); - } - - public TupleProjectionPlan(QueryPlan plan, TupleProjector tupleProjector, Expression postFilter, RowProjector rowProjector) { super(plan); if (tupleProjector == null) throw new IllegalArgumentException("tupleProjector is null"); this.tupleProjector = tupleProjector; this.postFilter = postFilter; - this.rowProjector = rowProjector; - } - - @Override - public RowProjector getProjector() { - return this.rowProjector; } @Override http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjector.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjector.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjector.java index a4728e9..7ec147f 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjector.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjector.java @@ -54,6 +54,7 @@ public class TupleProjector { public static final byte[] VALUE_COLUMN_QUALIFIER = new byte[0]; private static final String SCAN_PROJECTOR = "scanProjector"; + private static final String POST_JOIN_PROJECTOR = "postJoinProjector"; private final KeyValueSchema schema; private final Expression[] expressions; @@ -100,7 +101,15 @@ public class TupleProjector { this.valueSet = bitSet; } + public static boolean hasProjector(Scan scan, boolean scanProjector) { + return scan.getAttribute(scanProjector ? SCAN_PROJECTOR : POST_JOIN_PROJECTOR) != null; + } + public static void serializeProjectorIntoScan(Scan scan, TupleProjector projector) { + serializeProjectorIntoScan(scan, projector, true); + } + + public static void serializeProjectorIntoScan(Scan scan, TupleProjector projector, boolean scanProjector) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { DataOutputStream output = new DataOutputStream(stream); @@ -111,7 +120,7 @@ public class TupleProjector { WritableUtils.writeVInt(output, ExpressionType.valueOf(projector.expressions[i]).ordinal()); projector.expressions[i].write(output); } - scan.setAttribute(SCAN_PROJECTOR, stream.toByteArray()); + scan.setAttribute(scanProjector ? SCAN_PROJECTOR : POST_JOIN_PROJECTOR, stream.toByteArray()); } catch (IOException e) { throw new RuntimeException(e); } finally { @@ -125,7 +134,11 @@ public class TupleProjector { } public static TupleProjector deserializeProjectorFromScan(Scan scan) { - byte[] proj = scan.getAttribute(SCAN_PROJECTOR); + return deserializeProjectorFromScan(scan, true); + } + + public static TupleProjector deserializeProjectorFromScan(Scan scan, boolean scanProjector) { + byte[] proj = scan.getAttribute(scanProjector ? SCAN_PROJECTOR : POST_JOIN_PROJECTOR); if (proj == null) { return null; } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f6ff1171/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java b/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java index 2b7a62b..802f803 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java @@ -199,8 +199,8 @@ public class TestUtil { public static final String JOIN_ITEM_TABLE_FULL_NAME = JOIN_ITEM_TABLE; //'"' + JOIN_SCHEMA + "\".\"" + JOIN_ITEM_TABLE + '"'; public static final String JOIN_SUPPLIER_TABLE_FULL_NAME = JOIN_SUPPLIER_TABLE; //'"' + JOIN_SCHEMA + "\".\"" + JOIN_SUPPLIER_TABLE + '"'; public static final String JOIN_COITEM_TABLE_FULL_NAME = '"' + JOIN_SCHEMA + "\".\"" + JOIN_COITEM_TABLE + '"'; - public static final String JOIN_ORDER_TABLE_DISPLAY_NAME = JOIN_SCHEMA + "." + JOIN_ORDER_TABLE; - public static final String JOIN_CUSTOMER_TABLE_DISPLAY_NAME = JOIN_SCHEMA + "." + JOIN_CUSTOMER_TABLE; + public static final String JOIN_ORDER_TABLE_DISPLAY_NAME = JOIN_ORDER_TABLE.toUpperCase(); + public static final String JOIN_CUSTOMER_TABLE_DISPLAY_NAME = JOIN_CUSTOMER_TABLE.toUpperCase(); public static final String JOIN_ITEM_TABLE_DISPLAY_NAME = JOIN_ITEM_TABLE.toUpperCase(); public static final String JOIN_SUPPLIER_TABLE_DISPLAY_NAME = JOIN_SUPPLIER_TABLE.toUpperCase(); public static final String JOIN_COITEM_TABLE_DISPLAY_NAME = JOIN_SCHEMA + "." + JOIN_COITEM_TABLE;