>From Peeyush Gupta <[email protected]>: Peeyush Gupta has submitted this change. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19526 )
Change subject: [ASTERIXDB-3579][COMP] Unnest as many Unnest Operators as possible ...................................................................... [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]> --- M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java 1 file changed, 78 insertions(+), 37 deletions(-) Approvals: [email protected]: Looks good to me, but someone else must approve Peeyush Gupta: Looks good to me, approved; Verified [email protected]: Looks good to me, but someone else must approve Anon. E. Moose #1000171: Jenkins: Verified 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..148ace9 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 @@ // 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 @@ 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 @@ 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); + } + 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); } } - 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/+/19526 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: Ic1c305b6795ae312ff4d61948b32fb8a0974e7ba Gerrit-Change-Number: 19526 Gerrit-PatchSet: 5 Gerrit-Owner: [email protected] Gerrit-Reviewer: Anon. E. Moose #1000171 Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Peeyush Gupta <[email protected]> Gerrit-Reviewer: [email protected] Gerrit-Reviewer: [email protected] Gerrit-MessageType: merged
