Repository: phoenix
Updated Branches:
  refs/heads/4.x-HBase-0.98 1f4a5400b -> 7eac78e75


PHOENIX-2274 Sort-merge join could not optimize out the sort on the right table


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/ea91e634
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/ea91e634
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/ea91e634

Branch: refs/heads/4.x-HBase-0.98
Commit: ea91e634400a58654ba98d8b696c169272ac8308
Parents: 6cd7936
Author: maryannxue <wei....@intel.com>
Authored: Mon Sep 21 09:26:07 2015 -0400
Committer: maryannxue <wei....@intel.com>
Committed: Mon Sep 21 09:26:07 2015 -0400

----------------------------------------------------------------------
 .../apache/phoenix/end2end/SortMergeJoinIT.java | 35 ++++++++++++++++++--
 .../end2end/SubqueryUsingSortMergeJoinIT.java   |  2 --
 .../apache/phoenix/compile/OrderByCompiler.java | 10 +++---
 .../apache/phoenix/compile/QueryCompiler.java   | 11 +++---
 4 files changed, 45 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/ea91e634/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinIT.java
index 8b65ab3..9b85d8a 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SortMergeJoinIT.java
@@ -113,8 +113,6 @@ public class SortMergeJoinIT extends BaseHBaseManagedTimeIT 
{
                 "AND\n" +
                 "    SORT-MERGE-JOIN (INNER) TABLES\n" +
                 "        CLIENT PARALLEL 1-WAY FULL SCAN OVER " + 
JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
-                "            SERVER SORTED BY [\"I.item_id\"]\n" +
-                "        CLIENT MERGE SORT\n" +
                 "    AND (SKIP MERGE)\n" +
                 "        CLIENT PARALLEL 1-WAY FULL SCAN OVER " + 
JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
                 "            SERVER FILTER BY QUANTITY < 5000\n" +
@@ -129,6 +127,12 @@ public class SortMergeJoinIT extends 
BaseHBaseManagedTimeIT {
                 "        SERVER SORTED BY [\"O.item_id\"]\n" +
                 "    CLIENT MERGE SORT\n" +
                 "CLIENT 4 ROW LIMIT",
+                
+                "SORT-MERGE-JOIN (INNER) TABLES\n" +
+                "    CLIENT PARALLEL 1-WAY FULL SCAN OVER Join.ItemTable\n" +
+                "AND\n" +
+                "    CLIENT PARALLEL 1-WAY FULL SCAN OVER Join.ItemTable\n" +
+                "        SERVER FILTER BY FIRST KEY ONLY"
                 }});
         testCases.add(new String[][] {
                 {
@@ -163,6 +167,18 @@ public class SortMergeJoinIT extends 
BaseHBaseManagedTimeIT {
                 "        SERVER SORTED BY [\"O.item_id\"]\n" +
                 "    CLIENT MERGE SORT\n" +
                 "CLIENT 4 ROW LIMIT",
+                
+                "SORT-MERGE-JOIN (INNER) TABLES\n" +
+                "    CLIENT PARALLEL 1-WAY FULL SCAN OVER Join.idx_item\n" +
+                "        SERVER FILTER BY FIRST KEY ONLY\n" +
+                "        SERVER SORTED BY [\"I1.:item_id\"]\n" +
+                "    CLIENT MERGE SORT\n" +
+                "AND\n" +
+                "    CLIENT PARALLEL 1-WAY FULL SCAN OVER Join.idx_item\n" +
+                "        SERVER FILTER BY FIRST KEY ONLY\n" +
+                "        SERVER SORTED BY [\"I2.:item_id\"]\n" +
+                "    CLIENT MERGE SORT\n" +
+                "CLIENT SORTED BY [\"I1.:item_id\"]"
                 }});
         testCases.add(new String[][] {
                 {
@@ -197,6 +213,18 @@ public class SortMergeJoinIT extends 
BaseHBaseManagedTimeIT {
                 "        SERVER SORTED BY [\"O.item_id\"]\n" +
                 "    CLIENT MERGE SORT\n" +
                 "CLIENT 4 ROW LIMIT",
+                
+                "SORT-MERGE-JOIN (INNER) TABLES\n" +
+                "    CLIENT PARALLEL 1-WAY RANGE SCAN OVER 
_LOCAL_IDX_Join.ItemTable [-32768]\n" +
+                "        SERVER FILTER BY FIRST KEY ONLY\n" +
+                "        SERVER SORTED BY [\"I1.:item_id\"]\n" +
+                "    CLIENT MERGE SORT\n" +
+                "AND\n" +
+                "    CLIENT PARALLEL 1-WAY RANGE SCAN OVER 
_LOCAL_IDX_Join.ItemTable [-32768]\n" +
+                "        SERVER FILTER BY FIRST KEY ONLY\n" +
+                "        SERVER SORTED BY [\"I2.:item_id\"]\n" +
+                "    CLIENT MERGE SORT\n" +
+                "CLIENT SORTED BY [\"I1.:item_id\"]"
                 }});
         return testCases;
     }
@@ -1674,6 +1702,9 @@ public class SortMergeJoinIT extends 
BaseHBaseManagedTimeIT {
             
             assertFalse(rs.next());
 
+            rs = conn.createStatement().executeQuery("EXPLAIN " + query1);
+            assertEquals(plans[2], QueryUtil.getExplainPlan(rs));
+
             statement = conn.prepareStatement(query2);
             rs = statement.executeQuery();
             assertTrue (rs.next());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ea91e634/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
index cb9f4b1..f3b6bce 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SubqueryUsingSortMergeJoinIT.java
@@ -114,8 +114,6 @@ public class SubqueryUsingSortMergeJoinIT extends 
BaseHBaseManagedTimeIT {
                 "        CLIENT MERGE SORT\n" +
                 "    AND\n" +
                 "        CLIENT PARALLEL 1-WAY FULL SCAN OVER " + 
JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
-                "            SERVER SORTED BY [\"S.supplier_id\"]\n" +
-                "        CLIENT MERGE SORT\n" +
                 "    CLIENT SORTED BY [\"I.item_id\"]\n" +
                 "AND (SKIP MERGE)\n" +
                 "    CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + 
JOIN_ORDER_TABLE_DISPLAY_NAME + " ['000000000000001'] - [*]\n" +

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ea91e634/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
index 7275b64..0ae31f0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java
@@ -27,6 +27,7 @@ import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
 import org.apache.phoenix.compile.OrderPreservingTracker.Ordering;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.exception.SQLExceptionInfo;
+import org.apache.phoenix.execute.TupleProjector;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.OrderByExpression;
 import org.apache.phoenix.parse.LiteralParseNode;
@@ -82,7 +83,8 @@ public class OrderByCompiler {
     public static OrderBy compile(StatementContext context,
                                   SelectStatement statement,
                                   GroupBy groupBy, Integer limit, 
-                                  RowProjector projector,
+                                  RowProjector rowProjector,
+                                  TupleProjector tupleProjector,
                                   boolean isInRowKeyOrder) throws SQLException 
{
         List<OrderByNode> orderByNodes = statement.getOrderBy();
         if (orderByNodes.isEmpty()) {
@@ -91,19 +93,19 @@ public class OrderByCompiler {
         ExpressionCompiler compiler = new ExpressionCompiler(context, groupBy);
         // accumulate columns in ORDER BY
         OrderPreservingTracker tracker = 
-                new OrderPreservingTracker(context, groupBy, Ordering.ORDERED, 
orderByNodes.size());
+                new OrderPreservingTracker(context, groupBy, Ordering.ORDERED, 
orderByNodes.size(), tupleProjector);
         LinkedHashSet<OrderByExpression> orderByExpressions = 
Sets.newLinkedHashSetWithExpectedSize(orderByNodes.size());
         for (OrderByNode node : orderByNodes) {
             ParseNode parseNode = node.getNode();
             Expression expression = null;
             if (parseNode instanceof LiteralParseNode && 
((LiteralParseNode)parseNode).getType() == PInteger.INSTANCE){
                 Integer index = 
(Integer)((LiteralParseNode)parseNode).getValue();
-                int size = projector.getColumnProjectors().size();
+                int size = rowProjector.getColumnProjectors().size();
                 if (index > size || index <= 0 ) {
                     throw new 
SQLExceptionInfo.Builder(SQLExceptionCode.PARAM_INDEX_OUT_OF_BOUND)
                     .build().buildException();
                 }
-                expression = 
projector.getColumnProjector(index-1).getExpression();
+                expression = 
rowProjector.getColumnProjector(index-1).getExpression();
             } else {
                 expression = node.getNode().accept(compiler);
                 // Detect mix of aggregate and non aggregates (i.e. ORDER BY 
txns, SUM(txns)

http://git-wip-us.apache.org/repos/asf/phoenix/blob/ea91e634/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
index 4191da9..f14d808 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
@@ -242,10 +242,11 @@ public class QueryCompiler {
             if (!table.isSubselect()) {
                 context.setCurrentTable(table.getTableRef());
                 PTable projectedTable = 
table.createProjectedTable(!projectPKColumns, context);
-                TupleProjector.serializeProjectorIntoScan(context.getScan(), 
new TupleProjector(projectedTable));
+                TupleProjector projector = new TupleProjector(projectedTable);
+                TupleProjector.serializeProjectorIntoScan(context.getScan(), 
projector);
                 
context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, 
context.getConnection(), subquery.getUdfParseNodes()));
                 table.projectColumns(context.getScan());
-                return compileSingleQuery(context, subquery, binds, 
asSubquery, !asSubquery);
+                return compileSingleFlatQuery(context, subquery, binds, 
asSubquery, !asSubquery, null, projectPKColumns ? projector : null, true);
             }
             QueryPlan plan = compileSubquery(subquery, false);
             PTable projectedTable = 
table.createProjectedTable(plan.getProjector());
@@ -314,7 +315,7 @@ public class QueryCompiler {
                 subPlans[i] = new HashSubPlan(i, joinPlan, optimized ? null : 
hashExpressions, joinSpec.isSingleValueOnly(), keyRangeLhsExpression, 
keyRangeRhsExpression);
             }
             TupleProjector.serializeProjectorIntoScan(context.getScan(), 
tupleProjector);
-            QueryPlan plan = compileSingleQuery(context, query, binds, 
asSubquery, !asSubquery && joinTable.isAllLeftJoin());
+            QueryPlan plan = compileSingleFlatQuery(context, query, binds, 
asSubquery, !asSubquery && joinTable.isAllLeftJoin(), null, 
!table.isSubselect() && projectPKColumns ? tupleProjector : null, true);
             Expression postJoinFilterExpression = 
joinTable.compilePostFilterExpression(context, table);
             Integer limit = null;
             if (!query.isAggregate() && !query.isDistinct() && 
query.getOrderBy().isEmpty()) {
@@ -368,7 +369,7 @@ public class QueryCompiler {
             PTable projectedTable = needsMerge ? 
JoinCompiler.joinProjectedTables(rhsProjTable, lhsTable, type == JoinType.Right 
? JoinType.Left : type) : rhsProjTable;
             TupleProjector.serializeProjectorIntoScan(context.getScan(), 
tupleProjector);
             
context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, 
context.getConnection(), rhs.getUdfParseNodes()));
-            QueryPlan rhsPlan = compileSingleQuery(context, rhs, binds, 
asSubquery, !asSubquery && type == JoinType.Right);
+            QueryPlan rhsPlan = compileSingleFlatQuery(context, rhs, binds, 
asSubquery, !asSubquery && type == JoinType.Right, null, 
!rhsTable.isSubselect() && projectPKColumns ? tupleProjector : null, true);
             Expression postJoinFilterExpression = 
joinTable.compilePostFilterExpression(context, rhsTable);
             Integer limit = null;
             if (!rhs.isAggregate() && !rhs.isDistinct() && 
rhs.getOrderBy().isEmpty()) {
@@ -536,7 +537,7 @@ public class QueryCompiler {
         Expression where = WhereCompiler.compile(context, select, viewWhere, 
subqueries);
         context.setResolver(resolver); // recover resolver
         RowProjector projector = ProjectionCompiler.compile(context, select, 
groupBy, asSubquery ? Collections.<PDatum>emptyList() : targetColumns);
-        OrderBy orderBy = OrderByCompiler.compile(context, select, groupBy, 
limit, projector, isInRowKeyOrder); 
+        OrderBy orderBy = OrderByCompiler.compile(context, select, groupBy, 
limit, projector, groupBy == GroupBy.EMPTY_GROUP_BY ? innerPlanTupleProjector : 
null, isInRowKeyOrder); 
         // Final step is to build the query plan
         if (!asSubquery) {
             int maxRows = statement.getMaxRows();

Reply via email to