>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

Reply via email to