>From Michael Blow <[email protected]>: Michael Blow has submitted this change. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19317 )
Change subject: Merge branch 'gerrit/trinity' into 'gerrit/goldfish' ...................................................................... Merge branch 'gerrit/trinity' into 'gerrit/goldfish' Ext-ref: MB-64561 Change-Id: If535113f5438a9d32420ffd1d35d44a24a217b1e --- M asterixdb/asterix-app/src/test/java/org/apache/asterix/test/external_dataset/ExternalDatasetTestUtils.java A asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.3.plan M asterixdb/asterix-app/src/test/resources/runtimets/results/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.5.plan M asterixdb/asterix-app/src/test/resources/runtimets/results/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.3.plan M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/ExpectedSchemaBuilder.java A asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.5.plan D asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/ExpectedSchemaBuilder.java 8 files changed, 179 insertions(+), 324 deletions(-) Approvals: Michael Blow: Looks good to me, approved; Verified diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/ExpectedSchemaBuilder.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/ExpectedSchemaBuilder.java deleted file mode 100644 index b87cada..0000000 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/ExpectedSchemaBuilder.java +++ /dev/null @@ -1,288 +0,0 @@ -<<<<<<< HEAD (474bef Merge branch 'gerrit/trinity' into 'gerrit/goldfish') -======= -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.asterix.optimizer.rules.pushdown; - -import static org.apache.asterix.optimizer.rules.pushdown.ExpressionValueAccessPushdownVisitor.ARRAY_FUNCTIONS; -import static org.apache.asterix.optimizer.rules.pushdown.ExpressionValueAccessPushdownVisitor.SUPPORTED_FUNCTIONS; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.asterix.om.functions.BuiltinFunctions; -import org.apache.asterix.om.types.ARecordType; -import org.apache.asterix.om.utils.ConstantExpressionUtil; -import org.apache.asterix.optimizer.rules.pushdown.schema.AbstractComplexExpectedSchemaNode; -import org.apache.asterix.optimizer.rules.pushdown.schema.AnyExpectedSchemaNode; -import org.apache.asterix.optimizer.rules.pushdown.schema.ArrayExpectedSchemaNode; -import org.apache.asterix.optimizer.rules.pushdown.schema.ExpectedSchemaNodeType; -import org.apache.asterix.optimizer.rules.pushdown.schema.IExpectedSchemaNode; -import org.apache.asterix.optimizer.rules.pushdown.schema.ObjectExpectedSchemaNode; -import org.apache.asterix.optimizer.rules.pushdown.schema.RootExpectedSchemaNode; -import org.apache.asterix.optimizer.rules.pushdown.schema.UnionExpectedSchemaNode; -import org.apache.asterix.runtime.projection.DataProjectionInfo; -import org.apache.asterix.runtime.projection.FunctionCallInformation; -import org.apache.commons.lang3.mutable.Mutable; -import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; -import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag; -import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable; -import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression; -import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities; - -/** - * This class takes a value access expression and produces an expected schema (given the expression). - * Example: - * - $$t.getField("hashtags").getItem(0) - * We expect: - * 1- $$t is OBJECT - * 2- the output type of getField("hashtags") is ARRAY - * 3- the output type of getItem(0) is ANY node - */ -class ExpectedSchemaBuilder { - //Registered Variables - private final Map<LogicalVariable, IExpectedSchemaNode> varToNode; - private final ExpectedSchemaNodeToIATypeTranslatorVisitor typeBuilder; - - public ExpectedSchemaBuilder() { - varToNode = new HashMap<>(); - typeBuilder = new ExpectedSchemaNodeToIATypeTranslatorVisitor(); - } - - public DataProjectionInfo createProjectionInfo(LogicalVariable recordVariable) { - IExpectedSchemaNode rootNode = varToNode.get(recordVariable); - Map<String, FunctionCallInformation> sourceInformation = new HashMap<>(); - typeBuilder.reset(sourceInformation); - ARecordType recordType = (ARecordType) rootNode.accept(typeBuilder, null); - return new DataProjectionInfo(recordType, sourceInformation); - } - - public boolean setSchemaFromExpression(AbstractFunctionCallExpression expr, LogicalVariable producedVar) { - return buildExpectedSchemaNodes(expr, producedVar); - } - - public boolean setSchemaFromCalculatedExpression(AbstractFunctionCallExpression expr, LogicalVariable producedVar) { - //Parent always nested - AbstractComplexExpectedSchemaNode parent = (AbstractComplexExpectedSchemaNode) buildNestedNode(expr); - if (parent != null) { - IExpectedSchemaNode leaf = - new AnyExpectedSchemaNode(parent, expr.getSourceLocation(), expr.getFunctionIdentifier().getName()); - addChild(expr, parent, leaf); - if (producedVar != null) { - //Register the node if a variable is produced - varToNode.put(producedVar, leaf); - } - } - return parent != null; - } - - public void registerDataset(LogicalVariable recordVar, RootExpectedSchemaNode rootNode) { - varToNode.put(recordVar, rootNode); - } - - public void unregisterVariable(LogicalVariable variable) { - //Remove the node so no other expression will pushdown any expression in the future - IExpectedSchemaNode node = varToNode.remove(variable); - AbstractComplexExpectedSchemaNode parent = node.getParent(); - if (parent == null) { - //It is a root node. Request the entire record - varToNode.put(variable, RootExpectedSchemaNode.ALL_FIELDS_ROOT_NODE); - } else { - //It is a nested node. Replace the node to a LEAF node - node.replaceIfNeeded(ExpectedSchemaNodeType.ANY, parent.getSourceLocation(), parent.getFunctionName()); - } - } - - public boolean isVariableRegistered(LogicalVariable recordVar) { - return varToNode.containsKey(recordVar); - } - - public boolean containsRegisteredDatasets() { - return !varToNode.isEmpty(); - } - - private boolean buildExpectedSchemaNodes(ILogicalExpression expr, LogicalVariable producedVar) { - return buildNestedNodes(expr, producedVar); - } - - private boolean buildNestedNodes(ILogicalExpression expr, LogicalVariable producedVar) { - //The current node expression - boolean changed = false; - if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { - return false; - } - AbstractFunctionCallExpression myExpr = (AbstractFunctionCallExpression) expr; - if (!SUPPORTED_FUNCTIONS.contains(myExpr.getFunctionIdentifier()) || noArgsOrFirstArgIsConstant(myExpr)) { - // Check if the function consists of the Supported Functions - for (Mutable<ILogicalExpression> arg : myExpr.getArguments()) { - changed |= buildNestedNodes(arg.getValue(), producedVar); - } - return changed; - } - // if the child is not a function expression, then just one node. - if (BuiltinFunctions.ARRAY_STAR.equals(myExpr.getFunctionIdentifier()) - || BuiltinFunctions.SCAN_COLLECTION.equals(myExpr.getFunctionIdentifier())) { - // these supported function won't have second child - IExpectedSchemaNode expectedSchemaNode = buildNestedNode(expr); - if (expectedSchemaNode != null) { - changed |= setSchemaFromCalculatedExpression((AbstractFunctionCallExpression) expr, producedVar); - } - } else { - ILogicalExpression childExpr = myExpr.getArguments().get(1).getValue(); - if (childExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { - // must be a variable or constant - IExpectedSchemaNode expectedSchemaNode = buildNestedNode(expr); - if (expectedSchemaNode != null) { - changed |= setSchemaFromCalculatedExpression((AbstractFunctionCallExpression) expr, producedVar); - } - } else { - // as the childExpr is a function. - // if the function had been evaluated at compile time, it would have been - // evaluated at this stage of compilation. - // eg: field-access(t.r.p, substring("name",2,4)) - // this will be evaluated to field-access(t.r.p, "me") at compile time itself. - // since the execution reached this branch, this means the childExpr - // need to be evaluated at runtime, hence the childExpr should also be checked - // for possible pushdown. - // eg: field-access(t.r.p, substring(x.y.age_field, 0, 4)) - ILogicalExpression parentExpr = myExpr.getArguments().get(0).getValue(); - IExpectedSchemaNode parentExpectedNode = buildNestedNode(parentExpr); - if (parentExpectedNode != null) { - changed |= - setSchemaFromCalculatedExpression((AbstractFunctionCallExpression) parentExpr, producedVar); - } - changed |= buildNestedNodes(childExpr, producedVar); - } - } - return changed; - } - - private boolean noArgsOrFirstArgIsConstant(AbstractFunctionCallExpression myExpr) { - List<Mutable<ILogicalExpression>> args = myExpr.getArguments(); - return args.isEmpty() || args.get(0).getValue().getExpressionTag() == LogicalExpressionTag.CONSTANT; - } - - private IExpectedSchemaNode buildNestedNode(ILogicalExpression expr) { - //The current node expression - AbstractFunctionCallExpression myExpr = (AbstractFunctionCallExpression) expr; - if (!SUPPORTED_FUNCTIONS.contains(myExpr.getFunctionIdentifier())) { - //Return null if the function is not supported. - return null; - } - - //The parent expression - ILogicalExpression parentExpr = myExpr.getArguments().get(0).getValue(); - if (isVariable(parentExpr)) { - //A variable could be the record's originated from data-scan or an expression from assign - LogicalVariable sourceVar = VariableUtilities.getVariable(parentExpr); - return changeNodeForVariable(sourceVar, myExpr); - } - - //Recursively create the parent nodes. Parent is always a nested node - AbstractComplexExpectedSchemaNode newParent = (AbstractComplexExpectedSchemaNode) buildNestedNode(parentExpr); - //newParent could be null if the expression is not supported - if (newParent != null) { - //Parent expression must be a function call (as parent is a nested node) - AbstractFunctionCallExpression parentFuncExpr = (AbstractFunctionCallExpression) parentExpr; - //Get 'myType' as we will create the child type of the newParent - ExpectedSchemaNodeType myType = getExpectedNestedNodeType(myExpr); - /* - * Create 'myNode'. It is a nested node because the function is either getField() or supported array - * function - */ - AbstractComplexExpectedSchemaNode myNode = AbstractComplexExpectedSchemaNode.createNestedNode(myType, - newParent, myExpr.getSourceLocation(), myExpr.getFunctionIdentifier().getName()); - //Add myNode to the parent - addChild(parentFuncExpr, newParent, myNode); - return myNode; - } - return null; - } - - private IExpectedSchemaNode changeNodeForVariable(LogicalVariable sourceVar, - AbstractFunctionCallExpression myExpr) { - //Get the associated node with the sourceVar (if any) - IExpectedSchemaNode oldNode = varToNode.get(sourceVar); - if (oldNode == null) { - //Variable is not associated with a node. No pushdown is possible - return null; - } - //What is the expected type of the variable - ExpectedSchemaNodeType varExpectedType = getExpectedNestedNodeType(myExpr); - // Get the node associated with the variable (or change its type if needed). - IExpectedSchemaNode newNode = oldNode.replaceIfNeeded(varExpectedType, myExpr.getSourceLocation(), - myExpr.getFunctionIdentifier().getName()); - //Map the sourceVar to the node - varToNode.put(sourceVar, newNode); - return newNode; - } - - private void addChild(AbstractFunctionCallExpression parentExpr, AbstractComplexExpectedSchemaNode parent, - IExpectedSchemaNode child) { - switch (parent.getType()) { - case OBJECT: - handleObject(parentExpr, parent, child); - break; - case ARRAY: - handleArray(parent, child); - break; - case UNION: - handleUnion(parentExpr, parent, child); - break; - default: - throw new IllegalStateException("Node " + parent.getType() + " is not nested"); - - } - } - - private void handleObject(AbstractFunctionCallExpression parentExpr, AbstractComplexExpectedSchemaNode parent, - IExpectedSchemaNode child) { - ObjectExpectedSchemaNode objectNode = (ObjectExpectedSchemaNode) parent; - objectNode.addChild(ConstantExpressionUtil.getStringArgument(parentExpr, 1), child); - } - - private void handleArray(AbstractComplexExpectedSchemaNode parent, IExpectedSchemaNode child) { - ArrayExpectedSchemaNode arrayNode = (ArrayExpectedSchemaNode) parent; - arrayNode.addChild(child); - } - - private void handleUnion(AbstractFunctionCallExpression parentExpr, AbstractComplexExpectedSchemaNode parent, - IExpectedSchemaNode child) { - UnionExpectedSchemaNode unionNode = (UnionExpectedSchemaNode) parent; - ExpectedSchemaNodeType parentType = getExpectedNestedNodeType(parentExpr); - addChild(parentExpr, unionNode.getChild(parentType), child); - } - - private static ExpectedSchemaNodeType getExpectedNestedNodeType(AbstractFunctionCallExpression funcExpr) { - FunctionIdentifier fid = funcExpr.getFunctionIdentifier(); - if (BuiltinFunctions.FIELD_ACCESS_BY_NAME.equals(fid)) { - return ExpectedSchemaNodeType.OBJECT; - } else if (ARRAY_FUNCTIONS.contains(fid)) { - return ExpectedSchemaNodeType.ARRAY; - } - throw new IllegalStateException("Function " + fid + " should not be pushed down"); - } - - private static boolean isVariable(ILogicalExpression expr) { - return expr.getExpressionTag() == LogicalExpressionTag.VARIABLE; - } -} ->>>>>>> BRANCH (0ef025 Merge branch 'gerrit/neo' into 'gerrit/trinity') diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/ExpectedSchemaBuilder.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/ExpectedSchemaBuilder.java index e442d64..23da417 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/ExpectedSchemaBuilder.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/ExpectedSchemaBuilder.java @@ -56,6 +56,11 @@ public boolean setSchemaFromExpression(AbstractFunctionCallExpression expr, LogicalVariable producedVar, IVariableTypeEnvironment typeEnv) throws AlgebricksException { + return buildExpectedSchemaNodes(expr, producedVar, typeEnv); + } + + public boolean setSchemaFromCalculatedExpression(AbstractFunctionCallExpression expr, LogicalVariable producedVar, + IVariableTypeEnvironment typeEnv) throws AlgebricksException { //Parent always nested AbstractComplexExpectedSchemaNode parent = (AbstractComplexExpectedSchemaNode) buildNestedNode(expr, typeEnv); if (parent != null) { @@ -104,6 +109,71 @@ return varToNode.get(variable); } + private boolean buildExpectedSchemaNodes(ILogicalExpression expr, LogicalVariable producedVar, + IVariableTypeEnvironment typeEnv) throws AlgebricksException { + return buildNestedNodes(expr, producedVar, typeEnv); + } + + private boolean buildNestedNodes(ILogicalExpression expr, LogicalVariable producedVar, + IVariableTypeEnvironment typeEnv) throws AlgebricksException { + //The current node expression + boolean changed = false; + if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { + return false; + } + AbstractFunctionCallExpression myExpr = (AbstractFunctionCallExpression) expr; + if (!SUPPORTED_FUNCTIONS.contains(myExpr.getFunctionIdentifier()) || noArgsOrFirstArgIsConstant(myExpr)) { + // Check if the function consists of the Supported Functions + for (Mutable<ILogicalExpression> arg : myExpr.getArguments()) { + changed |= buildNestedNodes(arg.getValue(), producedVar, typeEnv); + } + return changed; + } + // if the child is not a function expression, then just one node. + if (BuiltinFunctions.ARRAY_STAR.equals(myExpr.getFunctionIdentifier()) + || BuiltinFunctions.SCAN_COLLECTION.equals(myExpr.getFunctionIdentifier())) { + // these supported function won't have second child + IExpectedSchemaNode expectedSchemaNode = buildNestedNode(expr, typeEnv); + if (expectedSchemaNode != null) { + changed |= + setSchemaFromCalculatedExpression((AbstractFunctionCallExpression) expr, producedVar, typeEnv); + } + } else { + ILogicalExpression childExpr = myExpr.getArguments().get(1).getValue(); + if (childExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { + // must be a variable or constant + IExpectedSchemaNode expectedSchemaNode = buildNestedNode(expr, typeEnv); + if (expectedSchemaNode != null) { + changed |= setSchemaFromCalculatedExpression((AbstractFunctionCallExpression) expr, producedVar, + typeEnv); + } + } else { + // as the childExpr is a function. + // if the function had been evaluated at compile time, it would have been + // evaluated at this stage of compilation. + // eg: field-access(t.r.p, substring("name",2,4)) + // this will be evaluated to field-access(t.r.p, "me") at compile time itself. + // since the execution reached this branch, this means the childExpr + // need to be evaluated at runtime, hence the childExpr should also be checked + // for possible pushdown. + // eg: field-access(t.r.p, substring(x.y.age_field, 0, 4)) + ILogicalExpression parentExpr = myExpr.getArguments().get(0).getValue(); + IExpectedSchemaNode parentExpectedNode = buildNestedNode(parentExpr, typeEnv); + if (parentExpectedNode != null) { + changed |= setSchemaFromCalculatedExpression((AbstractFunctionCallExpression) parentExpr, + producedVar, typeEnv); + } + changed |= buildNestedNodes(childExpr, producedVar, typeEnv); + } + } + return changed; + } + + private boolean noArgsOrFirstArgIsConstant(AbstractFunctionCallExpression myExpr) { + List<Mutable<ILogicalExpression>> args = myExpr.getArguments(); + return args.isEmpty() || args.get(0).getValue().getExpressionTag() == LogicalExpressionTag.CONSTANT; + } + private IExpectedSchemaNode buildNestedNode(ILogicalExpression expr, IVariableTypeEnvironment typeEnv) throws AlgebricksException { //The current node expression @@ -142,11 +212,6 @@ return null; } - private boolean noArgsOrFirstArgIsConstant(AbstractFunctionCallExpression myExpr) { - List<Mutable<ILogicalExpression>> args = myExpr.getArguments(); - return args.isEmpty() || args.get(0).getValue().getExpressionTag() == LogicalExpressionTag.CONSTANT; - } - private IExpectedSchemaNode changeNodeForVariable(LogicalVariable sourceVar, AbstractFunctionCallExpression parentExpression, ILogicalExpression expression) { //Get the associated node with the sourceVar (if any) diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/external_dataset/ExternalDatasetTestUtils.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/external_dataset/ExternalDatasetTestUtils.java index 92f0063..9e63c44 100644 --- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/external_dataset/ExternalDatasetTestUtils.java +++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/external_dataset/ExternalDatasetTestUtils.java @@ -395,7 +395,7 @@ loadData(generatedDataBasePath, "", "heterogeneous_1.parquet", definition, definitionSegment, false, false); loadData(generatedDataBasePath, "", "heterogeneous_2.parquet", definition, definitionSegment, false, false); loadData(generatedDataBasePath, "", "parquetTypes.parquet", definition, definitionSegment, false, false); -<<<<<<< HEAD (474bef Merge branch 'gerrit/trinity' into 'gerrit/goldfish') + loadData(generatedDataBasePath, "", "friends.parquet", definition, definitionSegment, false, false); Collection<File> files = IoUtil.getMatchingFiles(Paths.get(generatedDataBasePath + "/external-filter"), PARQUET_FILTER); @@ -471,9 +471,6 @@ size++; } LOGGER.info("Loaded {} files from {}", size, dataBasePath + File.separator + rootPath); -======= - loadData(generatedDataBasePath, "", "friends.parquet", definition, definitionSegment, false, false); ->>>>>>> BRANCH (0ef025 Merge branch 'gerrit/neo' into 'gerrit/trinity') } private static void loadData(String fileBasePath, String filePathSegment, String filename, String definition, diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.3.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.3.plan index c5f8436..1f2126c 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.3.plan +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.3.plan @@ -1,22 +1,22 @@ -distribute result [$$297] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1] +distribute result [$$311] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- DISTRIBUTE_RESULT |PARTITIONED| - exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1] + exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - project ([$$297]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1] + project ([$$311]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- STREAM_PROJECT |PARTITIONED| - assign [$$297] <- [{"id": $$331}] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1] + assign [$$311] <- [{"id": $$345}] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- ASSIGN |PARTITIONED| - select (not(is-null($$331))) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1] + select (not(is-null($$345))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- STREAM_SELECT |PARTITIONED| - project ([$$331]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 2.1] + project ([$$345]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- STREAM_PROJECT |PARTITIONED| - assign [$$331] <- [string-default-null($$s.getField("id"))] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 2.1] + assign [$$345] <- [string-default-null($$s.getField("id"))] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- ASSIGN |PARTITIONED| - project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 2.1] + project ([$$s]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- STREAM_PROJECT |PARTITIONED| - exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 2.1] + exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - data-scan []<-[$$300, $$s] <- test.dat1 [cardinality: 1000000.0, op-cost: 2.1, total-cost: 2.1] + data-scan []<-[$$314, $$s] <- test.dat1 [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- DATASOURCE_SCAN |PARTITIONED| exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- ONE_TO_ONE_EXCHANGE |PARTITIONED| diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.5.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.5.plan index 3029611..2f074b7 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.5.plan +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.5.plan @@ -1,39 +1,39 @@ -distribute result [$$303] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1] +distribute result [$$317] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- DISTRIBUTE_RESULT |PARTITIONED| - exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1] + exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - project ([$$303]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1] + project ([$$317]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- STREAM_PROJECT |PARTITIONED| - assign [$$303] <- [{"dat3": {"id": $$337, "a": string-default-null($$331), "d": int64-default-null($$304)}}] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1] + assign [$$317] <- [{"dat3": {"id": $$351, "a": string-default-null($$345), "d": int64-default-null($$318)}}] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- ASSIGN |PARTITIONED| - project ([$$337, $$331, $$304]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1] + project ([$$351, $$345, $$318]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- STREAM_PROJECT |PARTITIONED| - select (le($$304, get-item($$281, 0))) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1] + select (le($$318, get-item($$295, 0))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- STREAM_SELECT |PARTITIONED| - project ([$$337, $$331, $$304, $$281]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 2.1] + project ([$$351, $$345, $$318, $$295]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- STREAM_PROJECT |PARTITIONED| subplan { - aggregate [$$281] <- [listify($$316)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + aggregate [$$295] <- [listify($$330)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- AGGREGATE |LOCAL| - aggregate [$$316] <- [agg-sql-count(1)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + aggregate [$$330] <- [agg-sql-count(1)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- AGGREGATE |LOCAL| - unnest $$319 <- scan-collection($$329) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + unnest $$333 <- scan-collection($$343) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- UNNEST |LOCAL| nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- NESTED_TUPLE_SOURCE |LOCAL| - } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 2.1] + } [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- SUBPLAN |PARTITIONED| - select (not(is-null($$337))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + select (not(is-null($$351))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- STREAM_SELECT |PARTITIONED| - project ([$$337, $$331, $$304, $$329]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 2.1] + project ([$$351, $$345, $$318, $$343]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- STREAM_PROJECT |PARTITIONED| - assign [$$337, $$331, $$304, $$329] <- [string-default-null($$s.getField("id")), $$s.getField("a"), $$s.getField("d"), $$s.getField("e")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 2.1] + assign [$$351, $$345, $$318, $$343] <- [string-default-null($$s.getField("id")), $$s.getField("a"), $$s.getField("d"), $$s.getField("e")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- ASSIGN |PARTITIONED| - project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 2.1] + project ([$$s]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- STREAM_PROJECT |PARTITIONED| - exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 2.1] + exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - data-scan []<-[$$305, $$s] <- test.dat1 [cardinality: 1000000.0, op-cost: 2.1, total-cost: 2.1] + data-scan []<-[$$319, $$s] <- test.dat1 [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- DATASOURCE_SCAN |PARTITIONED| exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] -- ONE_TO_ONE_EXCHANGE |PARTITIONED| diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.3.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.3.plan new file mode 100644 index 0000000..dc43c42 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.3.plan @@ -0,0 +1,24 @@ +distribute result [$$311] [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] +-- DISTRIBUTE_RESULT |PARTITIONED| + exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + project ([$$311]) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- STREAM_PROJECT |PARTITIONED| + assign [$$311] <- [{"id": $$345}] [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- ASSIGN |PARTITIONED| + select (not(is-null($$345))) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- STREAM_SELECT |PARTITIONED| + project ([$$345]) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- STREAM_PROJECT |PARTITIONED| + assign [$$345] <- [string-default-null($$s.getField("id"))] [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- ASSIGN |PARTITIONED| + project ([$$s]) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- STREAM_PROJECT |PARTITIONED| + exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + data-scan []<-[$$314, $$s] <- test.dat1 [cardinality: 8.0, op-cost: 8.0, total-cost: 8.0] + -- DATASOURCE_SCAN |PARTITIONED| + exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- EMPTY_TUPLE_SOURCE |PARTITIONED| diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.5.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.5.plan new file mode 100644 index 0000000..b9dda19 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/subquery/query-ASTERIXDB-3538/query-ASTERIXDB-3538.5.plan @@ -0,0 +1,41 @@ +distribute result [$$317] [cardinality: 4.0, op-cost: 0.0, total-cost: 8.0] +-- DISTRIBUTE_RESULT |PARTITIONED| + exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 8.0] + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + project ([$$317]) [cardinality: 4.0, op-cost: 0.0, total-cost: 8.0] + -- STREAM_PROJECT |PARTITIONED| + assign [$$317] <- [{"dat3": {"id": $$351, "a": string-default-null($$345), "d": int64-default-null($$318)}}] [cardinality: 4.0, op-cost: 0.0, total-cost: 8.0] + -- ASSIGN |PARTITIONED| + project ([$$351, $$345, $$318]) [cardinality: 4.0, op-cost: 0.0, total-cost: 8.0] + -- STREAM_PROJECT |PARTITIONED| + select (le($$318, get-item($$295, 0))) [cardinality: 4.0, op-cost: 0.0, total-cost: 8.0] + -- STREAM_SELECT |PARTITIONED| + project ([$$351, $$345, $$318, $$295]) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- STREAM_PROJECT |PARTITIONED| + subplan { + aggregate [$$295] <- [listify($$330)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- AGGREGATE |LOCAL| + aggregate [$$330] <- [agg-sql-count(1)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- AGGREGATE |LOCAL| + unnest $$333 <- scan-collection($$343) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- UNNEST |LOCAL| + nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- NESTED_TUPLE_SOURCE |LOCAL| + } [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- SUBPLAN |PARTITIONED| + select (not(is-null($$351))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- STREAM_SELECT |PARTITIONED| + project ([$$351, $$345, $$318, $$343]) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- STREAM_PROJECT |PARTITIONED| + assign [$$351, $$345, $$318, $$343] <- [string-default-null($$s.getField("id")), $$s.getField("a"), $$s.getField("d"), $$s.getField("e")] [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- ASSIGN |PARTITIONED| + project ([$$s]) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- STREAM_PROJECT |PARTITIONED| + exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0] + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + data-scan []<-[$$319, $$s] <- test.dat1 [cardinality: 8.0, op-cost: 8.0, total-cost: 8.0] + -- DATASOURCE_SCAN |PARTITIONED| + exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0] + -- EMPTY_TUPLE_SOURCE |PARTITIONED| -- To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19317 To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-Project: asterixdb Gerrit-Branch: goldfish Gerrit-Change-Id: If535113f5438a9d32420ffd1d35d44a24a217b1e Gerrit-Change-Number: 19317 Gerrit-PatchSet: 3 Gerrit-Owner: Michael Blow <[email protected]> Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Michael Blow <[email protected]> Gerrit-CC: Anon. E. Moose #1000171 Gerrit-MessageType: merged
