PHOENIX-3050 Handle DESC columns in child/parent join optimization
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/977699af Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/977699af Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/977699af Branch: refs/heads/4.x-HBase-0.98 Commit: 977699afe0d66f1434b8bc1c5a751767e563d6ce Parents: 92b57c7 Author: maryannxue <maryann....@gmail.com> Authored: Wed Dec 6 12:07:16 2017 -0800 Committer: maryannxue <maryann....@gmail.com> Committed: Tue Mar 13 17:17:16 2018 -0700 ---------------------------------------------------------------------- .../phoenix/end2end/join/HashJoinMoreIT.java | 5 +++++ .../org/apache/phoenix/compile/JoinCompiler.java | 19 +++++++++++++------ .../apache/phoenix/compile/QueryCompiler.java | 6 +++--- .../apache/phoenix/compile/WhereOptimizer.java | 5 ----- 4 files changed, 21 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/977699af/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinMoreIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinMoreIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinMoreIT.java index 37ffd02..f09f1d3 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinMoreIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinMoreIT.java @@ -895,6 +895,11 @@ public class HashJoinMoreIT extends ParallelStatsDisabledIT { + "FROM ( SELECT ACCOUNT_ID, BUCKET_ID, OBJECT_ID, MAX(OBJECT_VERSION) AS MAXVER " + " FROM test2961 GROUP BY ACCOUNT_ID, BUCKET_ID, OBJECT_ID) AS X " + " INNER JOIN test2961 AS OBJ ON X.ACCOUNT_ID = OBJ.ACCOUNT_ID AND X.BUCKET_ID = OBJ.BUCKET_ID AND X.OBJECT_ID = OBJ.OBJECT_ID AND X.MAXVER = OBJ.OBJECT_VERSION"; + rs = conn.createStatement().executeQuery("explain " + q); + String plan = QueryUtil.getExplainPlan(rs); + String dynamicFilter = "DYNAMIC SERVER FILTER BY (OBJ.ACCOUNT_ID, OBJ.BUCKET_ID, OBJ.OBJECT_ID, OBJ.OBJECT_VERSION) IN ((X.ACCOUNT_ID, X.BUCKET_ID, X.OBJECT_ID, X.MAXVER))"; + assertTrue("Expected '" + dynamicFilter + "' to be used for the query, but got:\n" + plan, + plan.contains(dynamicFilter)); rs = conn.createStatement().executeQuery(q); assertTrue(rs.next()); assertEquals("2222", rs.getString(4)); http://git-wip-us.apache.org/repos/asf/phoenix/blob/977699af/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java index f9d8711..f3c4c24 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java @@ -108,6 +108,12 @@ import com.google.common.collect.Sets; public class JoinCompiler { + public enum Strategy { + HASH_BUILD_LEFT, + HASH_BUILD_RIGHT, + SORT_MERGE, + } + public enum ColumnRefType { JOINLOCAL, GENERAL, @@ -487,7 +493,7 @@ public class JoinCompiler { return dependencies; } - public Pair<List<Expression>, List<Expression>> compileJoinConditions(StatementContext lhsCtx, StatementContext rhsCtx, boolean sortExpressions) throws SQLException { + public Pair<List<Expression>, List<Expression>> compileJoinConditions(StatementContext lhsCtx, StatementContext rhsCtx, Strategy strategy) throws SQLException { if (onConditions.isEmpty()) { return new Pair<List<Expression>, List<Expression>>( Collections.<Expression> singletonList(LiteralExpression.newConstant(1)), @@ -503,15 +509,16 @@ public class JoinCompiler { rhsCompiler.reset(); Expression right = condition.getRHS().accept(rhsCompiler); PDataType toType = getCommonType(left.getDataType(), right.getDataType()); - if (left.getDataType() != toType || left.getSortOrder() == SortOrder.DESC) { - left = CoerceExpression.create(left, toType, SortOrder.ASC, left.getMaxLength()); + SortOrder toSortOrder = strategy == Strategy.SORT_MERGE ? SortOrder.ASC : (strategy == Strategy.HASH_BUILD_LEFT ? right.getSortOrder() : left.getSortOrder()); + if (left.getDataType() != toType || left.getSortOrder() != toSortOrder) { + left = CoerceExpression.create(left, toType, toSortOrder, left.getMaxLength()); } - if (right.getDataType() != toType || right.getSortOrder() == SortOrder.DESC) { - right = CoerceExpression.create(right, toType, SortOrder.ASC, right.getMaxLength()); + if (right.getDataType() != toType || right.getSortOrder() != toSortOrder) { + right = CoerceExpression.create(right, toType, toSortOrder, right.getMaxLength()); } compiled.add(new Pair<Expression, Expression>(left, right)); } - if (sortExpressions) { + if (strategy != Strategy.SORT_MERGE) { Collections.sort(compiled, new Comparator<Pair<Expression, Expression>>() { @Override public int compare(Pair<Expression, Expression> o1, Pair<Expression, Expression> o2) { http://git-wip-us.apache.org/repos/asf/phoenix/blob/977699af/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 9443110..c5bc44c 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 @@ -305,7 +305,7 @@ public class QueryCompiler { JoinSpec joinSpec = joinSpecs.get(i); context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), query.getUdfParseNodes())); joinIds[i] = new ImmutableBytesPtr(emptyByteArray); // place-holder - Pair<List<Expression>, List<Expression>> joinConditions = joinSpec.compileJoinConditions(context, subContexts[i], true); + Pair<List<Expression>, List<Expression>> joinConditions = joinSpec.compileJoinConditions(context, subContexts[i], JoinCompiler.Strategy.HASH_BUILD_RIGHT); joinExpressions[i] = joinConditions.getFirst(); List<Expression> hashExpressions = joinConditions.getSecond(); Pair<Expression, Expression> keyRangeExpressions = new Pair<Expression, Expression>(null, null); @@ -367,7 +367,7 @@ public class QueryCompiler { context.setCurrentTable(rhsTableRef); context.setResolver(FromCompiler.getResolverForProjectedTable(rhsProjTable, context.getConnection(), rhs.getUdfParseNodes())); ImmutableBytesPtr[] joinIds = new ImmutableBytesPtr[] {new ImmutableBytesPtr(emptyByteArray)}; - Pair<List<Expression>, List<Expression>> joinConditions = lastJoinSpec.compileJoinConditions(lhsCtx, context, true); + Pair<List<Expression>, List<Expression>> joinConditions = lastJoinSpec.compileJoinConditions(lhsCtx, context, JoinCompiler.Strategy.HASH_BUILD_LEFT); List<Expression> joinExpressions = joinConditions.getSecond(); List<Expression> hashExpressions = joinConditions.getFirst(); boolean needsMerge = lhsJoin.hasPostReference(); @@ -420,7 +420,7 @@ public class QueryCompiler { QueryPlan rhsPlan = compileJoinQuery(rhsCtx, binds, rhsJoin, true, true, rhsOrderBy); PTable rhsProjTable = rhsCtx.getResolver().getTables().get(0).getTable(); - Pair<List<Expression>, List<Expression>> joinConditions = lastJoinSpec.compileJoinConditions(type == JoinType.Right ? rhsCtx : lhsCtx, type == JoinType.Right ? lhsCtx : rhsCtx, false); + Pair<List<Expression>, List<Expression>> joinConditions = lastJoinSpec.compileJoinConditions(type == JoinType.Right ? rhsCtx : lhsCtx, type == JoinType.Right ? lhsCtx : rhsCtx, JoinCompiler.Strategy.SORT_MERGE); List<Expression> lhsKeyExpressions = type == JoinType.Right ? joinConditions.getSecond() : joinConditions.getFirst(); List<Expression> rhsKeyExpressions = type == JoinType.Right ? joinConditions.getFirst() : joinConditions.getSecond(); http://git-wip-us.apache.org/repos/asf/phoenix/blob/977699af/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java index ccf073a..87f00e4 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java @@ -326,11 +326,6 @@ public class WhereOptimizer { PTable table = context.getCurrentTable().getTable(); for (int i = 0; i < expressions.size(); i++) { Expression expression = expressions.get(i); - // TODO this is a temporary fix for PHOENIX-3029. - if (expression instanceof CoerceExpression - && expression.getSortOrder() != expression.getChildren().get(0).getSortOrder()) { - continue; - } KeyExpressionVisitor visitor = new KeyExpressionVisitor(context, table); KeyExpressionVisitor.KeySlots keySlots = expression.accept(visitor); int minPkPos = Integer.MAX_VALUE;