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/d5bc5ce2 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/d5bc5ce2 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/d5bc5ce2 Branch: refs/heads/4.x-cdh5.11.2 Commit: d5bc5ce2777486e00efa6237fa965843035ee324 Parents: 515f10d Author: maryannxue <maryann....@gmail.com> Authored: Mon Nov 6 02:37:55 2017 +0000 Committer: Pedro Boado <pbo...@apache.org> Committed: Wed Jan 31 22:24:48 2018 +0000 ---------------------------------------------------------------------- .../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/d5bc5ce2/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/d5bc5ce2/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 887e2d2..439a79b 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 @@ -110,6 +110,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, @@ -489,7 +495,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)), @@ -505,15 +511,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/d5bc5ce2/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 af2254b..287f9e0 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 @@ -307,7 +307,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); @@ -369,7 +369,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(); @@ -422,7 +422,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/d5bc5ce2/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 5e7b996..7bf8259 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;