This is an automated email from the ASF dual-hosted git repository.
alsuliman 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 b19f89ee42 [ASTERIXDB-3579][COMP] Unnest as many Unnest Operators as
possible
b19f89ee42 is described below
commit b19f89ee420ecd4da63286ad05fcb6a78e0e3cca
Author: murali4104 <[email protected]>
AuthorDate: Mon Mar 17 22:04:17 2025 -0700
[ASTERIXDB-3579][COMP] Unnest as many Unnest Operators as possible
Ext-ref:MB-65823
Change-Id: Ic1c305b6795ae312ff4d61948b32fb8a0974e7ba
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19526
Tested-by: Peeyush Gupta <[email protected]>
Integration-Tests: Jenkins <[email protected]>
Reviewed-by: <[email protected]>
Reviewed-by: Peeyush Gupta <[email protected]>
Reviewed-by: <[email protected]>
---
.../optimizer/rules/cbo/EnumerateJoinsRule.java | 102 +++++++++++++--------
1 file changed, 63 insertions(+), 39 deletions(-)
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 7a3b2995ee..148ace9ac8 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
@@ -91,6 +91,7 @@ public class EnumerateJoinsRule implements
IAlgebraicRewriteRule {
// for the Array UNNEST optimization. The main list is for each leafInput.
private List<List<List<ILogicalOperator>>> unnestOpsInfo;
+ private boolean arrayUnnestPossible = false;
// The Distinct operators for each DataSourceScan operator (if applicable)
private HashMap<DataSourceScanOperator, ILogicalOperator>
dataScanAndGroupByDistinctOps;
@@ -102,7 +103,6 @@ public class EnumerateJoinsRule implements
IAlgebraicRewriteRule {
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;
@@ -524,60 +524,84 @@ public class EnumerateJoinsRule implements
IAlgebraicRewriteRule {
private void findUnnestOps(ILogicalOperator leafInput) throws
AlgebricksException {
ILogicalOperator p = leafInput;
+ realLeafInputs.add(true); // every leafInput wil be real
List<ILogicalOperator> unnestOps = findAllUnnestOps(p); // how many
and which ones
+ if (unnestOps.isEmpty()) {
+ unnestOpsInfo.add(new ArrayList<>());
+ return;
+ }
+ List<List<ILogicalOperator>> bigList = new ArrayList<>();
+ int count = 0;
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;
}
+ count++; // found something unnestable
+ bigList.add(info.second);
}
- 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;
-
- 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);
- }
+ if (count > 0) {
+ arrayUnnestPossible = true;
+ unnestOpsInfo.add(bigList);
+ for (int i = 0; i < count; i++) {
+ unnestOpsInfo.add(new ArrayList<>()); // this is for the fake
leaf Input that will be added for every unnestOp
+ realLeafInputs.add(false);
+ }
+ }
+ }
+
+ Pair<Boolean, List<ILogicalOperator>>
findAllAssociatedAssingOps(ILogicalOperator leafInput,
+ UnnestOperator unnestOp) throws AlgebricksException {
+ Pair<Boolean, List<ILogicalOperator>> info = new Pair<>(true, new
ArrayList<>());
+ ILogicalOperator p = leafInput;
+
+ 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)