>From Vijay Sarathy <[email protected]>:
Vijay Sarathy has uploaded this change for review. (
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17550 )
Change subject: [ASTERIXDB-3195][COMP] Need a debug option to enumerate all
plans without pruning during join enumeration.
......................................................................
[ASTERIXDB-3195][COMP] Need a debug option to enumerate all plans without
pruning during join enumeration.
Change-Id: Ie99c7310ebfca075f3211f32195fb2ad5df7c470
---
M
asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/OptimizationConfUtil.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/SqlppCompilationProvider.java
M
asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
M
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinEnum.java
M
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/PhysicalOptimizationConfig.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
8 files changed, 223 insertions(+), 137 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/50/17550/1
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/SqlppCompilationProvider.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/SqlppCompilationProvider.java
index f4ec7c4..13ae156 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/SqlppCompilationProvider.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/SqlppCompilationProvider.java
@@ -85,13 +85,13 @@
CompilerProperties.COMPILER_SUBPLAN_NESTEDPUSHDOWN_KEY,
CompilerProperties.COMPILER_ARRAYINDEX_KEY,
CompilerProperties.COMPILER_CBO_KEY,
CompilerProperties.COMPILER_CBO_TEST_KEY,
CompilerProperties.COMPILER_FORCE_JOIN_ORDER_KEY,
CompilerProperties.COMPILER_QUERY_PLAN_SHAPE_KEY,
- CompilerProperties.COMPILER_MIN_MEMORY_ALLOCATION_KEY,
CompilerProperties.COMPILER_COLUMN_FILTER_KEY,
- CompilerProperties.COMPILER_BATCH_LOOKUP_KEY,
FunctionUtil.IMPORT_PRIVATE_FUNCTIONS,
- FuzzyUtils.SIM_FUNCTION_PROP_NAME,
FuzzyUtils.SIM_THRESHOLD_PROP_NAME,
- StartFeedStatement.WAIT_FOR_COMPLETION,
FeedActivityDetails.FEED_POLICY_NAME,
- FeedActivityDetails.COLLECT_LOCATIONS,
SqlppQueryRewriter.INLINE_WITH_OPTION,
- SqlppExpressionToPlanTranslator.REWRITE_IN_AS_OR_OPTION,
"hash_merge", "output-record-type",
- DisjunctivePredicateToJoinRule.REWRITE_OR_AS_JOIN_OPTION,
+ CompilerProperties.COMPILER_CBO_PRUNING_KEY,
CompilerProperties.COMPILER_MIN_MEMORY_ALLOCATION_KEY,
+ CompilerProperties.COMPILER_COLUMN_FILTER_KEY,
CompilerProperties.COMPILER_BATCH_LOOKUP_KEY,
+ FunctionUtil.IMPORT_PRIVATE_FUNCTIONS,
FuzzyUtils.SIM_FUNCTION_PROP_NAME,
+ FuzzyUtils.SIM_THRESHOLD_PROP_NAME,
StartFeedStatement.WAIT_FOR_COMPLETION,
+ FeedActivityDetails.FEED_POLICY_NAME,
FeedActivityDetails.COLLECT_LOCATIONS,
+ SqlppQueryRewriter.INLINE_WITH_OPTION,
SqlppExpressionToPlanTranslator.REWRITE_IN_AS_OR_OPTION,
+ "hash_merge", "output-record-type",
DisjunctivePredicateToJoinRule.REWRITE_OR_AS_JOIN_OPTION,
SetAsterixPhysicalOperatorsRule.REWRITE_ATTEMPT_BATCH_ASSIGN,
EquivalenceClassUtils.REWRITE_INTERNAL_QUERYUID_PK,
SqlppQueryRewriter.SQL_COMPAT_OPTION));
}
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
index f2319c4..3a7736e 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
@@ -88,6 +88,8 @@
throws AlgebricksException {
boolean cboMode = this.getCBOMode(context);
boolean cboTestMode = this.getCBOTestMode(context);
+ boolean cboPruningMode = this.getCBOPruningMode(context);
+
if (!(cboMode || cboTestMode)) {
return false;
}
@@ -131,7 +133,7 @@
int numberOfFromTerms = emptyTupleAndDataSourceOps.size();
- joinEnum.initEnum((AbstractLogicalOperator) op, cboMode, cboTestMode,
numberOfFromTerms,
+ joinEnum.initEnum((AbstractLogicalOperator) op, cboMode, cboTestMode,
cboPruningMode, numberOfFromTerms,
emptyTupleAndDataSourceOps, joinLeafInputsHashMap, joinOps,
assignOps, context);
if (cboMode) {
@@ -225,6 +227,11 @@
return physOptConfig.getCBOTestMode();
}
+ private boolean getCBOPruningMode(IOptimizationContext context) {
+ PhysicalOptimizationConfig physOptConfig =
context.getPhysicalOptimizationConfig();
+ return physOptConfig.getCBOPruningMode();
+ }
+
/**
* Should not see any kind of joins here. store the emptyTupeSourceOp and
DataSource operators.
* Each leaf input will normally have both, but sometimes only
emptyTupeSourceOp will be present (in lists)
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinEnum.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinEnum.java
index 46a67e8..c033656 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinEnum.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinEnum.java
@@ -104,6 +104,7 @@
protected Stats stats;
private boolean cboMode;
private boolean cboTestMode;
+ protected boolean cboPruningMode;
protected int numberOfTerms;
private AbstractLogicalOperator op;
protected boolean connectedJoinGraph;
@@ -115,7 +116,8 @@
public JoinEnum() {
}
- protected void initEnum(AbstractLogicalOperator op, boolean cboMode,
boolean cboTestMode, int numberOfFromTerms,
+ protected void initEnum(AbstractLogicalOperator op, boolean cboMode,
boolean cboTestMode, boolean cboPruningMode,
+ int numberOfFromTerms,
List<Pair<EmptyTupleSourceOperator, DataSourceScanOperator>>
emptyTupleAndDataSourceOps,
Map<EmptyTupleSourceOperator, ILogicalOperator>
joinLeafInputsHashMap, List<ILogicalOperator> joinOps,
List<AssignOperator> assignOps, IOptimizationContext context) {
@@ -126,6 +128,7 @@
this.numberOfTerms = numberOfFromTerms;
this.cboMode = cboMode;
this.cboTestMode = cboTestMode;
+ this.cboPruningMode = cboPruningMode;
this.connectedJoinGraph = true;
this.optCtx = context;
this.emptyTupleAndDataSourceOps = emptyTupleAndDataSourceOps;
@@ -607,11 +610,11 @@
JoinNode jnIJ = jnArray[addPlansToThisJn];
jnIJ.jnArrayIndex = addPlansToThisJn;
jnIJ.addMultiDatasetPlans(jnI, jnJ);
- if (forceJoinOrderMode) {
+ if (forceJoinOrderMode && cboPruningMode) {
break;
}
}
- if (forceJoinOrderMode) {
+ if (forceJoinOrderMode && cboPruningMode) {
break;
}
}
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 fa2a144..cd2a776 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
@@ -383,7 +383,8 @@
opCost = joinEnum.getCostMethodsHandle().costFullScan(this);
totalCost = opCost;
- if (this.cheapestPlanIndex == PlanNode.NO_PLAN ||
opCost.costLT(this.cheapestPlanCost)) {
+ if (this.cheapestPlanIndex == PlanNode.NO_PLAN ||
opCost.costLT(this.cheapestPlanCost)
+ || !joinEnum.cboPruningMode) {
// for now just add one plan
PlanNode pn = new PlanNode(allPlans.size(), joinEnum);
pn.setJoinNode(this);
@@ -399,9 +400,10 @@
allPlans.add(pn);
this.planIndexesArray.add(pn.allPlansIndex);
- this.cheapestPlanCost = totalCost;
- this.cheapestPlanIndex = pn.allPlansIndex;
- return this.cheapestPlanIndex;
+ PlanNode cheapestPlan = findCheapestPlan();
+ this.cheapestPlanCost = cheapestPlan.totalCost;
+ this.cheapestPlanIndex = cheapestPlan.allPlansIndex;
+ return pn.allPlansIndex;
}
return PlanNode.NO_PLAN;
}
@@ -548,7 +550,7 @@
for (int i = 1; i < optionalIndexesInfo.size(); i++) {
newIdxCost = newIdxCost.costAdd(indexCosts.get(i)); // I0 +
I1; I0 + I1 + I2
currentCost = newIdxCost.costAdd(dataCosts.get(i)); // I0 + I1
+ D01; I0 + I1 + I2 + D012
- if (currentCost.costLT(opCost)) { // save this cost and try
adding one more index
+ if (currentCost.costLT(opCost) || !joinEnum.cboPruningMode) {
// save this cost and try adding one more index
opCost = currentCost;
} else {
// set the selectivites of the indexes not picked to be
-1.0, so we can set
@@ -562,14 +564,14 @@
}
// opCost is now the total cost of the indexes chosen along with the
associated data scan cost.
- if (opCost.costGT(this.cheapestPlanCost)) { // cheapest plan cost is
the data scan cost.
+ if (opCost.costGT(this.cheapestPlanCost) && joinEnum.cboPruningMode) {
// cheapest plan cost is the data scan cost.
for (int j = 0; j < optionalIndexesInfo.size(); j++) {
optionalIndexesInfo.get(j).second = -1.0; // remove all
indexes from consideration.
}
}
totalCost = opCost.costAdd(mandatoryIndexesCost); // cost of all the
indexes chosen
- if (opCost.costLT(this.cheapestPlanCost) ||
mandatoryIndexesInfo.size() > 0) {
+ if (opCost.costLT(this.cheapestPlanCost) ||
mandatoryIndexesInfo.size() > 0 || !joinEnum.cboPruningMode) {
PlanNode pn = new PlanNode(allPlans.size(), joinEnum);
pn.setJoinNode(this);
pn.setDatasetName(getDatasetNames().get(0));
@@ -584,8 +586,9 @@
allPlans.add(pn);
this.planIndexesArray.add(pn.allPlansIndex);
- this.cheapestPlanCost = totalCost; // in the presence of mandatory
indexes, this may not be the cheapest plan! But we have no choice!
- this.cheapestPlanIndex = pn.allPlansIndex;
+ PlanNode cheapestPlan = findCheapestPlan();
+ this.cheapestPlanCost = cheapestPlan.totalCost; // in the presence
of mandatory indexes, this may not be the cheapest plan! But we have no choice!
+ this.cheapestPlanIndex = cheapestPlan.allPlansIndex;
}
}
@@ -683,47 +686,45 @@
}
}
- private int buildHashJoinPlan(JoinNode leftJn, JoinNode rightJn,
ILogicalExpression hashJoinExpr,
- HashJoinExpressionAnnotation hintHashJoin) {
+ private int buildHashJoinPlan(JoinNode leftJn, JoinNode rightJn, PlanNode
leftPlan, PlanNode rightPlan,
+ ILogicalExpression hashJoinExpr, HashJoinExpressionAnnotation
hintHashJoin) {
List<PlanNode> allPlans = joinEnum.allPlans;
PlanNode pn;
ICost hjCost, leftExchangeCost, rightExchangeCost, childCosts,
totalCost;
this.leftJn = leftJn;
this.rightJn = rightJn;
- int leftPlan = leftJn.cheapestPlanIndex;
- int rightPlan = rightJn.cheapestPlanIndex;
if (hashJoinExpr == null || hashJoinExpr == ConstantExpression.TRUE) {
return PlanNode.NO_PLAN;
}
- if
(joinEnum.queryPlanShape.equals(AlgebricksConfig.QUERY_PLAN_SHAPE_LEFTDEEP)
- && !leftJn.IsBaseLevelJoinNode()) {
+ if
(joinEnum.queryPlanShape.equals(AlgebricksConfig.QUERY_PLAN_SHAPE_LEFTDEEP) &&
!leftJn.IsBaseLevelJoinNode()
+ && joinEnum.cboPruningMode) {
return PlanNode.NO_PLAN;
}
if
(joinEnum.queryPlanShape.equals(AlgebricksConfig.QUERY_PLAN_SHAPE_RIGHTDEEP)
- && !rightJn.IsBaseLevelJoinNode()) {
+ && !rightJn.IsBaseLevelJoinNode() && joinEnum.cboPruningMode) {
return PlanNode.NO_PLAN;
}
-
- if (rightJn.cardinality * rightJn.size <= leftJn.cardinality *
leftJn.size || hintHashJoin != null
- || joinEnum.forceJoinOrderMode
- ||
!joinEnum.queryPlanShape.equals(AlgebricksConfig.QUERY_PLAN_SHAPE_ZIGZAG)) {
+ boolean forceEnum = hintHashJoin != null || joinEnum.forceJoinOrderMode
+ ||
!joinEnum.queryPlanShape.equals(AlgebricksConfig.QUERY_PLAN_SHAPE_ZIGZAG)
+ || !joinEnum.cboPruningMode;
+ if (rightJn.cardinality * rightJn.size <= leftJn.cardinality *
leftJn.size || forceEnum) {
// We want to build with the smaller side.
hjCost = joinEnum.getCostMethodsHandle().costHashJoin(this);
leftExchangeCost =
joinEnum.getCostMethodsHandle().computeHJProbeExchangeCost(this);
rightExchangeCost =
joinEnum.getCostMethodsHandle().computeHJBuildExchangeCost(this);
- childCosts =
allPlans.get(leftPlan).totalCost.costAdd(allPlans.get(rightPlan).totalCost);
+ childCosts = allPlans.get(leftPlan.allPlansIndex).totalCost
+ .costAdd(allPlans.get(rightPlan.allPlansIndex).totalCost);
totalCost =
hjCost.costAdd(leftExchangeCost).costAdd(rightExchangeCost).costAdd(childCosts);
- if (this.cheapestPlanIndex == PlanNode.NO_PLAN ||
totalCost.costLT(this.cheapestPlanCost)
- || hintHashJoin != null) {
+ if (this.cheapestPlanIndex == PlanNode.NO_PLAN ||
totalCost.costLT(this.cheapestPlanCost) || forceEnum) {
pn = new PlanNode(allPlans.size(), joinEnum);
pn.setJoinNode(this);
pn.setLeftJoinIndex(leftJn.jnArrayIndex);
pn.setRightJoinIndex(rightJn.jnArrayIndex);
- pn.setLeftPlanIndex(leftPlan);
- pn.setRightPlanIndex(rightPlan);
+ pn.setLeftPlanIndex(leftPlan.allPlansIndex);
+ pn.setRightPlanIndex(rightPlan.allPlansIndex);
pn.joinOp = PlanNode.JoinMethod.HYBRID_HASH_JOIN; // need to
check that all the conditions have equality predicates ONLY.
pn.joinHint = hintHashJoin;
pn.side = HashJoinExpressionAnnotation.BuildSide.RIGHT;
@@ -734,6 +735,9 @@
pn.rightExchangeCost = rightExchangeCost;
allPlans.add(pn);
this.planIndexesArray.add(pn.allPlansIndex);
+ PlanNode cheapestPlan = findCheapestPlan();
+ this.cheapestPlanCost = cheapestPlan.totalCost;
+ this.cheapestPlanIndex = cheapestPlan.allPlansIndex;
return pn.allPlansIndex;
}
}
@@ -741,48 +745,47 @@
return PlanNode.NO_PLAN;
}
- private int buildBroadcastHashJoinPlan(JoinNode leftJn, JoinNode rightJn,
ILogicalExpression hashJoinExpr,
- BroadcastExpressionAnnotation hintBroadcastHashJoin) {
+ private int buildBroadcastHashJoinPlan(JoinNode leftJn, JoinNode rightJn,
PlanNode leftPlan, PlanNode rightPlan,
+ ILogicalExpression hashJoinExpr, BroadcastExpressionAnnotation
hintBroadcastHashJoin) {
List<PlanNode> allPlans = joinEnum.allPlans;
PlanNode pn;
ICost bcastHjCost, leftExchangeCost, rightExchangeCost, childCosts,
totalCost;
this.leftJn = leftJn;
this.rightJn = rightJn;
- int leftPlan = leftJn.cheapestPlanIndex;
- int rightPlan = rightJn.cheapestPlanIndex;
if (hashJoinExpr == null || hashJoinExpr == ConstantExpression.TRUE) {
return PlanNode.NO_PLAN;
}
- if
(joinEnum.queryPlanShape.equals(AlgebricksConfig.QUERY_PLAN_SHAPE_LEFTDEEP)
- && !leftJn.IsBaseLevelJoinNode()) {
+ if
(joinEnum.queryPlanShape.equals(AlgebricksConfig.QUERY_PLAN_SHAPE_LEFTDEEP) &&
!leftJn.IsBaseLevelJoinNode()
+ && joinEnum.cboPruningMode) {
return PlanNode.NO_PLAN;
}
if
(joinEnum.queryPlanShape.equals(AlgebricksConfig.QUERY_PLAN_SHAPE_RIGHTDEEP)
- && !rightJn.IsBaseLevelJoinNode()) {
+ && !rightJn.IsBaseLevelJoinNode() && joinEnum.cboPruningMode) {
return PlanNode.NO_PLAN;
}
- if (rightJn.cardinality * rightJn.size <= leftJn.cardinality *
leftJn.size || hintBroadcastHashJoin != null
- || joinEnum.forceJoinOrderMode
- ||
!joinEnum.queryPlanShape.equals(AlgebricksConfig.QUERY_PLAN_SHAPE_ZIGZAG)) {
+ boolean forceEnum = hintBroadcastHashJoin != null ||
joinEnum.forceJoinOrderMode
+ ||
!joinEnum.queryPlanShape.equals(AlgebricksConfig.QUERY_PLAN_SHAPE_ZIGZAG)
+ || !joinEnum.cboPruningMode;
+ if (rightJn.cardinality * rightJn.size <= leftJn.cardinality *
leftJn.size || forceEnum) {
// We want to broadcast and build with the smaller side.
bcastHjCost =
joinEnum.getCostMethodsHandle().costBroadcastHashJoin(this);
leftExchangeCost = joinEnum.getCostHandle().zeroCost();
rightExchangeCost =
joinEnum.getCostMethodsHandle().computeBHJBuildExchangeCost(this);
- childCosts =
allPlans.get(leftPlan).totalCost.costAdd(allPlans.get(rightPlan).totalCost);
+ childCosts = allPlans.get(leftPlan.allPlansIndex).totalCost
+ .costAdd(allPlans.get(rightPlan.allPlansIndex).totalCost);
totalCost =
bcastHjCost.costAdd(rightExchangeCost).costAdd(childCosts);
- if (this.cheapestPlanIndex == PlanNode.NO_PLAN ||
totalCost.costLT(this.cheapestPlanCost)
- || hintBroadcastHashJoin != null) {
+ if (this.cheapestPlanIndex == PlanNode.NO_PLAN ||
totalCost.costLT(this.cheapestPlanCost) || forceEnum) {
pn = new PlanNode(allPlans.size(), joinEnum);
pn.setJoinNode(this);
pn.setLeftJoinIndex(leftJn.jnArrayIndex);
pn.setRightJoinIndex(rightJn.jnArrayIndex);
- pn.setLeftPlanIndex(leftPlan);
- pn.setRightPlanIndex(rightPlan);
+ pn.setLeftPlanIndex(leftPlan.allPlansIndex);
+ pn.setRightPlanIndex(rightPlan.allPlansIndex);
pn.joinOp = PlanNode.JoinMethod.BROADCAST_HASH_JOIN; // need
to check that all the conditions have equality predicates ONLY.
pn.joinHint = hintBroadcastHashJoin;
pn.side = HashJoinExpressionAnnotation.BuildSide.RIGHT;
@@ -791,9 +794,11 @@
pn.totalCost = totalCost;
pn.leftExchangeCost = leftExchangeCost;
pn.rightExchangeCost = rightExchangeCost;
-
allPlans.add(pn);
this.planIndexesArray.add(pn.allPlansIndex);
+ PlanNode cheapestPlan = findCheapestPlan();
+ this.cheapestPlanCost = cheapestPlan.totalCost;
+ this.cheapestPlanIndex = cheapestPlan.allPlansIndex;
return pn.allPlansIndex;
}
}
@@ -801,8 +806,9 @@
return PlanNode.NO_PLAN;
}
- private int buildNLJoinPlan(JoinNode leftJn, JoinNode rightJn,
ILogicalExpression nestedLoopJoinExpr,
- IndexedNLJoinExpressionAnnotation hintNLJoin) throws
AlgebricksException {
+ private int buildNLJoinPlan(JoinNode leftJn, JoinNode rightJn, PlanNode
leftPlan, PlanNode rightPlan,
+ ILogicalExpression nestedLoopJoinExpr,
IndexedNLJoinExpressionAnnotation hintNLJoin)
+ throws AlgebricksException {
// Build a nested loops plan, first check if it is possible
// left right order must be preserved and right side should be a
single data set
List<PlanNode> allPlans = joinEnum.allPlans;
@@ -812,8 +818,6 @@
this.leftJn = leftJn;
this.rightJn = rightJn;
- int leftPlan = leftJn.cheapestPlanIndex;
- int rightPlan = rightJn.cheapestPlanIndex;
if (rightJn.jnArrayIndex > numberOfTerms) {
// right side consists of more than one table
return PlanNode.NO_PLAN; // nested loop plan not possible.
@@ -826,16 +830,16 @@
nljCost = joinEnum.getCostMethodsHandle().costIndexNLJoin(this);
leftExchangeCost =
joinEnum.getCostMethodsHandle().computeNLJOuterExchangeCost(this);
rightExchangeCost = joinEnum.getCostHandle().zeroCost();
- childCosts = allPlans.get(leftPlan).totalCost;
+ childCosts = allPlans.get(leftPlan.allPlansIndex).totalCost;
totalCost = nljCost.costAdd(leftExchangeCost).costAdd(childCosts);
- if (this.cheapestPlanIndex == PlanNode.NO_PLAN ||
totalCost.costLT(this.cheapestPlanCost)
- || hintNLJoin != null) {
+ boolean forceEnum = hintNLJoin != null || joinEnum.forceJoinOrderMode
|| !joinEnum.cboPruningMode;
+ if (this.cheapestPlanIndex == PlanNode.NO_PLAN ||
totalCost.costLT(this.cheapestPlanCost) || forceEnum) {
pn = new PlanNode(allPlans.size(), joinEnum);
pn.setJoinNode(this);
pn.setLeftJoinIndex(leftJn.jnArrayIndex);
pn.setRightJoinIndex(rightJn.jnArrayIndex);
- pn.setLeftPlanIndex(leftPlan);
- pn.setRightPlanIndex(rightPlan);
+ pn.setLeftPlanIndex(leftPlan.allPlansIndex);
+ pn.setRightPlanIndex(rightPlan.allPlansIndex);
pn.joinOp = PlanNode.JoinMethod.INDEX_NESTED_LOOP_JOIN;
pn.joinHint = hintNLJoin;
pn.joinExpr = nestedLoopJoinExpr; // save it so can be used to add
the NESTED annotation in getNewTree.
@@ -845,13 +849,16 @@
pn.rightExchangeCost = rightExchangeCost;
allPlans.add(pn);
this.planIndexesArray.add(pn.allPlansIndex);
+ PlanNode cheapestPlan = findCheapestPlan();
+ this.cheapestPlanCost = cheapestPlan.totalCost;
+ this.cheapestPlanIndex = cheapestPlan.allPlansIndex;
return pn.allPlansIndex;
}
return PlanNode.NO_PLAN;
}
- private int buildCPJoinPlan(JoinNode leftJn, JoinNode rightJn,
ILogicalExpression hashJoinExpr,
- ILogicalExpression nestedLoopJoinExpr) {
+ private int buildCPJoinPlan(JoinNode leftJn, JoinNode rightJn, PlanNode
leftPlan, PlanNode rightPlan,
+ ILogicalExpression hashJoinExpr, ILogicalExpression
nestedLoopJoinExpr) {
// Now build a cartesian product nested loops plan
List<PlanNode> allPlans = joinEnum.allPlans;
PlanNode pn;
@@ -859,8 +866,6 @@
this.leftJn = leftJn;
this.rightJn = rightJn;
- int leftPlan = leftJn.cheapestPlanIndex;
- int rightPlan = rightJn.cheapestPlanIndex;
ILogicalExpression cpJoinExpr = null;
List<Integer> newJoinConditions = this.getNewJoinConditionsOnly();
@@ -883,15 +888,17 @@
cpCost =
joinEnum.getCostMethodsHandle().costCartesianProductJoin(this);
leftExchangeCost = joinEnum.getCostHandle().zeroCost();
rightExchangeCost =
joinEnum.getCostMethodsHandle().computeCPRightExchangeCost(this);
- childCosts =
allPlans.get(leftPlan).totalCost.costAdd(allPlans.get(rightPlan).totalCost);
+ childCosts =
+
allPlans.get(leftPlan.allPlansIndex).totalCost.costAdd(allPlans.get(rightPlan.allPlansIndex).totalCost);
totalCost = cpCost.costAdd(rightExchangeCost).costAdd(childCosts);
- if (this.cheapestPlanIndex == PlanNode.NO_PLAN ||
totalCost.costLT(this.cheapestPlanCost)) {
+ boolean forceEnum = joinEnum.forceJoinOrderMode ||
!joinEnum.cboPruningMode;
+ if (this.cheapestPlanIndex == PlanNode.NO_PLAN ||
totalCost.costLT(this.cheapestPlanCost) || forceEnum) {
pn = new PlanNode(allPlans.size(), joinEnum);
pn.setJoinNode(this);
pn.setLeftJoinIndex(leftJn.jnArrayIndex);
pn.setRightJoinIndex(rightJn.jnArrayIndex);
- pn.setLeftPlanIndex(leftPlan);
- pn.setRightPlanIndex(rightPlan);
+ pn.setLeftPlanIndex(leftPlan.allPlansIndex);
+ pn.setRightPlanIndex(rightPlan.allPlansIndex);
pn.joinOp = PlanNode.JoinMethod.CARTESIAN_PRODUCT_JOIN;
pn.joinExpr = Objects.requireNonNullElse(cpJoinExpr,
ConstantExpression.TRUE);
pn.opCost = cpCost;
@@ -900,22 +907,44 @@
pn.rightExchangeCost = rightExchangeCost;
allPlans.add(pn);
this.planIndexesArray.add(pn.allPlansIndex);
+ PlanNode cheapestPlan = findCheapestPlan();
+ this.cheapestPlanCost = cheapestPlan.totalCost;
+ this.cheapestPlanIndex = cheapestPlan.allPlansIndex;
return pn.allPlansIndex;
}
return PlanNode.NO_PLAN;
}
- protected Pair<Integer, ICost> addMultiDatasetPlans(JoinNode leftJn,
JoinNode rightJn) throws AlgebricksException {
+ protected void addMultiDatasetPlans(JoinNode leftJn, JoinNode rightJn)
throws AlgebricksException {
+ PlanNode leftPlan, rightPlan;
+
+ if (joinEnum.cboPruningMode) {
+ leftPlan = leftJn.findCheapestPlan();
+ rightPlan = rightJn.findCheapestPlan();
+ addMultiDatasetPlans(leftJn, rightJn, leftPlan, rightPlan);
+ } else {
+ for (int leftPlanIndex : leftJn.planIndexesArray) {
+ leftPlan = joinEnum.allPlans.get(leftPlanIndex);
+ for (int rightPlanIndex : rightJn.planIndexesArray) {
+ rightPlan = joinEnum.allPlans.get(rightPlanIndex);
+ addMultiDatasetPlans(leftJn, rightJn, leftPlan, rightPlan);
+ }
+ }
+ }
+ }
+
+ protected void addMultiDatasetPlans(JoinNode leftJn, JoinNode rightJn,
PlanNode leftPlan, PlanNode rightPlan)
+ throws AlgebricksException {
this.leftJn = leftJn;
this.rightJn = rightJn;
ICost noJoinCost = joinEnum.getCostHandle().maxCost();
if (leftJn.planIndexesArray.size() == 0 ||
rightJn.planIndexesArray.size() == 0) {
- return new Pair<>(PlanNode.NO_PLAN, noJoinCost);
+ return;
}
if (this.cardinality >= Cost.MAX_CARD) {
- return new Pair<>(PlanNode.NO_PLAN, noJoinCost); // no card hint
available, so do not add this plan
+ return; // no card available, so do not add this plan
}
List<Integer> newJoinConditions = this.getNewJoinConditionsOnly(); //
these will be a subset of applicable join conditions.
@@ -925,13 +954,13 @@
if ((newJoinConditions.size() == 0) && joinEnum.connectedJoinGraph) {
// at least one plan must be there at each level as the graph is
fully connected.
if (leftJn.cardinality * rightJn.cardinality > 10000.0) {
- return new Pair<>(PlanNode.NO_PLAN, noJoinCost);
+ return;
}
}
double current_card = this.cardinality;
if (current_card >= Cost.MAX_CARD) {
- return new Pair<>(PlanNode.NO_PLAN, noJoinCost); // no card hint
available, so do not add this plan
+ return; // no card available, so do not add this plan
}
int hjPlan, commutativeHjPlan, bcastHjPlan, commutativeBcastHjPlan,
nljPlan, commutativeNljPlan, cpPlan,
@@ -944,7 +973,7 @@
IndexedNLJoinExpressionAnnotation hintNLJoin =
joinEnum.findNLJoinHint(newJoinConditions);
if (leftJn.cheapestPlanIndex == PlanNode.NO_PLAN ||
rightJn.cheapestPlanIndex == PlanNode.NO_PLAN) {
- return new Pair<>(PlanNode.NO_PLAN, noJoinCost);
+ return;
}
if (hintHashJoin != null) {
@@ -963,12 +992,13 @@
|| rightJn.aliases.contains(buildOrProbeObject)))
|| (probe &&
(leftJn.datasetNames.contains(buildOrProbeObject)
||
leftJn.aliases.contains(buildOrProbeObject)))) {
- hjPlan = buildHashJoinPlan(leftJn, rightJn, hashJoinExpr,
hintHashJoin);
+ hjPlan = buildHashJoinPlan(leftJn, rightJn, leftPlan,
rightPlan, hashJoinExpr, hintHashJoin);
} else if ((build &&
(leftJn.datasetNames.contains(buildOrProbeObject)
|| leftJn.aliases.contains(buildOrProbeObject)))
|| (probe &&
(rightJn.datasetNames.contains(buildOrProbeObject)
||
rightJn.aliases.contains(buildOrProbeObject)))) {
- commutativeHjPlan = buildHashJoinPlan(rightJn, leftJn,
hashJoinExpr, hintHashJoin);
+ commutativeHjPlan =
+ buildHashJoinPlan(rightJn, leftJn, rightPlan,
leftPlan, hashJoinExpr, hintHashJoin);
}
}
if (hjPlan == PlanNode.NO_PLAN && commutativeHjPlan ==
PlanNode.NO_PLAN) {
@@ -984,21 +1014,24 @@
(build ? "build " : "probe ") + "with
" + buildOrProbeObject));
}
}
- hjPlan = buildHashJoinPlan(leftJn, rightJn, hashJoinExpr,
null);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeHjPlan = buildHashJoinPlan(rightJn, leftJn,
hashJoinExpr, null);
+ hjPlan = buildHashJoinPlan(leftJn, rightJn, leftPlan,
rightPlan, hashJoinExpr, null);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeHjPlan = buildHashJoinPlan(rightJn, leftJn,
rightPlan, leftPlan, hashJoinExpr, null);
}
- bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
hashJoinExpr, null);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeBcastHjPlan =
buildBroadcastHashJoinPlan(rightJn, leftJn, hashJoinExpr, null);
+ bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
leftPlan, rightPlan, hashJoinExpr, null);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeBcastHjPlan =
+ buildBroadcastHashJoinPlan(rightJn, leftJn,
rightPlan, leftPlan, hashJoinExpr, null);
}
- nljPlan = buildNLJoinPlan(leftJn, rightJn, nestedLoopJoinExpr,
null);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeNljPlan = buildNLJoinPlan(rightJn, leftJn,
nestedLoopJoinExpr, null);
+ nljPlan = buildNLJoinPlan(leftJn, rightJn, leftPlan,
rightPlan, nestedLoopJoinExpr, null);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeNljPlan =
+ buildNLJoinPlan(rightJn, leftJn, rightPlan,
leftPlan, nestedLoopJoinExpr, null);
}
- cpPlan = buildCPJoinPlan(leftJn, rightJn, hashJoinExpr,
nestedLoopJoinExpr);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeCpPlan = buildCPJoinPlan(rightJn, leftJn,
hashJoinExpr, nestedLoopJoinExpr);
+ cpPlan = buildCPJoinPlan(leftJn, rightJn, leftPlan, rightPlan,
hashJoinExpr, nestedLoopJoinExpr);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeCpPlan =
+ buildCPJoinPlan(rightJn, leftJn, rightPlan,
leftPlan, hashJoinExpr, nestedLoopJoinExpr);
}
}
} else if (hintBroadcastHashJoin != null) {
@@ -1012,17 +1045,19 @@
if (validBroadcastObject) {
joinEnum.joinHints.put(hintBroadcastHashJoin, null);
if (rightJn.datasetNames.contains(broadcastObject) ||
rightJn.aliases.contains(broadcastObject)) {
- bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
hashJoinExpr, hintBroadcastHashJoin);
+ bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
leftPlan, rightPlan, hashJoinExpr,
+ hintBroadcastHashJoin);
} else if (leftJn.datasetNames.contains(broadcastObject) ||
leftJn.aliases.contains(broadcastObject)) {
- commutativeBcastHjPlan =
- buildBroadcastHashJoinPlan(rightJn, leftJn,
hashJoinExpr, hintBroadcastHashJoin);
+ commutativeBcastHjPlan =
buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan,
+ hashJoinExpr, hintBroadcastHashJoin);
}
} else if (broadcastObject == null) {
joinEnum.joinHints.put(hintBroadcastHashJoin, null);
- bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
hashJoinExpr, hintBroadcastHashJoin);
+ bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
leftPlan, rightPlan, hashJoinExpr,
+ hintBroadcastHashJoin);
if (!joinEnum.forceJoinOrderMode) {
- commutativeBcastHjPlan =
- buildBroadcastHashJoinPlan(rightJn, leftJn,
hashJoinExpr, hintBroadcastHashJoin);
+ commutativeBcastHjPlan =
buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan, leftPlan,
+ hashJoinExpr, hintBroadcastHashJoin);
}
}
if (bcastHjPlan == PlanNode.NO_PLAN && commutativeBcastHjPlan ==
PlanNode.NO_PLAN) {
@@ -1039,28 +1074,32 @@
}
}
- hjPlan = buildHashJoinPlan(leftJn, rightJn, hashJoinExpr,
null);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeHjPlan = buildHashJoinPlan(rightJn, leftJn,
hashJoinExpr, null);
+ hjPlan = buildHashJoinPlan(leftJn, rightJn, leftPlan,
rightPlan, hashJoinExpr, null);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeHjPlan = buildHashJoinPlan(rightJn, leftJn,
rightPlan, leftPlan, hashJoinExpr, null);
}
- bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
hashJoinExpr, null);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeBcastHjPlan =
buildBroadcastHashJoinPlan(rightJn, leftJn, hashJoinExpr, null);
+ bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
leftPlan, rightPlan, hashJoinExpr, null);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeBcastHjPlan =
+ buildBroadcastHashJoinPlan(rightJn, leftJn,
rightPlan, leftPlan, hashJoinExpr, null);
}
- nljPlan = buildNLJoinPlan(leftJn, rightJn, nestedLoopJoinExpr,
null);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeNljPlan = buildNLJoinPlan(rightJn, leftJn,
nestedLoopJoinExpr, null);
+ nljPlan = buildNLJoinPlan(leftJn, rightJn, leftPlan,
rightPlan, nestedLoopJoinExpr, null);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeNljPlan =
+ buildNLJoinPlan(rightJn, leftJn, rightPlan,
leftPlan, nestedLoopJoinExpr, null);
}
- cpPlan = buildCPJoinPlan(leftJn, rightJn, hashJoinExpr,
nestedLoopJoinExpr);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeCpPlan = buildCPJoinPlan(rightJn, leftJn,
hashJoinExpr, nestedLoopJoinExpr);
+ cpPlan = buildCPJoinPlan(leftJn, rightJn, leftPlan, rightPlan,
hashJoinExpr, nestedLoopJoinExpr);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeCpPlan =
+ buildCPJoinPlan(rightJn, leftJn, rightPlan,
leftPlan, hashJoinExpr, nestedLoopJoinExpr);
}
}
} else if (hintNLJoin != null) {
joinEnum.joinHints.put(hintNLJoin, null);
- nljPlan = buildNLJoinPlan(leftJn, rightJn, nestedLoopJoinExpr,
hintNLJoin);
+ nljPlan = buildNLJoinPlan(leftJn, rightJn, leftPlan, rightPlan,
nestedLoopJoinExpr, hintNLJoin);
if (!joinEnum.forceJoinOrderMode) {
- commutativeNljPlan = buildNLJoinPlan(rightJn, leftJn,
nestedLoopJoinExpr, hintNLJoin);
+ commutativeNljPlan =
+ buildNLJoinPlan(rightJn, leftJn, rightPlan, leftPlan,
nestedLoopJoinExpr, hintNLJoin);
}
if (nljPlan == PlanNode.NO_PLAN && commutativeNljPlan ==
PlanNode.NO_PLAN) {
// Hints are attached to predicates, so newJoinConditions
should not be empty, but adding the check to be safe.
@@ -1074,35 +1113,39 @@
ErrorCode.INAPPLICABLE_HINT, "index
nested loop join", "ignored"));
}
}
- hjPlan = buildHashJoinPlan(leftJn, rightJn, hashJoinExpr,
null);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeHjPlan = buildHashJoinPlan(rightJn, leftJn,
hashJoinExpr, null);
+ hjPlan = buildHashJoinPlan(leftJn, rightJn, leftPlan,
rightPlan, hashJoinExpr, null);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeHjPlan = buildHashJoinPlan(rightJn, leftJn,
rightPlan, leftPlan, hashJoinExpr, null);
}
- bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
hashJoinExpr, null);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeBcastHjPlan =
buildBroadcastHashJoinPlan(rightJn, leftJn, hashJoinExpr, null);
+ bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
leftPlan, rightPlan, hashJoinExpr, null);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeBcastHjPlan =
+ buildBroadcastHashJoinPlan(rightJn, leftJn,
rightPlan, leftPlan, hashJoinExpr, null);
}
- cpPlan = buildCPJoinPlan(leftJn, rightJn, hashJoinExpr,
nestedLoopJoinExpr);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeCpPlan = buildCPJoinPlan(rightJn, leftJn,
hashJoinExpr, nestedLoopJoinExpr);
+ cpPlan = buildCPJoinPlan(leftJn, rightJn, leftPlan, rightPlan,
hashJoinExpr, nestedLoopJoinExpr);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeCpPlan =
+ buildCPJoinPlan(rightJn, leftJn, rightPlan,
leftPlan, hashJoinExpr, nestedLoopJoinExpr);
}
}
} else {
- hjPlan = buildHashJoinPlan(leftJn, rightJn, hashJoinExpr, null);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeHjPlan = buildHashJoinPlan(rightJn, leftJn,
hashJoinExpr, null);
+ hjPlan = buildHashJoinPlan(leftJn, rightJn, leftPlan, rightPlan,
hashJoinExpr, null);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeHjPlan = buildHashJoinPlan(rightJn, leftJn,
rightPlan, leftPlan, hashJoinExpr, null);
}
- bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
hashJoinExpr, null);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeBcastHjPlan = buildBroadcastHashJoinPlan(rightJn,
leftJn, hashJoinExpr, null);
+ bcastHjPlan = buildBroadcastHashJoinPlan(leftJn, rightJn,
leftPlan, rightPlan, hashJoinExpr, null);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeBcastHjPlan =
+ buildBroadcastHashJoinPlan(rightJn, leftJn, rightPlan,
leftPlan, hashJoinExpr, null);
}
- nljPlan = buildNLJoinPlan(leftJn, rightJn, nestedLoopJoinExpr,
null);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeNljPlan = buildNLJoinPlan(rightJn, leftJn,
nestedLoopJoinExpr, null);
+ nljPlan = buildNLJoinPlan(leftJn, rightJn, leftPlan, rightPlan,
nestedLoopJoinExpr, null);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeNljPlan = buildNLJoinPlan(rightJn, leftJn,
rightPlan, leftPlan, nestedLoopJoinExpr, null);
}
- cpPlan = buildCPJoinPlan(leftJn, rightJn, hashJoinExpr,
nestedLoopJoinExpr);
- if (!joinEnum.forceJoinOrderMode) {
- commutativeCpPlan = buildCPJoinPlan(rightJn, leftJn,
hashJoinExpr, nestedLoopJoinExpr);
+ cpPlan = buildCPJoinPlan(leftJn, rightJn, leftPlan, rightPlan,
hashJoinExpr, nestedLoopJoinExpr);
+ if (!joinEnum.forceJoinOrderMode || !joinEnum.cboPruningMode) {
+ commutativeCpPlan =
+ buildCPJoinPlan(rightJn, leftJn, rightPlan, leftPlan,
hashJoinExpr, nestedLoopJoinExpr);
}
}
@@ -1110,21 +1153,22 @@
&& commutativeBcastHjPlan == PlanNode.NO_PLAN && nljPlan ==
PlanNode.NO_PLAN
&& commutativeNljPlan == PlanNode.NO_PLAN && cpPlan ==
PlanNode.NO_PLAN
&& commutativeCpPlan == PlanNode.NO_PLAN) {
- return new Pair<>(PlanNode.NO_PLAN, noJoinCost);
+ return;
}
//Reset as these might have changed when we tried the commutative
joins.
this.leftJn = leftJn;
this.rightJn = rightJn;
- PlanNode cheapestPlan = findCheapestPlan();
- this.cheapestPlanCost = cheapestPlan.totalCost;
- this.cheapestPlanIndex = cheapestPlan.allPlansIndex;
-
- return new Pair<>(this.cheapestPlanIndex, this.cheapestPlanCost);
+ return;
}
private PlanNode findCheapestPlan() {
+ if (!joinEnum.cboPruningMode) {
+ // If pruning is off, just return something.
+ return joinEnum.allPlans.get(planIndexesArray.get(0));
+ }
+
List<PlanNode> allPlans = joinEnum.allPlans;
ICost cheapestCost = joinEnum.getCostHandle().maxCost();
PlanNode cheapestPlanNode = null;
diff --git
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
index 01f9509..3136258 100644
---
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
+++
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
@@ -119,6 +119,10 @@
STRING,
AlgebricksConfig.QUERY_PLAN_SHAPE_DEFAULT,
"Set the mode for forcing the shape of the query plan"),
+ COMPILER_CBOPRUNING(
+ BOOLEAN,
+ AlgebricksConfig.CBO_PRUNING_DEFAULT,
+ "Set the mode for pruning during join and plan enumeration in
the optimizer"),
COMPILER_COLUMN_FILTER(
BOOLEAN,
AlgebricksConfig.COLUMN_FILTER_DEFAULT,
@@ -156,7 +160,7 @@
@Override
public boolean hidden() {
- return this == COMPILER_EXTERNALSCANMEMORY || this ==
COMPILER_CBOTEST;
+ return this == COMPILER_EXTERNALSCANMEMORY || this ==
COMPILER_CBOTEST || this == COMPILER_CBOPRUNING;
}
}
@@ -202,6 +206,8 @@
public static final String COMPILER_QUERY_PLAN_SHAPE_KEY =
Option.COMPILER_QUERYPLANSHAPE.ini();
+ public static final String COMPILER_CBO_PRUNING_KEY =
Option.COMPILER_CBOPRUNING.ini();
+
public static final String COMPILER_COLUMN_FILTER_KEY =
Option.COMPILER_COLUMN_FILTER.ini();
public static final int COMPILER_PARALLELISM_AS_STORAGE = 0;
@@ -303,6 +309,10 @@
return queryPlanShapeMode;
}
+ public boolean getCBOPruningMode() {
+ return accessor.getBoolean(Option.COMPILER_CBOPRUNING);
+ }
+
public boolean isColumnFilter() {
return accessor.getBoolean(Option.COMPILER_COLUMN_FILTER);
}
diff --git
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/OptimizationConfUtil.java
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/OptimizationConfUtil.java
index c103b50..a9ab8d6 100644
---
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/OptimizationConfUtil.java
+++
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/OptimizationConfUtil.java
@@ -87,6 +87,8 @@
compilerProperties.getForceJoinOrderMode());
String queryPlanShape = getString(querySpecificConfig,
CompilerProperties.COMPILER_QUERY_PLAN_SHAPE_KEY,
compilerProperties.getQueryPlanShapeMode());
+ boolean cboPruning = getBoolean(querySpecificConfig,
CompilerProperties.COMPILER_CBO_PRUNING_KEY,
+ compilerProperties.getCBOPruningMode());
boolean columnFilter = getBoolean(querySpecificConfig,
CompilerProperties.COMPILER_COLUMN_FILTER_KEY,
compilerProperties.isColumnFilter());
@@ -112,6 +114,7 @@
physOptConf.setCBOTestMode(cboTest);
physOptConf.setForceJoinOrderMode(forceJoinOrder);
physOptConf.setQueryPlanShapeMode(queryPlanShape);
+ physOptConf.setCBOPruningMode(cboPruning);
physOptConf.setColumnFilter(columnFilter);
return physOptConf;
}
diff --git
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
index 74f4447..91c2533 100644
---
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
+++
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
@@ -39,6 +39,7 @@
public static final boolean CBO_TEST_DEFAULT = false;
public static final boolean FORCE_JOIN_ORDER_DEFAULT = false;
public static final String QUERY_PLAN_SHAPE_ZIGZAG = "zigzag";
+ public static final boolean CBO_PRUNING_DEFAULT = true;
public static final String QUERY_PLAN_SHAPE_LEFTDEEP = "leftdeep";
public static final String QUERY_PLAN_SHAPE_RIGHTDEEP = "rightdeep";
public static final String QUERY_PLAN_SHAPE_DEFAULT =
QUERY_PLAN_SHAPE_ZIGZAG;
diff --git
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/PhysicalOptimizationConfig.java
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/PhysicalOptimizationConfig.java
index 3e51a80..b77e704 100644
---
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/PhysicalOptimizationConfig.java
+++
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/PhysicalOptimizationConfig.java
@@ -52,6 +52,7 @@
private static final String CBO_TEST = "CBO_TEST";
private static final String FORCE_JOIN_ORDER = "FORCE_JOIN_ORDER";
private static final String QUERY_PLAN_SHAPE = "QUERY_PLAN_SHAPE";
+ private static final String CBO_PRUNING = "CBO_PRUNING";
private static final String COLUMN_FILTER = "COLUMN_FILTER";
private final Properties properties = new Properties();
@@ -267,6 +268,10 @@
return queryPlanShapeMode;
}
+ public boolean getCBOPruningMode() {
+ return getBoolean(CBO_PRUNING, AlgebricksConfig.CBO_PRUNING_DEFAULT);
+ }
+
public void setCBOMode(boolean cbo) {
setBoolean(CBO, cbo);
}
@@ -283,6 +288,10 @@
setString(QUERY_PLAN_SHAPE, queryPlanShape);
}
+ public void setCBOPruningMode(boolean cboPruning) {
+ setBoolean(CBO_PRUNING, cboPruning);
+ }
+
public boolean isBatchLookupEnabled() {
return getBoolean(BATCH_LOOKUP, AlgebricksConfig.BATCH_LOOKUP_DEFAULT);
}
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17550
To unsubscribe, or for help writing mail filters, visit
https://asterix-gerrit.ics.uci.edu/settings
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: Ie99c7310ebfca075f3211f32195fb2ad5df7c470
Gerrit-Change-Number: 17550
Gerrit-PatchSet: 1
Gerrit-Owner: Vijay Sarathy <[email protected]>
Gerrit-MessageType: newchange