This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch PHOENIX-7876-feature in repository https://gitbox.apache.org/repos/asf/phoenix.git
commit ce469c890a210dfaeedaa51d09d1a95c62ff5a5d Author: Andrew Purtell <[email protected]> AuthorDate: Sat Jun 6 09:48:45 2026 -0700 [WIP] Render hash-join strategy as trailing line comment in EXPLAIN Move the JoinCompiler.Strategy and the SKIP MERGE / DELAYED EVALUATION decorators out of inline parentheticals and into a single trailing SQL comment on each join operator line. HashJoinPlan and SortMergeJoinPlan gain a JoinCompiler.Strategy field + getter QueryCompiler threads the chosen strategy through HashJoinPlan.create(). The comment is emitted in the rendered text only. --- .../org/apache/phoenix/compile/QueryCompiler.java | 5 +- .../org/apache/phoenix/execute/HashJoinPlan.java | 85 ++++++++++++++++------ .../apache/phoenix/execute/SortMergeJoinPlan.java | 13 +++- .../phoenix/end2end/QueryWithTableSampleIT.java | 2 +- .../apache/phoenix/end2end/index/IndexUsageIT.java | 4 +- .../end2end/join/HashJoinGlobalIndexIT.java | 25 +++---- .../phoenix/end2end/join/HashJoinLocalIndexIT.java | 24 +++--- .../phoenix/end2end/join/HashJoinMoreIT.java | 8 +- .../phoenix/end2end/join/HashJoinNoIndexIT.java | 23 +++--- .../phoenix/query/explain/ExplainPlanTest.java | 6 +- 10 files changed, 124 insertions(+), 71 deletions(-) diff --git a/phoenix-core-client/src/main/java/org/apache/phoenix/compile/QueryCompiler.java b/phoenix-core-client/src/main/java/org/apache/phoenix/compile/QueryCompiler.java index f4d78ce0e6..1d8e9cb7a7 100644 --- a/phoenix-core-client/src/main/java/org/apache/phoenix/compile/QueryCompiler.java +++ b/phoenix-core-client/src/main/java/org/apache/phoenix/compile/QueryCompiler.java @@ -486,7 +486,7 @@ public class QueryCompiler { joinTypes, starJoinVector, tables, fieldPositions, postJoinFilterExpression, QueryUtil.getOffsetLimit(limit, offset)); return HashJoinPlan.create(joinTable.getOriginalJoinSelectStatement(), plan, joinInfo, - hashPlans); + hashPlans, strategy); } case HASH_BUILD_LEFT: { JoinSpec lastJoinSpec = joinSpecs.get(joinSpecs.size() - 1); @@ -562,7 +562,8 @@ public class QueryCompiler { hashExpressions); return HashJoinPlan.create(joinTable.getOriginalJoinSelectStatement(), rhsPlan, joinInfo, new HashSubPlan[] { new HashSubPlan(0, lhsPlan, hashExpressions, false, - usePersistentCache, keyRangeExpressions.getFirst(), keyRangeExpressions.getSecond()) }); + usePersistentCache, keyRangeExpressions.getFirst(), keyRangeExpressions.getSecond()) }, + strategy); } case SORT_MERGE: { JoinTable lhsJoin = joinTable.createSubJoinTable(statement.getConnection()); diff --git a/phoenix-core-client/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java b/phoenix-core-client/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java index aa18e0e6cc..5b3aa8e30d 100644 --- a/phoenix-core-client/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java +++ b/phoenix-core-client/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java @@ -43,6 +43,7 @@ import org.apache.phoenix.compile.ExplainPlan; import org.apache.phoenix.compile.ExplainPlanAttributes; import org.apache.phoenix.compile.ExplainPlanAttributes.ExplainPlanAttributesBuilder; import org.apache.phoenix.compile.FromCompiler; +import org.apache.phoenix.compile.JoinCompiler; import org.apache.phoenix.compile.QueryPlan; import org.apache.phoenix.compile.RowProjector; import org.apache.phoenix.compile.ScanRanges; @@ -100,6 +101,7 @@ public class HashJoinPlan extends DelegateQueryPlan { private final SelectStatement statement; private final HashJoinInfo joinInfo; private final SubPlan[] subPlans; + private final JoinCompiler.Strategy strategy; private final boolean recompileWhereClause; private final Set<TableRef> tableRefs; private final int maxServerCacheTimeToLive; @@ -116,8 +118,14 @@ public class HashJoinPlan extends DelegateQueryPlan { public static HashJoinPlan create(SelectStatement statement, QueryPlan plan, HashJoinInfo joinInfo, SubPlan[] subPlans) throws SQLException { - if (!(plan instanceof HashJoinPlan)) return new HashJoinPlan(statement, plan, joinInfo, - subPlans, joinInfo == null, Collections.<ImmutableBytesPtr, ServerCache> emptyMap()); + return create(statement, plan, joinInfo, subPlans, null); + } + + public static HashJoinPlan create(SelectStatement statement, QueryPlan plan, + HashJoinInfo joinInfo, SubPlan[] subPlans, JoinCompiler.Strategy strategy) throws SQLException { + if (!(plan instanceof HashJoinPlan)) + return new HashJoinPlan(statement, plan, joinInfo, subPlans, joinInfo == null, + Collections.<ImmutableBytesPtr, ServerCache> emptyMap(), strategy); HashJoinPlan hashJoinPlan = (HashJoinPlan) plan; assert (hashJoinPlan.joinInfo == null && hashJoinPlan.delegate instanceof BaseQueryPlan); @@ -130,17 +138,19 @@ public class HashJoinPlan extends DelegateQueryPlan { mergedSubPlans[i++] = subPlan; } return new HashJoinPlan(statement, hashJoinPlan.delegate, joinInfo, mergedSubPlans, true, - hashJoinPlan.dependencies); + hashJoinPlan.dependencies, strategy); } private HashJoinPlan(SelectStatement statement, QueryPlan plan, HashJoinInfo joinInfo, SubPlan[] subPlans, boolean recompileWhereClause, - Map<ImmutableBytesPtr, ServerCache> dependencies) throws SQLException { + Map<ImmutableBytesPtr, ServerCache> dependencies, JoinCompiler.Strategy strategy) + throws SQLException { super(plan); this.dependencies.putAll(dependencies); this.statement = statement; this.joinInfo = joinInfo; this.subPlans = subPlans; + this.strategy = strategy; this.recompileWhereClause = recompileWhereClause; this.tableRefs = Sets.newHashSetWithExpectedSize(subPlans.length + plan.getSourceRefs().size()); this.tableRefs.addAll(plan.getSourceRefs()); @@ -386,6 +396,32 @@ public class HashJoinPlan extends DelegateQueryPlan { return subPlans; } + /** + * The {@link JoinCompiler.Strategy} chosen for this hash join (build left or build right), or + * {@code null}. + */ + public JoinCompiler.Strategy getStrategy() { + return strategy; + } + + /** + * Renders the trailing SQL comment that discloses the chosen hash-join strategy and the optional + * build-side decorators, e.g. {@code " /* HASH BUILD RIGHT, SKIP MERGE *}{@code /"}. The build + * side is derived from {@code strategy} (defaulting to {@code RIGHT} when unknown). + */ + static String hashStrategyComment(JoinCompiler.Strategy strategy, boolean skipMerge, + boolean delayedEvaluation) { + String side = strategy == JoinCompiler.Strategy.HASH_BUILD_LEFT ? "LEFT" : "RIGHT"; + StringBuilder comment = new StringBuilder(" /* HASH BUILD ").append(side); + if (skipMerge) { + comment.append(", SKIP MERGE"); + } + if (delayedEvaluation) { + comment.append(", DELAYED EVALUATION"); + } + return comment.append(" */").toString(); + } + @Override public <T> T accept(QueryPlanVisitor<T> visitor) { return visitor.visit(this); @@ -683,18 +719,35 @@ public class HashJoinPlan extends DelegateQueryPlan { } } + /** + * Builds the bare join operator line without leading indentation and without the trailing + * strategy comment, e.g. {@code "PARALLEL INNER-JOIN TABLE 1"} or + * {@code "SKIP-SCAN-JOIN TABLE 0"}. + */ + private String getBareJoinHeader(HashJoinPlan parent) { + if (hashExpressions != null) { + return "PARALLEL " + parent.joinInfo.getJoinTypes()[index].toString().toUpperCase() + + "-JOIN TABLE " + index; + } else { + return "SKIP-SCAN-JOIN TABLE " + index; + } + } + @Override public List<String> getPreSteps(HashJoinPlan parent) throws SQLException { List<String> steps = Lists.newArrayList(); - boolean earlyEvaluation = parent.joinInfo.earlyEvaluation()[index]; - boolean skipMerge = parent.joinInfo.getSchemas()[index].getFieldCount() == 0; + // The chosen JoinCompiler.Strategy and the optional SKIP MERGE / DELAYED EVALUATION + // decorators + // are rendered as a single trailing SQL comment on the join operator line. + String comment; if (hashExpressions != null) { - steps.add(" PARALLEL " + parent.joinInfo.getJoinTypes()[index].toString().toUpperCase() - + "-JOIN TABLE " + index + (earlyEvaluation ? "" : "(DELAYED EVALUATION)") - + (skipMerge ? " (SKIP MERGE)" : "")); + boolean delayedEvaluation = !parent.joinInfo.earlyEvaluation()[index]; + boolean skipMerge = parent.joinInfo.getSchemas()[index].getFieldCount() == 0; + comment = hashStrategyComment(parent.getStrategy(), skipMerge, delayedEvaluation); } else { - steps.add(" SKIP-SCAN-JOIN TABLE " + index); + comment = hashStrategyComment(parent.getStrategy(), false, false); } + steps.add(" " + getBareJoinHeader(parent) + comment); for (String step : plan.getExplainPlan().getPlanSteps()) { steps.add(" " + step); } @@ -703,17 +756,7 @@ public class HashJoinPlan extends DelegateQueryPlan { @Override public ExplainPlanAttributes getPreStepsAsAttributes(HashJoinPlan parent) throws SQLException { - boolean earlyEvaluation = parent.joinInfo.earlyEvaluation()[index]; - boolean skipMerge = parent.joinInfo.getSchemas()[index].getFieldCount() == 0; - String header; - if (hashExpressions != null) { - header = "PARALLEL " + parent.joinInfo.getJoinTypes()[index].toString().toUpperCase() - + "-JOIN TABLE " + index + (earlyEvaluation ? "" : "(DELAYED EVALUATION)") - + (skipMerge ? " (SKIP MERGE)" : ""); - } else { - header = "SKIP-SCAN-JOIN TABLE " + index; - } - return subPlanAttributesWithHeader(plan, header); + return subPlanAttributesWithHeader(plan, getBareJoinHeader(parent)); } @Override diff --git a/phoenix-core-client/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java b/phoenix-core-client/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java index 9e1cd2290b..361117d62f 100644 --- a/phoenix-core-client/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java +++ b/phoenix-core-client/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java @@ -41,6 +41,7 @@ import org.apache.phoenix.compile.ExplainPlan; import org.apache.phoenix.compile.ExplainPlanAttributes; import org.apache.phoenix.compile.ExplainPlanAttributes.ExplainPlanAttributesBuilder; import org.apache.phoenix.compile.GroupByCompiler.GroupBy; +import org.apache.phoenix.compile.JoinCompiler; import org.apache.phoenix.compile.OrderByCompiler.OrderBy; import org.apache.phoenix.compile.QueryCompiler; import org.apache.phoenix.compile.QueryPlan; @@ -98,6 +99,7 @@ public class SortMergeJoinPlan implements QueryPlan { * {@link JoinType#Left}. */ private final JoinType joinType; + private final JoinCompiler.Strategy strategy = JoinCompiler.Strategy.SORT_MERGE; private final QueryPlan lhsPlan; private final QueryPlan rhsPlan; private final List<Expression> lhsKeyExpressions; @@ -156,6 +158,14 @@ public class SortMergeJoinPlan implements QueryPlan { return statement.getOperation(); } + /** + * The {@link JoinCompiler.Strategy} chosen for this join. Always + * {@link JoinCompiler.Strategy#SORT_MERGE} for a {@link SortMergeJoinPlan}. + */ + public JoinCompiler.Strategy getStrategy() { + return strategy; + } + private static KeyValueSchema buildSchema(PTable table) { KeyValueSchemaBuilder builder = new KeyValueSchemaBuilder(0); if (table != null) { @@ -188,7 +198,8 @@ public class SortMergeJoinPlan implements QueryPlan { @Override public ExplainPlan getExplainPlan() throws SQLException { List<String> steps = Lists.newArrayList(); - steps.add("SORT-MERGE-JOIN (" + joinType.toString().toUpperCase() + ") TABLES"); + steps + .add("SORT-MERGE-JOIN (" + joinType.toString().toUpperCase() + ") TABLES /* SORT_MERGE */"); ExplainPlan lhsExplainPlan = lhsPlan.getExplainPlan(); List<String> lhsPlanSteps = lhsExplainPlan.getPlanSteps(); ExplainPlanAttributes lhsPlanAttributes = lhsExplainPlan.getPlanStepsAsAttributes(); diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithTableSampleIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithTableSampleIT.java index 04068fee05..1a90a1c04a 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithTableSampleIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryWithTableSampleIT.java @@ -247,7 +247,7 @@ public class QueryWithTableSampleIT extends ParallelStatsEnabledIT { assertPlan(conn, query).scanType("FULL SCAN").table(tableName).samplingRate(0.45d) .serverFirstKeyOnlyProjection(true).serverAggregate("SERVER AGGREGATE INTO SINGLE ROW") .dynamicServerFilter("DYNAMIC SERVER FILTER BY A.I1 IN (B.I1)").subPlanCount(1).subPlan(0) - .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0 (SKIP MERGE)").scanType("FULL SCAN") + .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0").scanType("FULL SCAN") .table(joinedTableName).samplingRate(0.75d).serverFirstKeyOnlyProjection(true).end(); } finally { conn.close(); diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexUsageIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexUsageIT.java index 674e84d43d..6cd01a876e 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexUsageIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexUsageIT.java @@ -862,12 +862,12 @@ public class IndexUsageIT extends ParallelStatsDisabledIT { .serverFirstKeyOnlyProjection(true).clientSortAlgo("CLIENT MERGE SORT").subPlanCount(1) .subPlan(0).scanType("RANGE SCAN").tableContains(indexName + "(" + tableName + ")") .keyRanges(" [1]").serverFirstKeyOnlyProjection(true).clientSortAlgo("CLIENT MERGE SORT") - .abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0 (SKIP MERGE)").end(); + .abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0").end(); } else { assertPlan(conn, query).scanType("RANGE SCAN").tableContains(indexName) .keyRanges(" ['1David']").serverFirstKeyOnlyProjection(true).subPlanCount(1).subPlan(0) .scanType("FULL SCAN").tableContains(indexName).serverFirstKeyOnlyProjection(true) - .abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0 (SKIP MERGE)").end(); + .abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0").end(); } rs = conn.createStatement().executeQuery(query); diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinGlobalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinGlobalIndexIT.java index e1aa1b19e0..4c5f9fa3be 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinGlobalIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinGlobalIndexIT.java @@ -142,8 +142,8 @@ public class HashJoinGlobalIndexIT extends HashJoinIT { String order = getTableName(conn, JOIN_ORDER_TABLE_FULL_NAME); String idxSupplier = getSchemaName() + ".idx_supplier"; assertPlan(conn, query).scanType("FULL SCAN").table(idxItem).subPlanCount(2).subPlan(0) - .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0 (SKIP MERGE)").scanType("FULL SCAN") - .table(order).serverWhereFilter("QUANTITY < 5000").end().subPlan(1) + .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0").scanType("FULL SCAN").table(order) + .serverWhereFilter("QUANTITY < 5000").end().subPlan(1) .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1").scanType("FULL SCAN").table(idxSupplier) .serverFirstKeyOnlyProjection(true).end(); } @@ -225,8 +225,8 @@ public class HashJoinGlobalIndexIT extends HashJoinIT { assertPlan(conn, query).scanType("FULL SCAN").table(order) .serverAggregate("SERVER AGGREGATE INTO DISTINCT ROWS BY [O.IID]") .clientSortAlgo("CLIENT MERGE SORT").clientSortedBy("[SUM(O.QUANTITY) DESC]").subPlanCount(1) - .subPlan(0).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0 (SKIP MERGE)") - .scanType("FULL SCAN").table(idxItem).serverFirstKeyOnlyProjection(true).end(); + .subPlan(0).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0").scanType("FULL SCAN") + .table(idxItem).serverFirstKeyOnlyProjection(true).end(); } @Override @@ -277,8 +277,8 @@ public class HashJoinGlobalIndexIT extends HashJoinIT { assertPlan(conn, query).iteratorType("SERIAL").scanType("FULL SCAN").table(supplier) .serverRowLimit(4L).clientRowLimit(4).joinScannerLimit(4L).subPlanCount(2).subPlan(0) .abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0").scanType("FULL SCAN").table(idxItem).end() - .subPlan(1).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1(DELAYED EVALUATION)") - .scanType("FULL SCAN").table(order).end(); + .subPlan(1).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1").scanType("FULL SCAN") + .table(order).end(); } @Override @@ -290,8 +290,8 @@ public class HashJoinGlobalIndexIT extends HashJoinIT { .dynamicServerFilter("DYNAMIC SERVER FILTER BY \"S.supplier_id\" IN (\"I.0:supplier_id\")") .joinScannerLimit(4L).subPlanCount(2).subPlan(0) .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0").scanType("FULL SCAN").table(idxItem).end() - .subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)") - .scanType("FULL SCAN").table(order).end(); + .subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1").scanType("FULL SCAN") + .table(order).end(); } @Override @@ -316,9 +316,8 @@ public class HashJoinGlobalIndexIT extends HashJoinIT { assertPlan(conn, query).iteratorType("SERIAL").scanType("FULL SCAN").table(supplier) .serverOffset(2).serverRowLimit(3L).clientRowLimit(1).joinScannerLimit(3L).subPlanCount(2) .subPlan(0).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0").scanType("FULL SCAN") - .table(idxItem).end().subPlan(1) - .abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1(DELAYED EVALUATION)").scanType("FULL SCAN") - .table(order).end(); + .table(idxItem).end().subPlan(1).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1") + .scanType("FULL SCAN").table(order).end(); } @Override @@ -331,8 +330,8 @@ public class HashJoinGlobalIndexIT extends HashJoinIT { .dynamicServerFilter("DYNAMIC SERVER FILTER BY \"S.supplier_id\" IN (\"I.0:supplier_id\")") .joinScannerLimit(3L).subPlanCount(2).subPlan(0) .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0").scanType("FULL SCAN").table(idxItem).end() - .subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)") - .scanType("FULL SCAN").table(order).end(); + .subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1").scanType("FULL SCAN") + .table(order).end(); } @Parameters(name = "HashJoinGlobalIndexIT_{index}") // name is used by failsafe as file name in diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java index e83b84ed7c..96b2de8bfe 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinLocalIndexIT.java @@ -173,7 +173,7 @@ public class HashJoinLocalIndexIT extends HashJoinIT { assertPlan(conn, query).scanType("RANGE SCAN").table(itemIndex + "(" + item + ")") .keyRanges(" [1]").clientSortAlgo("CLIENT MERGE SORT") .dynamicServerFilter("DYNAMIC SERVER FILTER BY \"I.:item_id\" IN (\"O.item_id\")") - .subPlanCount(2).subPlan(0).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0 (SKIP MERGE)") + .subPlanCount(2).subPlan(0).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0") .scanType("FULL SCAN").table(order).serverWhereFilter("QUANTITY < 5000").end().subPlan(1) .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1").scanType("RANGE SCAN") .table(supplierIndex + "(" + supplier + ")").keyRanges(" [1]") @@ -274,9 +274,9 @@ public class HashJoinLocalIndexIT extends HashJoinIT { assertPlan(conn, query).scanType("FULL SCAN").table(order) .serverAggregate("SERVER AGGREGATE INTO DISTINCT ROWS BY [O.IID]") .clientSortAlgo("CLIENT MERGE SORT").clientSortedBy("[SUM(O.QUANTITY) DESC]").subPlanCount(1) - .subPlan(0).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0 (SKIP MERGE)") - .scanType("RANGE SCAN").table(itemIndex + "(" + item + ")").keyRanges(" [1]") - .serverFirstKeyOnlyProjection(true).clientSortAlgo("CLIENT MERGE SORT").end(); + .subPlan(0).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0").scanType("RANGE SCAN") + .table(itemIndex + "(" + item + ")").keyRanges(" [1]").serverFirstKeyOnlyProjection(true) + .clientSortAlgo("CLIENT MERGE SORT").end(); } @Override @@ -335,8 +335,8 @@ public class HashJoinLocalIndexIT extends HashJoinIT { .serverRowLimit(4L).clientRowLimit(4).joinScannerLimit(4L).subPlanCount(2).subPlan(0) .abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0").scanType("RANGE SCAN") .table(itemIndex + "(" + item + ")").keyRanges(" [1]").clientSortAlgo("CLIENT MERGE SORT") - .end().subPlan(1).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1(DELAYED EVALUATION)") - .scanType("FULL SCAN").table(order).end(); + .end().subPlan(1).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1").scanType("FULL SCAN") + .table(order).end(); } @Override @@ -350,8 +350,8 @@ public class HashJoinLocalIndexIT extends HashJoinIT { .joinScannerLimit(4L).subPlanCount(2).subPlan(0) .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0").scanType("RANGE SCAN") .table(itemIndex + "(" + item + ")").keyRanges(" [1]").clientSortAlgo("CLIENT MERGE SORT") - .end().subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)") - .scanType("FULL SCAN").table(order).end(); + .end().subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1").scanType("FULL SCAN") + .table(order).end(); } @Override @@ -382,8 +382,8 @@ public class HashJoinLocalIndexIT extends HashJoinIT { .serverOffset(2).serverRowLimit(3L).clientRowLimit(1).joinScannerLimit(3L).subPlanCount(2) .subPlan(0).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0").scanType("RANGE SCAN") .table(itemIndex + "(" + item + ")").keyRanges(" [1]").clientSortAlgo("CLIENT MERGE SORT") - .end().subPlan(1).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1(DELAYED EVALUATION)") - .scanType("FULL SCAN").table(order).end(); + .end().subPlan(1).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1").scanType("FULL SCAN") + .table(order).end(); } @Override @@ -398,8 +398,8 @@ public class HashJoinLocalIndexIT extends HashJoinIT { .joinScannerLimit(3L).subPlanCount(2).subPlan(0) .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0").scanType("RANGE SCAN") .table(itemIndex + "(" + item + ")").keyRanges(" [1]").clientSortAlgo("CLIENT MERGE SORT") - .end().subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)") - .scanType("FULL SCAN").table(order).end(); + .end().subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1").scanType("FULL SCAN") + .table(order).end(); } @Parameters(name = "HashJoinLocalIndexIT_{index}") // name is used by failsafe as file name in 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 2c04a09961..46a6fa15d3 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 @@ -785,10 +785,10 @@ public class HashJoinMoreIT extends ParallelStatsDisabledIT { .serverFirstKeyOnlyProjection(true) .serverAggregate("SERVER AGGREGATE INTO DISTINCT ROWS BY [\"E.TIMESTAMP\", E.BUCKET]") .clientSortAlgo("CLIENT MERGE SORT").subPlanCount(1).subPlan(0) - .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0 (SKIP MERGE)") - .scanType("SKIP SCAN ON 2 RANGES").table(t[i]).keyRanges(innerKeyRanges) - .serverFirstKeyOnlyProjection(true).serverWhereFilter("SRC_LOCATION = DST_LOCATION") - .clientSortAlgo("CLIENT MERGE SORT").end(); + .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0").scanType("SKIP SCAN ON 2 RANGES") + .table(t[i]).keyRanges(innerKeyRanges).serverFirstKeyOnlyProjection(true) + .serverWhereFilter("SRC_LOCATION = DST_LOCATION").clientSortAlgo("CLIENT MERGE SORT") + .end(); ResultSet rs = conn.createStatement().executeQuery(q); assertTrue(rs.next()); diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinNoIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinNoIndexIT.java index 104e14f50a..b9d8bccc4c 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinNoIndexIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/join/HashJoinNoIndexIT.java @@ -142,7 +142,7 @@ public class HashJoinNoIndexIT extends HashJoinIT { String supplier = getTableName(conn, JOIN_SUPPLIER_TABLE_FULL_NAME); assertPlan(conn, query).scanType("FULL SCAN").table(item) .dynamicServerFilter("DYNAMIC SERVER FILTER BY \"I.item_id\" IN (\"O.item_id\")") - .subPlanCount(2).subPlan(0).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0 (SKIP MERGE)") + .subPlanCount(2).subPlan(0).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0") .scanType("FULL SCAN").table(order).serverWhereFilter("QUANTITY < 5000").end().subPlan(1) .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1").scanType("FULL SCAN").table(supplier) .end(); @@ -224,8 +224,8 @@ public class HashJoinNoIndexIT extends HashJoinIT { assertPlan(conn, query).scanType("FULL SCAN").table(order) .serverAggregate("SERVER AGGREGATE INTO DISTINCT ROWS BY [O.IID]") .clientSortAlgo("CLIENT MERGE SORT").clientSortedBy("[SUM(O.QUANTITY) DESC]").subPlanCount(1) - .subPlan(0).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0 (SKIP MERGE)") - .scanType("FULL SCAN").table(item).serverFirstKeyOnlyProjection(true).end(); + .subPlan(0).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0").scanType("FULL SCAN") + .table(item).serverFirstKeyOnlyProjection(true).end(); } @Override @@ -276,8 +276,8 @@ public class HashJoinNoIndexIT extends HashJoinIT { assertPlan(conn, query).iteratorType("SERIAL").scanType("FULL SCAN").table(supplier) .serverRowLimit(4L).clientRowLimit(4).joinScannerLimit(4L).subPlanCount(2).subPlan(0) .abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0").scanType("FULL SCAN").table(item).end() - .subPlan(1).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1(DELAYED EVALUATION)") - .scanType("FULL SCAN").table(order).end(); + .subPlan(1).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1").scanType("FULL SCAN") + .table(order).end(); } @Override @@ -289,8 +289,8 @@ public class HashJoinNoIndexIT extends HashJoinIT { .dynamicServerFilter("DYNAMIC SERVER FILTER BY \"S.supplier_id\" IN (\"I.supplier_id\")") .joinScannerLimit(4L).subPlanCount(2).subPlan(0) .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0").scanType("FULL SCAN").table(item).end() - .subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)") - .scanType("FULL SCAN").table(order).end(); + .subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1").scanType("FULL SCAN") + .table(order).end(); } @Override @@ -316,9 +316,8 @@ public class HashJoinNoIndexIT extends HashJoinIT { assertPlan(conn, query).iteratorType("SERIAL").scanType("FULL SCAN").table(supplier) .serverOffset(2).serverRowLimit(3L).clientRowLimit(1).joinScannerLimit(3L).subPlanCount(2) .subPlan(0).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 0").scanType("FULL SCAN") - .table(item).end().subPlan(1) - .abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1(DELAYED EVALUATION)").scanType("FULL SCAN") - .table(order).end(); + .table(item).end().subPlan(1).abstractExplainPlan("PARALLEL LEFT-JOIN TABLE 1") + .scanType("FULL SCAN").table(order).end(); } @Override @@ -331,8 +330,8 @@ public class HashJoinNoIndexIT extends HashJoinIT { .dynamicServerFilter("DYNAMIC SERVER FILTER BY \"S.supplier_id\" IN (\"I.supplier_id\")") .joinScannerLimit(3L).subPlanCount(2).subPlan(0) .abstractExplainPlan("PARALLEL INNER-JOIN TABLE 0").scanType("FULL SCAN").table(item).end() - .subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1(DELAYED EVALUATION)") - .scanType("FULL SCAN").table(order).end(); + .subPlan(1).abstractExplainPlan("PARALLEL INNER-JOIN TABLE 1").scanType("FULL SCAN") + .table(order).end(); } @Parameters(name = "HashJoinNoIndexIT_{index}") // name is used by failsafe as file name in diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/explain/ExplainPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/explain/ExplainPlanTest.java index 1326750984..e0880a2c2d 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/query/explain/ExplainPlanTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/query/explain/ExplainPlanTest.java @@ -491,7 +491,7 @@ public class ExplainPlanTest extends BaseConnectionlessQueryTest { "SELECT /*+ USE_SORT_MERGE_JOIN */ a.a_string, b.a_string FROM atable a" + " JOIN atable b ON a.organization_id = b.organization_id" + " WHERE a.organization_id = '00D000000000001'", - text("SORT-MERGE-JOIN (INNER) TABLES", + text("SORT-MERGE-JOIN (INNER) TABLES /* SORT_MERGE */", " CLIENT PARALLEL <N>-WAY RANGE SCAN OVER ATABLE ['00D000000000001']", " INDEX ATABLE", " REGIONS PLANNED <N>", "AND", " CLIENT PARALLEL <N>-WAY FULL SCAN OVER ATABLE", " INDEX ATABLE", @@ -514,7 +514,7 @@ public class ExplainPlanTest extends BaseConnectionlessQueryTest { + " JOIN atable b ON a.organization_id = b.organization_id" + " WHERE a.organization_id = '00D000000000001'", text("CLIENT PARALLEL <N>-WAY RANGE SCAN OVER ATABLE ['00D000000000001']", " INDEX ATABLE", - " REGIONS PLANNED <N>", " PARALLEL INNER-JOIN TABLE 0", + " REGIONS PLANNED <N>", " PARALLEL INNER-JOIN TABLE 0 /* HASH BUILD RIGHT */", " CLIENT PARALLEL <N>-WAY FULL SCAN OVER ATABLE", " INDEX ATABLE", " REGIONS PLANNED <N>", " DYNAMIC SERVER FILTER BY A.ORGANIZATION_ID IN (B.ORGANIZATION_ID)"), @@ -536,7 +536,7 @@ public class ExplainPlanTest extends BaseConnectionlessQueryTest { "SELECT a_string FROM atable" + " WHERE organization_id IN (SELECT organization_id FROM atable WHERE a_integer = 1)", text("CLIENT PARALLEL <N>-WAY FULL SCAN OVER ATABLE", " INDEX ATABLE", - " REGIONS PLANNED <N>", " SKIP-SCAN-JOIN TABLE 0", + " REGIONS PLANNED <N>", " SKIP-SCAN-JOIN TABLE 0 /* HASH BUILD RIGHT */", " CLIENT PARALLEL <N>-WAY FULL SCAN OVER ATABLE", " INDEX ATABLE", " REGIONS PLANNED <N>", " SERVER FILTER BY A_INTEGER = 1", " SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [ORGANIZATION_ID]",
