This is an automated email from the ASF dual-hosted git repository.

vsarathy1 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new f20b04bcfc [ASTERIXDB-3350][COMP] Refactor and simplify CBO plan 
generation code.
f20b04bcfc is described below

commit f20b04bcfcfc3f1b18ef6ca2e1d29c8c168e3e0e
Author: Vijay Sarathy <[email protected]>
AuthorDate: Thu Feb 1 17:03:29 2024 -0800

    [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: <[email protected]>
    Reviewed-by: Vijay Sarathy <[email protected]>
    Integration-Tests: Jenkins <[email protected]>
    Tested-by: Jenkins <[email protected]>
---
 .../asterix/optimizer/rules/cbo/JoinNode.java      | 358 ++++++++++-----------
 1 file changed, 163 insertions(+), 195 deletions(-)

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 ebbd71ae45..872f6b1ad2 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.AbstractFunctionCa
 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 @@ public class JoinNode {
             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 @@ public class JoinNode {
             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) {
+            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;
+    }
+
+    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, null, outerJoin);
+                        buildHashJoinPlan(rightJn, leftJn, rightPlan, 
leftPlan, hashJoinExpr, hintHashJoin, 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);
+        }
+        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);
             }
-            cpPlan = buildCPJoinPlan(leftJn, rightJn, leftPlan, rightPlan, 
hashJoinExpr, nestedLoopJoinExpr, outerJoin);
+        } else if (broadcastObject == null) {
+            bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn, 
leftPlan, rightPlan, hashJoinExpr,
+                    hintBroadcastHashJoin, outerJoin);
             if (!joinEnum.forceJoinOrderMode || level <= 
joinEnum.cboFullEnumLevel) {
-                commutativeCpPlan = buildCPJoinPlan(rightJn, leftJn, 
rightPlan, leftPlan, hashJoinExpr,
-                        nestedLoopJoinExpr, outerJoin);
+                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;
+        }
 
-        //Reset as these might have changed when we tried the commutative 
joins.
-        this.leftJn = leftJn;
-        this.rightJn = rightJn;
+        // hintBroadcastHashJoin has been used, no warning to be issued.
+        joinEnum.joinHints.put(hintBroadcastHashJoin, null);
+        return true;
+    }
 
-        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 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 @@ public class JoinNode {
             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()) {

Reply via email to