[ASTERIXDB-3350][COMP] Refactor and simplify CBO plan generation code.
Change-Id: I34de84cef4094e714862517883f862759825c172
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18151
Reviewed-by: <murali.krishna@couchbase.com>
Reviewed-by: Vijay Sarathy <vijay.sarathy@couchbase.com>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
index ebbd71a..872f6b1 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
@@ -59,6 +59,7 @@
import org.apache.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation;
import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.HashJoinExpressionAnnotation;
+import org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
import org.apache.hyracks.algebricks.core.algebra.expressions.PredicateCardinalityAnnotation;
import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
import org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
@@ -1201,7 +1202,6 @@
throws AlgebricksException {
this.leftJn = leftJn;
this.rightJn = rightJn;
- ICost noJoinCost = joinEnum.getCostHandle().maxCost();
if (leftJn.planIndexesArray.size() == 0 || rightJn.planIndexesArray.size() == 0) {
return;
@@ -1249,214 +1249,182 @@
this.distinctCardinality = (double) Math.round(this.distinctCardinality * 100) / 100;
}
- int hjPlan, commutativeHjPlan, bcastHjPlan, commutativeBcastHjPlan, nljPlan, commutativeNljPlan, cpPlan,
- commutativeCpPlan;
- hjPlan = commutativeHjPlan = bcastHjPlan =
- commutativeBcastHjPlan = nljPlan = commutativeNljPlan = cpPlan = commutativeCpPlan = PlanNode.NO_PLAN;
-
+ boolean validPlan = false;
HashJoinExpressionAnnotation hintHashJoin = joinEnum.findHashJoinHint(newJoinConditions);
BroadcastExpressionAnnotation hintBroadcastHashJoin = joinEnum.findBroadcastHashJoinHint(newJoinConditions);
IndexedNLJoinExpressionAnnotation hintNLJoin = joinEnum.findNLJoinHint(newJoinConditions);
if (hintHashJoin != null) {
- boolean build = (hintHashJoin.getBuildOrProbe() == HashJoinExpressionAnnotation.BuildOrProbe.BUILD);
- boolean probe = (hintHashJoin.getBuildOrProbe() == HashJoinExpressionAnnotation.BuildOrProbe.PROBE);
- boolean validBuildOrProbeObject = false;
- String buildOrProbeObject = hintHashJoin.getName();
- if (buildOrProbeObject != null && (rightJn.datasetNames.contains(buildOrProbeObject)
- || rightJn.aliases.contains(buildOrProbeObject) || leftJn.datasetNames.contains(buildOrProbeObject)
- || leftJn.aliases.contains(buildOrProbeObject))) {
- validBuildOrProbeObject = true;
- }
- if (validBuildOrProbeObject) {
- if ((build && (rightJn.datasetNames.contains(buildOrProbeObject)
- || rightJn.aliases.contains(buildOrProbeObject)))
- || (probe && (leftJn.datasetNames.contains(buildOrProbeObject)
- || leftJn.aliases.contains(buildOrProbeObject)))) {
- hjPlan = buildHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, hintHashJoin,
- outerJoin);
- } else if ((build && (leftJn.datasetNames.contains(buildOrProbeObject)
- || leftJn.aliases.contains(buildOrProbeObject)))
- || (probe && (rightJn.datasetNames.contains(buildOrProbeObject)
- || rightJn.aliases.contains(buildOrProbeObject)))) {
- commutativeHjPlan = buildHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr,
- hintHashJoin, outerJoin);
- }
- }
- if (hjPlan != PlanNode.NO_PLAN || commutativeHjPlan != PlanNode.NO_PLAN) {
- // hintHashJoin has been used.
- joinEnum.joinHints.put(hintHashJoin, null);
- } else if (!(joinEnum.joinHints.containsKey(hintHashJoin)
- && joinEnum.joinHints.get(hintHashJoin) == null)) {
- // Hints are attached to predicates, so newJoinConditions should not be empty, but adding the check to be safe.
- if (!joinEnum.getJoinConditions().isEmpty() && !newJoinConditions.isEmpty()) {
- if (!joinEnum.joinHints.containsKey(hintHashJoin)) {
- joinEnum.joinHints.put(hintHashJoin,
- Warning.of(
- joinEnum.getJoinConditions().get(newJoinConditions.get(0)).joinCondition
- .getSourceLocation(),
- ErrorCode.INAPPLICABLE_HINT, "hash join",
- (build ? "build " : "probe ") + "with " + buildOrProbeObject));
- }
- }
- hjPlan = buildHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, null, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeHjPlan =
- buildHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr, null, outerJoin);
- }
- bcastHjPlan =
- buildBroadcastHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, null, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeBcastHjPlan = buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan,
- hashJoinExpr, null, outerJoin);
- }
- nljPlan = buildNLJoinPlan(leftJn, rightJn, leftPlan, rightPlan, nestedLoopJoinExpr, null, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeNljPlan =
- buildNLJoinPlan(rightJn, leftJn, rightPlan, leftPlan, nestedLoopJoinExpr, null, outerJoin);
- }
- cpPlan = buildCPJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, nestedLoopJoinExpr,
- outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeCpPlan = buildCPJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr,
- nestedLoopJoinExpr, outerJoin);
- }
- }
+ validPlan = buildHintedHJPlans(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, hintHashJoin, outerJoin,
+ newJoinConditions);
} else if (hintBroadcastHashJoin != null) {
- boolean validBroadcastObject = false;
- String broadcastObject = hintBroadcastHashJoin.getName();
- if (broadcastObject != null && (rightJn.datasetNames.contains(broadcastObject)
- || rightJn.aliases.contains(broadcastObject) || leftJn.datasetNames.contains(broadcastObject)
- || leftJn.aliases.contains(broadcastObject))) {
- validBroadcastObject = true;
- }
- if (validBroadcastObject) {
- if (rightJn.datasetNames.contains(broadcastObject) || rightJn.aliases.contains(broadcastObject)) {
- bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr,
- hintBroadcastHashJoin, outerJoin);
- } else if (leftJn.datasetNames.contains(broadcastObject) || leftJn.aliases.contains(broadcastObject)) {
- commutativeBcastHjPlan = buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan,
- hashJoinExpr, hintBroadcastHashJoin, outerJoin);
- }
- } else if (broadcastObject == null) {
- bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr,
- hintBroadcastHashJoin, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeBcastHjPlan = buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan,
- hashJoinExpr, hintBroadcastHashJoin, outerJoin);
- }
- }
- if (bcastHjPlan != PlanNode.NO_PLAN || commutativeBcastHjPlan != PlanNode.NO_PLAN) {
- // hintBroadcastHashJoin has been used.
- joinEnum.joinHints.put(hintBroadcastHashJoin, null);
- } else if (!(joinEnum.joinHints.containsKey(hintBroadcastHashJoin)
- && joinEnum.joinHints.get(hintBroadcastHashJoin) == null)) {
- // Hints are attached to predicates, so newJoinConditions should not be empty, but adding the check to be safe.
- if (!joinEnum.getJoinConditions().isEmpty() && !newJoinConditions.isEmpty()) {
- if (!joinEnum.joinHints.containsKey(hintBroadcastHashJoin)) {
- joinEnum.joinHints.put(hintBroadcastHashJoin,
- Warning.of(
- joinEnum.getJoinConditions().get(newJoinConditions.get(0)).joinCondition
- .getSourceLocation(),
- ErrorCode.INAPPLICABLE_HINT, "broadcast hash join",
- "broadcast " + broadcastObject));
- }
- }
-
- hjPlan = buildHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, null, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeHjPlan =
- buildHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr, null, outerJoin);
- }
- bcastHjPlan =
- buildBroadcastHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, null, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeBcastHjPlan = buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan,
- hashJoinExpr, null, outerJoin);
- }
- nljPlan = buildNLJoinPlan(leftJn, rightJn, leftPlan, rightPlan, nestedLoopJoinExpr, null, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeNljPlan =
- buildNLJoinPlan(rightJn, leftJn, rightPlan, leftPlan, nestedLoopJoinExpr, null, outerJoin);
- }
- cpPlan = buildCPJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, nestedLoopJoinExpr,
- outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeCpPlan = buildCPJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr,
- nestedLoopJoinExpr, outerJoin);
- }
- }
+ validPlan = buildHintedBcastHJPlans(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr,
+ hintBroadcastHashJoin, outerJoin, newJoinConditions);
} else if (hintNLJoin != null) {
- nljPlan = buildNLJoinPlan(leftJn, rightJn, leftPlan, rightPlan, nestedLoopJoinExpr, hintNLJoin, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeNljPlan = buildNLJoinPlan(rightJn, leftJn, rightPlan, leftPlan, nestedLoopJoinExpr,
- hintNLJoin, outerJoin);
- }
- if (nljPlan != PlanNode.NO_PLAN || commutativeNljPlan != PlanNode.NO_PLAN) {
- // hintNLJ has been used.
- joinEnum.joinHints.put(hintNLJoin, null);
- } else if (!(joinEnum.joinHints.containsKey(hintNLJoin) && joinEnum.joinHints.get(hintNLJoin) == null)) {
- // Hints are attached to predicates, so newJoinConditions should not be empty, but adding the check to be safe.
- if (!joinEnum.getJoinConditions().isEmpty() && !newJoinConditions.isEmpty()) {
- if (!joinEnum.joinHints.containsKey(hintNLJoin)) {
- joinEnum.joinHints.put(hintNLJoin,
- Warning.of(
- joinEnum.getJoinConditions().get(newJoinConditions.get(0)).joinCondition
- .getSourceLocation(),
- ErrorCode.INAPPLICABLE_HINT, "index nested loop join", "ignored"));
- }
- }
- hjPlan = buildHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, null, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeHjPlan =
- buildHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr, null, outerJoin);
- }
- bcastHjPlan =
- buildBroadcastHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, null, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeBcastHjPlan = buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan,
- hashJoinExpr, null, outerJoin);
- }
- cpPlan = buildCPJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, nestedLoopJoinExpr,
- outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeCpPlan = buildCPJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr,
- nestedLoopJoinExpr, outerJoin);
- }
- }
- } else {
- hjPlan = buildHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, null, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeHjPlan =
- buildHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr, null, outerJoin);
- }
- bcastHjPlan =
- buildBroadcastHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, null, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeBcastHjPlan =
- buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr, null, outerJoin);
- }
- nljPlan = buildNLJoinPlan(leftJn, rightJn, leftPlan, rightPlan, nestedLoopJoinExpr, null, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeNljPlan =
- buildNLJoinPlan(rightJn, leftJn, rightPlan, leftPlan, nestedLoopJoinExpr, null, outerJoin);
- }
- cpPlan = buildCPJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, nestedLoopJoinExpr, outerJoin);
- if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
- commutativeCpPlan = buildCPJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr,
- nestedLoopJoinExpr, outerJoin);
- }
+ validPlan = buildHintedNLJPlans(leftJn, rightJn, leftPlan, rightPlan, nestedLoopJoinExpr, hintNLJoin,
+ outerJoin, newJoinConditions);
+ }
+
+ if (!validPlan) {
+ // No join hints or inapplicable hinted plans, try all non hinted plans.
+ buildAllNonHintedPlans(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, nestedLoopJoinExpr, outerJoin);
}
//Reset as these might have changed when we tried the commutative joins.
this.leftJn = leftJn;
this.rightJn = rightJn;
+ }
- if (hjPlan == PlanNode.NO_PLAN && commutativeHjPlan == PlanNode.NO_PLAN && bcastHjPlan == PlanNode.NO_PLAN
- && commutativeBcastHjPlan == PlanNode.NO_PLAN && nljPlan == PlanNode.NO_PLAN
- && commutativeNljPlan == PlanNode.NO_PLAN && cpPlan == PlanNode.NO_PLAN
- && commutativeCpPlan == PlanNode.NO_PLAN) {
- return;
+ private boolean buildHintedHJPlans(JoinNode leftJn, JoinNode rightJn, PlanNode leftPlan, PlanNode rightPlan,
+ ILogicalExpression hashJoinExpr, HashJoinExpressionAnnotation hintHashJoin, boolean outerJoin,
+ List<Integer> newJoinConditions) {
+ int hjPlan, commutativeHjPlan;
+ hjPlan = commutativeHjPlan = PlanNode.NO_PLAN;
+ boolean build = (hintHashJoin.getBuildOrProbe() == HashJoinExpressionAnnotation.BuildOrProbe.BUILD);
+ boolean probe = (hintHashJoin.getBuildOrProbe() == HashJoinExpressionAnnotation.BuildOrProbe.PROBE);
+ boolean validBuildOrProbeObject = false;
+ String buildOrProbeObject = hintHashJoin.getName();
+ if (buildOrProbeObject != null && (rightJn.datasetNames.contains(buildOrProbeObject)
+ || rightJn.aliases.contains(buildOrProbeObject) || leftJn.datasetNames.contains(buildOrProbeObject)
+ || leftJn.aliases.contains(buildOrProbeObject))) {
+ validBuildOrProbeObject = true;
+ }
+ if (validBuildOrProbeObject) {
+ if ((build && (rightJn.datasetNames.contains(buildOrProbeObject)
+ || rightJn.aliases.contains(buildOrProbeObject)))
+ || (probe && (leftJn.datasetNames.contains(buildOrProbeObject)
+ || leftJn.aliases.contains(buildOrProbeObject)))) {
+ hjPlan = buildHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, hintHashJoin, outerJoin);
+ } else if ((build && (leftJn.datasetNames.contains(buildOrProbeObject)
+ || leftJn.aliases.contains(buildOrProbeObject)))
+ || (probe && (rightJn.datasetNames.contains(buildOrProbeObject)
+ || rightJn.aliases.contains(buildOrProbeObject)))) {
+ commutativeHjPlan =
+ buildHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr, hintHashJoin, outerJoin);
+ }
+ }
+ if (hjPlan == PlanNode.NO_PLAN && commutativeHjPlan == PlanNode.NO_PLAN) {
+ // No hinted HJ plan, issue an inapplicable hint warning.
+ inapplicableHintWarning(hintHashJoin, newJoinConditions);
+ return false;
+ }
+
+ // hintHashJoin has been used, no warning to be issued.
+ joinEnum.joinHints.put(hintHashJoin, null);
+ return true;
+ }
+
+ private boolean buildHintedBcastHJPlans(JoinNode leftJn, JoinNode rightJn, PlanNode leftPlan, PlanNode rightPlan,
+ ILogicalExpression hashJoinExpr, BroadcastExpressionAnnotation hintBroadcastHashJoin, boolean outerJoin,
+ List<Integer> newJoinConditions) {
+ int bcastHjPlan, commutativeBcastHjPlan;
+ bcastHjPlan = commutativeBcastHjPlan = PlanNode.NO_PLAN;
+ boolean validBroadcastObject = false;
+ String broadcastObject = hintBroadcastHashJoin.getName();
+ if (broadcastObject != null
+ && (rightJn.datasetNames.contains(broadcastObject) || rightJn.aliases.contains(broadcastObject)
+ || leftJn.datasetNames.contains(broadcastObject) || leftJn.aliases.contains(broadcastObject))) {
+ validBroadcastObject = true;
+ }
+ if (validBroadcastObject) {
+ if (rightJn.datasetNames.contains(broadcastObject) || rightJn.aliases.contains(broadcastObject)) {
+ bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr,
+ hintBroadcastHashJoin, outerJoin);
+ } else if (leftJn.datasetNames.contains(broadcastObject) || leftJn.aliases.contains(broadcastObject)) {
+ commutativeBcastHjPlan = buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr,
+ hintBroadcastHashJoin, outerJoin);
+ }
+ } else if (broadcastObject == null) {
+ bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr,
+ hintBroadcastHashJoin, outerJoin);
+ if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
+ commutativeBcastHjPlan = buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr,
+ hintBroadcastHashJoin, outerJoin);
+ }
+ }
+ if (bcastHjPlan == PlanNode.NO_PLAN && commutativeBcastHjPlan == PlanNode.NO_PLAN) {
+ // No hinted BHJ plan, issue an inapplicable hint warning.
+ inapplicableHintWarning(hintBroadcastHashJoin, newJoinConditions);
+ return false;
+ }
+
+ // hintBroadcastHashJoin has been used, no warning to be issued.
+ joinEnum.joinHints.put(hintBroadcastHashJoin, null);
+ return true;
+ }
+
+ private boolean buildHintedNLJPlans(JoinNode leftJn, JoinNode rightJn, PlanNode leftPlan, PlanNode rightPlan,
+ ILogicalExpression nestedLoopJoinExpr, IndexedNLJoinExpressionAnnotation hintNLJoin, boolean outerJoin,
+ List<Integer> newJoinConditions) throws AlgebricksException {
+ int nljPlan, commutativeNljPlan;
+ nljPlan = commutativeNljPlan = PlanNode.NO_PLAN;
+ nljPlan = buildNLJoinPlan(leftJn, rightJn, leftPlan, rightPlan, nestedLoopJoinExpr, hintNLJoin, outerJoin);
+ if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
+ commutativeNljPlan =
+ buildNLJoinPlan(rightJn, leftJn, rightPlan, leftPlan, nestedLoopJoinExpr, hintNLJoin, outerJoin);
+ }
+ if (nljPlan == PlanNode.NO_PLAN && commutativeNljPlan == PlanNode.NO_PLAN) {
+ // No hinted NLJ plan, issue an inapplicable hint warning.
+ inapplicableHintWarning(hintNLJoin, newJoinConditions);
+ return false;
+ }
+
+ // hintNLJoin has been used, no warning to be issued.
+ joinEnum.joinHints.put(hintNLJoin, null);
+ return true;
+ }
+
+ private void buildAllNonHintedPlans(JoinNode leftJn, JoinNode rightJn, PlanNode leftPlan, PlanNode rightPlan,
+ ILogicalExpression hashJoinExpr, ILogicalExpression nestedLoopJoinExpr, boolean outerJoin)
+ throws AlgebricksException {
+ buildHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, null, outerJoin);
+ if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
+ buildHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr, null, outerJoin);
+ }
+ buildBroadcastHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, null, outerJoin);
+ if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
+ buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr, null, outerJoin);
+ }
+ buildNLJoinPlan(leftJn, rightJn, leftPlan, rightPlan, nestedLoopJoinExpr, null, outerJoin);
+ if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
+ buildNLJoinPlan(rightJn, leftJn, rightPlan, leftPlan, nestedLoopJoinExpr, null, outerJoin);
+ }
+ buildCPJoinPlan(leftJn, rightJn, leftPlan, rightPlan, hashJoinExpr, nestedLoopJoinExpr, outerJoin);
+ if (!joinEnum.forceJoinOrderMode || level <= joinEnum.cboFullEnumLevel) {
+ buildCPJoinPlan(rightJn, leftJn, rightPlan, leftPlan, hashJoinExpr, nestedLoopJoinExpr, outerJoin);
+ }
+ }
+
+ private void inapplicableHintWarning(IExpressionAnnotation hint, List<Integer> newJoinConditions) {
+ HashJoinExpressionAnnotation hintHashJoin;
+ BroadcastExpressionAnnotation hintBroadcastHashJoin;
+ String param1 = "";
+ String param2 = "";
+
+ if (hint instanceof HashJoinExpressionAnnotation) {
+ hintHashJoin = (HashJoinExpressionAnnotation) hint;
+ boolean build = (hintHashJoin.getBuildOrProbe() == HashJoinExpressionAnnotation.BuildOrProbe.BUILD);
+ String buildOrProbeObject = hintHashJoin.getName();
+ param1 = "hash join";
+ param2 = (build ? "build " : "probe ") + "with " + buildOrProbeObject;
+ } else if (hint instanceof BroadcastExpressionAnnotation) {
+ hintBroadcastHashJoin = (BroadcastExpressionAnnotation) hint;
+ String broadcastObject = hintBroadcastHashJoin.getName();
+ param1 = "broadcast hash join";
+ param2 = "broadcast " + broadcastObject == null ? "" : broadcastObject;
+ } else if (hint instanceof IndexedNLJoinExpressionAnnotation) {
+ param1 = "index nested loop join";
+ param2 = "ignored";
+ }
+
+ if (!(joinEnum.joinHints.containsKey(hint) && joinEnum.joinHints.get(hint) == null)) {
+ // No valid hinted plans were built, issue a warning.
+ // Hints are attached to predicates, so newJoinConditions should not be empty, but adding the check to be safe.
+ if (!joinEnum.getJoinConditions().isEmpty() && !newJoinConditions.isEmpty()) {
+ joinEnum.joinHints.put(hint, Warning.of(
+ joinEnum.getJoinConditions().get(newJoinConditions.get(0)).joinCondition.getSourceLocation(),
+ ErrorCode.INAPPLICABLE_HINT, param1, param2));
+ }
}
}
@@ -1529,7 +1497,7 @@
for (int j = 0; j < planIndexesArray.size(); j++) {
int k = planIndexesArray.get(j);
PlanNode pn = allPlans.get(k);
- sb.append("\nPrinting Plan Node ").append(k).append('\n');
+ sb.append("\nPrinting Plan ").append(k).append('\n');
sb.append("planIndexesArray [").append(j).append("] ").append(k).append('\n');
if (IsBaseLevelJoinNode()) {
if (pn.IsScanNode()) {