>From <[email protected]>:
[email protected] has uploaded this change for review. (
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19523 )
Change subject: [ASTERIXDB-3579][COMP] Unnest as many Unnest Operators as
possible
......................................................................
[ASTERIXDB-3579][COMP] Unnest as many Unnest Operators as possible
Change-Id: Id9ed2be5dd3d8fe405ef0d6fad9cf709a5954dd8
---
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
1 file changed, 72 insertions(+), 38 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/23/19523/1
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 7a3b299..9e96a23 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
@@ -102,7 +102,6 @@
private List<LogicalVariable> resultAndJoinVars = new ArrayList();
private final List<Boolean> realLeafInputs = new ArrayList();
- private boolean arrayUnnestPossible = true;
private int numberOfFromTerms;
private List<Triple<ILogicalOperator, ILogicalOperator,
List<ILogicalOperator>>> modifyUnnestInfo;
@@ -191,7 +190,7 @@
if (LOGGER.isTraceEnabled()) {
viewInPlan = new ALogicalPlanImpl(opRef).toString(); //useful when
debugging
}
- if (arrayUnnestPossible) {
+ if (UnnestPossible()) {
joinEnum.stats = new Stats(context, joinEnum);
if (cboMode) {
if (!doAllDataSourcesHaveSamples(leafInputs, context)) {
@@ -375,6 +374,15 @@
return false;
}
+ private boolean UnnestPossible() {
+ for (List<List<ILogicalOperator>> l : unnestOpsInfo) {
+ if (l.size() > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private boolean cleanUp() {
removeTrueFromAllLeafInputs();
return false;
@@ -524,60 +532,77 @@
private void findUnnestOps(ILogicalOperator leafInput) throws
AlgebricksException {
ILogicalOperator p = leafInput;
+ realLeafInputs.add(true);
List<ILogicalOperator> unnestOps = findAllUnnestOps(p); // how many
and which ones
+ if (unnestOps.isEmpty()) {
+ unnestOpsInfo.add(new ArrayList<>());
+ return;
+ }
+ List<List<ILogicalOperator>> bigList = new ArrayList<>();
for (ILogicalOperator op : unnestOps) {
UnnestOperator unnestOp = (UnnestOperator) op;
if (anyVarIsAJoinVar(unnestOp.getVariables())) {
unnestOpsInfo.add(new ArrayList<>()); // each leafInput must
have one entry
- arrayUnnestPossible = false; // If these variables participate
in join predicates, then unnestOps cannot be moved above joins
+ //not possible to unnest this unnest op. If these variables
participate in join predicates, then unnestOps cannot be moved above joins
+ continue;
}
+
+ Pair<Boolean, List<ILogicalOperator>> info =
findAllAssociatedAssingOps(p, unnestOp);
+ if (!info.first) {// something 'bad' happened, so this unnestOp
cannot be unnested
+ unnestOpsInfo.add(new ArrayList<>()); // each leafInput must
have one entry
+ //not possible to unnest this unnest op. If these variables
participate in join predicates, then unnestOps cannot be moved above joins
+ continue;
+ }
+ info.second.add(unnestOp); // the unnestOp will be the last (and
may be the only op)
+ bigList.add(info.second);
+ unnestOpsInfo.add(new ArrayList<>()); // this is for the fake leaf
Input that will be added
+ realLeafInputs.add(false);
}
- List<List<ILogicalOperator>> bigList = new ArrayList<>();
- realLeafInputs.add(true);
- for (int i = 0; i < unnestOps.size(); i++) {
- List<ILogicalOperator> ops = new ArrayList<>(); //Gather all
AssignsOps, if any, associated wth this unnestOp
- UnnestOperator unnestOp = (UnnestOperator) unnestOps.get(i);
+ }
- while (p != null && p.getOperatorTag() !=
LogicalOperatorTag.EMPTYTUPLESOURCE) {
- if (p.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
- AssignOperator aOp = (AssignOperator) p;
+ Pair<Boolean, List<ILogicalOperator>>
findAllAssociatedAssingOps(ILogicalOperator leafInput,
+ UnnestOperator unnestOp) throws AlgebricksException {
+ Pair<Boolean, List<ILogicalOperator>> info = new Pair<>(true, new
ArrayList<>());
+ ILogicalOperator p = leafInput;
- ILogicalExpression a =
aOp.getExpressions().get(0).getValue();
- if (a.getExpressionTag() ==
LogicalExpressionTag.FUNCTION_CALL) {
- AbstractFunctionCallExpression exp =
- (AbstractFunctionCallExpression)
aOp.getExpressions().get(0).getValue();
- if (exp.getKind() ==
AbstractFunctionCallExpression.FunctionKind.SCALAR) {
- ILogicalExpression lexp =
exp.getArguments().get(0).getValue();
- if (lexp.getExpressionTag() ==
LogicalExpressionTag.VARIABLE) {
- VariableReferenceExpression varRef =
(VariableReferenceExpression) lexp;
- LogicalVariable var =
varRef.getVariableReference();
- LogicalVariable unnestVar =
unnestOp.getVariables().get(0);
- if (unnestVar == var) {
- if ((anyVarIsAJoinVar(aOp.getVariables())
- ||
assignVarPresentInLeafInput(aOp, leafInput))) {
- unnestOpsInfo.add(new ArrayList<>());
- arrayUnnestPossible = false;
- } else {
- ops.add(aOp);
- }
+ List<ILogicalOperator> ops = new ArrayList<>(); //Gather all
AssignsOps, if any, associated wth this unnestOp
+ while (p != null && p.getOperatorTag() !=
LogicalOperatorTag.EMPTYTUPLESOURCE) {
+ if (p.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
+ AssignOperator aOp = (AssignOperator) p;
+
+ ILogicalExpression a = aOp.getExpressions().get(0).getValue();
+ if (a.getExpressionTag() ==
LogicalExpressionTag.FUNCTION_CALL) {
+ AbstractFunctionCallExpression exp =
+ (AbstractFunctionCallExpression)
aOp.getExpressions().get(0).getValue();
+ if (exp.getKind() ==
AbstractFunctionCallExpression.FunctionKind.SCALAR) {
+ ILogicalExpression lexp =
exp.getArguments().get(0).getValue();
+ if (lexp.getExpressionTag() ==
LogicalExpressionTag.VARIABLE) {
+ VariableReferenceExpression varRef =
(VariableReferenceExpression) lexp;
+ LogicalVariable var =
varRef.getVariableReference();
+ LogicalVariable unnestVar =
unnestOp.getVariables().get(0);
+ if (unnestVar == var) {
+ if ((anyVarIsAJoinVar(aOp.getVariables())
+ || assignVarPresentInLeafInput(aOp,
leafInput))) {
+ info.first = false;
+ return info;
+ } else {
+ ops.add(aOp);
}
}
}
}
}
- p = p.getInputs().get(0).getValue();
}
- ops.add(unnestOp); // the unnestOp will be the last (and may be
the only op)
- bigList.add(ops);
+ p = p.getInputs().get(0).getValue();
}
+ ops.add(unnestOp); // the unnestOp will be the last (and may be the
only op)
+ info.second = ops;
+
+ /*
unnestOpsInfo.add(bigList); // one for each LeafInput. If empty, means
that there are no array references in this leafInout
// also need to add some dummy entries for the fake leafInputs. Add as
many as unnestOps. This will make the code in setCardsAndSizes happy
-
- for (ILogicalOperator q : unnestOps) {
- bigList = new ArrayList<>();
- unnestOpsInfo.add(bigList);
- realLeafInputs.add(false);
- }
+ */
+ return info;
}
private boolean assignVarPresentInLeafInput(AssignOperator aOp,
ILogicalOperator leafInput)
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19523
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: Id9ed2be5dd3d8fe405ef0d6fad9cf709a5954dd8
Gerrit-Change-Number: 19523
Gerrit-PatchSet: 1
Gerrit-Owner: [email protected]
Gerrit-MessageType: newchange