Steven Jacobs has uploaded a new change for review. https://asterix-gerrit.ics.uci.edu/1057
Change subject: Compile a plan that alligns with user query in the case of nonpure functions ...................................................................... Compile a plan that alligns with user query in the case of nonpure functions This fix makes it so that nonpure functions are called in the same place and with the same number of executions as specified by the user in the query. This also means that indexes cannot be used for queries that compare with a nonpure call that is made on a per-record basis. Added optimizer tests Change-Id: I2dec322b30835625430c06acd7626d902bada137 --- M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java A asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/global-datetime-no-index.aql A asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/global-datetime-use-index.aql A asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/local-datetime-ignore-index.aql A asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/local-datetime-no-index.aql M asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-02.plan A asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/global-datetime-no-index.plan A asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/global-datetime-use-index.plan A asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/local-datetime-ignore-index.plan A asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/local-datetime-no-index.plan M asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan M hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java M hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java M hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SetExecutionModeRule.java 19 files changed, 421 insertions(+), 119 deletions(-) git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/57/1057/1 diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java index ed1803d..6e41273 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java @@ -1,18 +1,18 @@ /* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * 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 + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ @@ -108,7 +108,7 @@ protected void fillSubTreeIndexExprs(OptimizableOperatorSubTree subTree, Map<IAccessMethod, AccessMethodAnalysisContext> analyzedAMs, IOptimizationContext context) - throws AlgebricksException { + throws AlgebricksException { Iterator<Map.Entry<IAccessMethod, AccessMethodAnalysisContext>> amIt = analyzedAMs.entrySet().iterator(); // Check applicability of indexes by access method type. while (amIt.hasNext()) { @@ -226,24 +226,24 @@ } boolean typeMatch = true; //Prune indexes based on field types - List<IAType> indexedTypes = new ArrayList<IAType>(); + List<IAType> matchedTypes = new ArrayList<IAType>(); //retrieve types of expressions joined/selected with an indexed field for (int j = 0; j < optFuncExpr.getNumLogicalVars(); j++) { if (j != exprAndVarIdx.second) { - indexedTypes.add(optFuncExpr.getFieldType(j)); + if (optFuncExpr.getFieldType(j) != null) { + matchedTypes.add(optFuncExpr.getFieldType(j)); + } } } - //add constants in case of select - if (indexedTypes.size() < 2 && optFuncExpr.getNumLogicalVars() == 1 - && optFuncExpr.getNumConstantAtRuntimeExpr() > 0) { - indexedTypes.add((IAType) AqlExpressionTypeComputer.INSTANCE.getType( + if (matchedTypes.size() < 2 && optFuncExpr.getNumLogicalVars() == 1) { + matchedTypes.add((IAType) AqlExpressionTypeComputer.INSTANCE.getType( optFuncExpr.getConstantAtRuntimeExpr(0), context.getMetadataProvider(), typeEnvironment)); } //infer type of logicalExpr based on index keyType - indexedTypes.add((IAType) AqlExpressionTypeComputer.INSTANCE.getType( + matchedTypes.add((IAType) AqlExpressionTypeComputer.INSTANCE.getType( optFuncExpr.getLogicalExpr(exprAndVarIdx.second), null, new IVariableTypeEnvironment() { @Override @@ -257,7 +257,7 @@ @Override public Object getVarType(LogicalVariable var, List<LogicalVariable> nonNullVariables, List<List<LogicalVariable>> correlatedNullableVariableLists) - throws AlgebricksException { + throws AlgebricksException { if (var.equals(optFuncExpr.getSourceVar(exprAndVarIdx.second))) { return keyType; } @@ -285,9 +285,9 @@ boolean jaccardSimilarity = optFuncExpr.getFuncExpr().getFunctionIdentifier().getName() .startsWith("similarity-jaccard-check"); - for (int j = 0; j < indexedTypes.size(); j++) { - for (int k = j + 1; k < indexedTypes.size(); k++) { - typeMatch &= isMatched(indexedTypes.get(j), indexedTypes.get(k), jaccardSimilarity); + for (int j = 0; j < matchedTypes.size(); j++) { + for (int k = j + 1; k < matchedTypes.size(); k++) { + typeMatch &= isMatched(matchedTypes.get(j), matchedTypes.get(k), jaccardSimilarity); } } @@ -435,7 +435,7 @@ protected boolean fillIndexExprs(List<Index> datasetIndexes, List<String> fieldName, IAType fieldType, IOptimizableFuncExpr optFuncExpr, int matchedFuncExprIndex, int varIdx, OptimizableOperatorSubTree matchedSubTree, AccessMethodAnalysisContext analysisCtx) - throws AlgebricksException { + throws AlgebricksException { List<Index> indexCandidates = new ArrayList<Index>(); // Add an index to the candidates if one of the indexed fields is // fieldName @@ -574,11 +574,12 @@ subTree.recordType, optVarIndex, optFuncExpr.getFuncExpr().getArguments().get(optVarIndex).getValue(), datasetRecordVar, subTree.metaRecordType, datasetMetaVar); + if (fieldName == null) { continue; } - IAType fieldType = (IAType) context.getOutputTypeEnvironment(assignOp) - .getType(optFuncExpr.getLogicalExpr(optVarIndex)); + + IAType fieldType = (IAType) context.getOutputTypeEnvironment(assignOp).getVarType(var); // Set the fieldName in the corresponding matched // function expression. optFuncExpr.setFieldName(optVarIndex, fieldName); @@ -595,7 +596,7 @@ private void matchVarsFromOptFuncExprToDataSourceScan(IOptimizableFuncExpr optFuncExpr, int optFuncExprIndex, List<Index> datasetIndexes, List<LogicalVariable> dsVarList, OptimizableOperatorSubTree subTree, AccessMethodAnalysisContext analysisCtx, IOptimizationContext context, boolean fromAdditionalDataSource) - throws AlgebricksException { + throws AlgebricksException { for (int varIndex = 0; varIndex < dsVarList.size(); varIndex++) { LogicalVariable var = dsVarList.get(varIndex); int funcVarIndex = optFuncExpr.findLogicalVar(var); @@ -666,7 +667,7 @@ protected List<String> getFieldNameFromSubTree(IOptimizableFuncExpr optFuncExpr, OptimizableOperatorSubTree subTree, int opIndex, int assignVarIndex, ARecordType recordType, int funcVarIndex, ILogicalExpression parentFuncExpr, LogicalVariable recordVar, ARecordType metaType, LogicalVariable metaVar) - throws AlgebricksException { + throws AlgebricksException { // Get expression corresponding to opVar at varIndex. AbstractLogicalExpression expr = null; AbstractFunctionCallExpression childFuncExpr = null; diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java index db2c627..80ee907 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java @@ -1,18 +1,18 @@ /* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * 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 + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ @@ -28,6 +28,7 @@ import org.apache.asterix.common.config.DatasetConfig.DatasetType; import org.apache.asterix.common.config.DatasetConfig.IndexType; import org.apache.asterix.common.exceptions.AsterixException; +import org.apache.asterix.dataflow.data.common.AqlExpressionTypeComputer; import org.apache.asterix.external.indexing.IndexingConstants; import org.apache.asterix.lang.common.util.FunctionUtil; import org.apache.asterix.metadata.declared.AqlSourceId; @@ -197,6 +198,7 @@ } else { return false; } + OptimizableFuncExpr newOptFuncExpr = new OptimizableFuncExpr(funcExpr, new LogicalVariable[] { fieldVar1, fieldVar2 }, new ILogicalExpression[0], new IAType[0]); for (IOptimizableFuncExpr optFuncExpr : analysisCtx.matchedFuncExprs) { @@ -303,19 +305,28 @@ } /** - * Returns the search key expression which feeds a secondary-index search. If we are optimizing a selection query then this method returns + * Returns the search key expression which feeds a secondary-index search. If we are optimizing a selection query + * then this method returns * the a ConstantExpression from the first constant value in the optimizable function expression. - * If we are optimizing a join, then this method returns the VariableReferenceExpression that should feed the secondary index probe. + * If we are optimizing a join, then this method returns the VariableReferenceExpression that should feed the + * secondary index probe. * * @throws AlgebricksException */ public static Pair<ILogicalExpression, Boolean> createSearchKeyExpr(IOptimizableFuncExpr optFuncExpr, OptimizableOperatorSubTree indexSubTree, OptimizableOperatorSubTree probeSubTree) - throws AlgebricksException { + throws AlgebricksException { if (probeSubTree == null) { // We are optimizing a selection query. Search key is a constant. // Type Checking and type promotion is done here IAType fieldType = optFuncExpr.getFieldType(0); + + if (optFuncExpr.getNumConstantAtRuntimeExpr() == 0) { + //We are looking at a nonpure case + //TODO: Right now we miss on type promotion for nonpure functions + return new Pair<ILogicalExpression, Boolean>( + new VariableReferenceExpression(optFuncExpr.getLogicalVar(1)), false); + } ILogicalExpression constantAtRuntimeExpression = null; AsterixConstantValue constantValue = null; @@ -399,7 +410,7 @@ public static ILogicalOperator createSecondaryIndexUnnestMap(Dataset dataset, ARecordType recordType, ARecordType metaRecordType, Index index, ILogicalOperator inputOp, AccessMethodJobGenParams jobGenParams, IOptimizationContext context, boolean outputPrimaryKeysOnly, boolean retainInput, boolean retainNull) - throws AlgebricksException { + throws AlgebricksException { // The job gen parameters are transferred to the actual job gen via the UnnestMapOperator's function arguments. ArrayList<Mutable<ILogicalExpression>> secondaryIndexFuncArgs = new ArrayList<Mutable<ILogicalExpression>>(); jobGenParams.writeToFuncArgs(secondaryIndexFuncArgs); diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java index 4dc7bf4..e7aa59b 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java @@ -1,18 +1,18 @@ /* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * 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 + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ @@ -102,6 +102,7 @@ public boolean analyzeFuncExprArgs(AbstractFunctionCallExpression funcExpr, List<AbstractLogicalOperator> assignsAndUnnests, AccessMethodAnalysisContext analysisCtx, IOptimizationContext context, IVariableTypeEnvironment typeEnvironment) throws AlgebricksException { + boolean matches = AccessMethodUtils.analyzeFuncExprArgsForOneConstAndVar(funcExpr, analysisCtx, context, typeEnvironment); if (!matches) { @@ -478,6 +479,18 @@ OperatorManipulationUtil.deepCopy(dataSourceOp.getInputs().get(0).getValue()))); assignConstantSearchKeys.setExecutionMode(dataSourceOp.getExecutionMode()); inputOp = assignConstantSearchKeys; + } else if (probeSubTree == null) { + //nonpure case + //Make sure that the nonpure function is unpartitioned + ILogicalOperator checkOp = dataSourceOp.getInputs().get(0).getValue(); + while (checkOp.getExecutionMode() != ExecutionMode.UNPARTITIONED) { + if (checkOp.getInputs().size() == 1) { + checkOp = checkOp.getInputs().get(0).getValue(); + } else { + return null; + } + } + inputOp = dataSourceOp.getInputs().get(0).getValue(); } else { // All index search keys are variables. inputOp = probeSubTree.root; @@ -688,6 +701,9 @@ private boolean probeIsOnLhs(IOptimizableFuncExpr optFuncExpr, OptimizableOperatorSubTree probeSubTree) { if (probeSubTree == null) { + if (optFuncExpr.getConstantAtRuntimeExpressions().length == 0) { + return optFuncExpr.getLogicalExpr(0) == null; + } // We are optimizing a selection query. Search key is a constant. Return true if constant is on lhs. return optFuncExpr.getFuncExpr().getArguments().get(0) == optFuncExpr.getConstantAtRuntimeExpr(0); } else { @@ -708,6 +724,10 @@ public boolean exprIsOptimizable(Index index, IOptimizableFuncExpr optFuncExpr) { // If we are optimizing a join, check for the indexed nested-loop join hint. if (optFuncExpr.getNumLogicalVars() == 2) { + if (optFuncExpr.getFieldType(0) == null || optFuncExpr.getFieldType(1) == null) { + //Nonpure nonjoin case + return true; + } if (!optFuncExpr.getFuncExpr().getAnnotations().containsKey(IndexedNLJoinExpressionAnnotation.INSTANCE)) { return false; } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java index b4f8c9f..fd3e4f4 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java @@ -1,18 +1,18 @@ /* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * 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 + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ @@ -76,4 +76,6 @@ IAType getConstantType(int index); void setConstantAtRuntimeExpr(int index, ILogicalExpression expr); + + ILogicalExpression[] getConstantAtRuntimeExpressions(); } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java index 2ecd504..4b4084b 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java @@ -1,18 +1,18 @@ /* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * 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 + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ @@ -143,6 +143,11 @@ } @Override + public ILogicalExpression[] getConstantAtRuntimeExpressions() { + return constantAtRuntimeExpressions; + } + + @Override public void setConstType(int index, IAType fieldType) { constantAtRuntimeExpressionTypes[index] = fieldType; } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java index d5a6f2b..7a849c8 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java @@ -1,18 +1,18 @@ /* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * 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 + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ @@ -39,6 +39,7 @@ 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.operators.logical.AbstractLogicalOperator; +import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode; import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractScanOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator; @@ -82,6 +83,8 @@ reset(); rootRef = subTreeOpRef; root = subTreeOpRef.getValue(); + boolean exitLoop = false; + boolean result = false; // Examine the op's children to match the expected patterns. AbstractLogicalOperator subTreeOp = (AbstractLogicalOperator) subTreeOpRef.getValue(); do { @@ -94,20 +97,33 @@ if (subTreeOp.getOperatorTag() != LogicalOperatorTag.ASSIGN && subTreeOp.getOperatorTag() != LogicalOperatorTag.UNNEST) { // Pattern may still match if we are looking for primary index matches as well. - return initializeDataSource(subTreeOpRef); + result = initializeDataSource(subTreeOpRef); + exitLoop = true; + if (!subTreeOp.getInputs().isEmpty()) { + subTreeOpRef = subTreeOp.getInputs().get(0); + subTreeOp = (AbstractLogicalOperator) subTreeOpRef.getValue(); + } } // Match (assign | unnest)+. while ((subTreeOp.getOperatorTag() == LogicalOperatorTag.ASSIGN - || subTreeOp.getOperatorTag() == LogicalOperatorTag.UNNEST)) { + || subTreeOp.getOperatorTag() == LogicalOperatorTag.UNNEST + || subTreeOp.getOperatorTag() == LogicalOperatorTag.EXCHANGE)) { if (!OperatorPropertiesUtil.isMovable(subTreeOp)) { return false; - } else { - assignsAndUnnestsRefs.add(subTreeOpRef); + } else if (subTreeOp.getOperatorTag() == LogicalOperatorTag.ASSIGN + || subTreeOp.getOperatorTag() == LogicalOperatorTag.UNNEST) { + if (subTreeOp.getExecutionMode() != ExecutionMode.UNPARTITIONED) { + //We won't need to move up the nonpure unpartitioned assigns + assignsAndUnnestsRefs.add(subTreeOpRef); + } assignsAndUnnests.add(subTreeOp); } subTreeOpRef = subTreeOp.getInputs().get(0); subTreeOp = (AbstractLogicalOperator) subTreeOpRef.getValue(); - }; + } + if (exitLoop) { + return result; + } } while (subTreeOp.getOperatorTag() == LogicalOperatorTag.SELECT); // Match data source (datasource scan or primary index search). diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/global-datetime-no-index.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/global-datetime-no-index.aql new file mode 100644 index 0000000..a637484 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/global-datetime-no-index.aql @@ -0,0 +1,35 @@ +/* + * 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. + */ + +drop dataverse channels if exists; +create dataverse channels; +use dataverse channels; + +create type userLocation as { + userId: int, + stamp: datetime +} + +create dataset Users(userLocation) +primary key userId; + +let $time := current-datetime() +for $result in dataset Users +where $result.stamp = $time +return $time \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/global-datetime-use-index.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/global-datetime-use-index.aql new file mode 100644 index 0000000..0a1948e --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/global-datetime-use-index.aql @@ -0,0 +1,35 @@ +/* + * 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. + */ + +drop dataverse channels if exists; +create dataverse channels; +use dataverse channels; + +create type userLocation as { + userId: int, + stamp: datetime +} + +create dataset Users(userLocation) +primary key stamp; + +let $time := current-datetime() +for $result in dataset Users +where $result.stamp = $time +return $result \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/local-datetime-ignore-index.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/local-datetime-ignore-index.aql new file mode 100644 index 0000000..939bac0 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/local-datetime-ignore-index.aql @@ -0,0 +1,35 @@ +/* + * 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. + */ + +drop dataverse channels if exists; +create dataverse channels; +use dataverse channels; + +create type userLocation as { + userId: int, + stamp: datetime +} + +create dataset Users(userLocation) +primary key stamp; + +for $result in dataset Users +let $time := current-datetime() +where $result.stamp = $time +return $result \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/local-datetime-no-index.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/local-datetime-no-index.aql new file mode 100644 index 0000000..36d6530 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/local-datetime-no-index.aql @@ -0,0 +1,35 @@ +/* + * 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. + */ + +drop dataverse channels if exists; +create dataverse channels; +use dataverse channels; + +create type userLocation as { + userId: int, + stamp: datetime +} + +create dataset Users(userLocation) +primary key userId; + +for $result in dataset Users +let $time := current-datetime() +where $result.stamp = $time +return $time \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-02.plan index a9e223a..a461461 100644 --- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-02.plan +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-02.plan @@ -1,8 +1,9 @@ -- DISTRIBUTE_RESULT |PARTITIONED| -- ONE_TO_ONE_EXCHANGE |PARTITIONED| -- STREAM_PROJECT |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- BTREE_SEARCH |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- ASSIGN |PARTITIONED| -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- ASSIGN |PARTITIONED| - -- EMPTY_TUPLE_SOURCE |PARTITIONED| \ No newline at end of file + -- DATASOURCE_SCAN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/global-datetime-no-index.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/global-datetime-no-index.plan new file mode 100644 index 0000000..82d3768 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/global-datetime-no-index.plan @@ -0,0 +1,10 @@ +-- DISTRIBUTE_RESULT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- DATASOURCE_SCAN |PARTITIONED| + -- BROADCAST_EXCHANGE |PARTITIONED| + -- ASSIGN |UNPARTITIONED| + -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/global-datetime-use-index.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/global-datetime-use-index.plan new file mode 100644 index 0000000..0b2ff34 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/global-datetime-use-index.plan @@ -0,0 +1,8 @@ +-- DISTRIBUTE_RESULT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- BTREE_SEARCH |PARTITIONED| + -- BROADCAST_EXCHANGE |PARTITIONED| + -- ASSIGN |UNPARTITIONED| + -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/local-datetime-ignore-index.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/local-datetime-ignore-index.plan new file mode 100644 index 0000000..a461461 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/local-datetime-ignore-index.plan @@ -0,0 +1,9 @@ +-- DISTRIBUTE_RESULT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- DATASOURCE_SCAN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/local-datetime-no-index.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/local-datetime-no-index.plan new file mode 100644 index 0000000..2d604a9 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nonpure/local-datetime-no-index.plan @@ -0,0 +1,10 @@ +-- DISTRIBUTE_RESULT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- DATASOURCE_SCAN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan index dd7b473..2ddb987 100644 --- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan @@ -20,14 +20,10 @@ -- ASSIGN |PARTITIONED| -- STREAM_PROJECT |PARTITIONED| -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- HYBRID_HASH_JOIN [$$15][$$14] |PARTITIONED| - -- HASH_PARTITION_EXCHANGE [$$15] |PARTITIONED| - -- ASSIGN |UNPARTITIONED| - -- UNNEST |UNPARTITIONED| - -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| + -- BTREE_SEARCH |PARTITIONED| -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- STREAM_PROJECT |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- DATASOURCE_SCAN |PARTITIONED| - -- ONE_TO_ONE_EXCHANGE |PARTITIONED| - -- EMPTY_TUPLE_SOURCE |PARTITIONED| + -- STABLE_SORT [$$15(ASC)] |PARTITIONED| + -- HASH_PARTITION_EXCHANGE [$$15] |PARTITIONED| + -- ASSIGN |UNPARTITIONED| + -- UNNEST |UNPARTITIONED| + -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| \ No newline at end of file diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java index 97aa853..dd11827 100644 --- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java +++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java @@ -1,18 +1,18 @@ /* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * 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 + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ @@ -25,20 +25,26 @@ import org.apache.commons.lang3.mutable.Mutable; import org.apache.commons.lang3.mutable.MutableObject; import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan; import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext; +import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag; import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag; 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.operators.logical.AbstractLogicalOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans; import org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator; +import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator; +import org.apache.hyracks.algebricks.core.algebra.operators.logical.ExchangeOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.OperatorDeepCopyVisitor; import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities; +import org.apache.hyracks.algebricks.core.algebra.operators.physical.BroadcastExchangePOperator; import org.apache.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl; import org.apache.hyracks.algebricks.core.algebra.typing.ITypingContext; @@ -78,7 +84,82 @@ return plan.getRoots().get(0).getValue(); } - public static boolean setOperatorMode(AbstractLogicalOperator op) { + //returns an integer value + //TODO: Make this better before the commit!!!! + public static int planIsConstantPlanIsNonPure(AbstractLogicalOperator op) { + if (op.getInputs().size() > 1) { + return -1; + } + int result = 0; + if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) { + AssignOperator asOp = (AssignOperator) op; + result = checkAssignForNonPures(asOp); + + if (result == -1) { + return result; + } + + if (op.getInputs().size() == 1) { + if (op.getInputs().get(0).getValue().getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) { + return result; + } else { + int subResult = planIsConstantPlanIsNonPure( + (AbstractLogicalOperator) op.getInputs().get(0).getValue()); + if (subResult == -1) { + result = -1; + } else if (subResult == 1 && result != -1) { + result = 1; + } + + } + } + + } + return result; + } + + //return 1 for constants + nonpure only, 0 for constants only, -1 otherwise + private static int checkAssignForNonPures(AssignOperator asOp) { + int result = 0; + for (Mutable<ILogicalExpression> expr : asOp.getExpressions()) { + if (expr.getValue().getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) { + int subResult = checkFunctionForNonPures((AbstractFunctionCallExpression) expr.getValue()); + if (subResult == -1) { + result = -1; + } else if (subResult == 1 && result != -1) { + result = 1; + } + } else if (expr.getValue().getExpressionTag() != LogicalExpressionTag.CONSTANT) { + return -1; + } + } + return result; + } + + private static int checkFunctionForNonPures(AbstractFunctionCallExpression fExpr) { + if (!fExpr.getFunctionInfo().isFunctional()) { + return 1; + + } else { + int result = 0; + for (Mutable<ILogicalExpression> expr : fExpr.getArguments()) { + if (expr.getValue().getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) { + int subResult = checkFunctionForNonPures((AbstractFunctionCallExpression) expr.getValue()); + if (subResult == -1) { + result = -1; + } else if (subResult == 1 && result != -1) { + result = 1; + } + } else if (expr.getValue().getExpressionTag() != LogicalExpressionTag.CONSTANT) { + return -1; + } + } + return result; + } + } + + public static boolean setOperatorMode(AbstractLogicalOperator op, IOptimizationContext context) + throws AlgebricksException { boolean change = false; switch (op.getOperatorTag()) { case DATASOURCESCAN: { @@ -89,6 +170,17 @@ if (child.getOperatorTag() == LogicalOperatorTag.EXCHANGE) { break; } + int nonPureCheck = planIsConstantPlanIsNonPure(child); + if (nonPureCheck == 1) { + ExchangeOperator exchg = new ExchangeOperator(); + exchg.setPhysicalOperator(new BroadcastExchangePOperator(null)); + exchg.setExecutionMode(AbstractLogicalOperator.ExecutionMode.PARTITIONED); + exchg.getInputs().add(currentOp.getInputs().get(0)); + currentOp.getInputs().clear(); + currentOp.getInputs().add(new MutableObject<ILogicalOperator>(exchg)); + context.computeAndSetTypeEnvironmentForOperator(exchg); + break; + } child.setExecutionMode(AbstractLogicalOperator.ExecutionMode.PARTITIONED); currentOp = child; } diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java index b4ade4c..2dacca4 100644 --- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java +++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java @@ -1,18 +1,18 @@ /* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * 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 + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ @@ -118,25 +118,6 @@ return false; } - /** - * An expression will be constant at runtime if it has: - * 1. A type - * 2. No free variables - * - * @param op - * @param funcExpr - * @param context - * @return whether a function is constant - * @throws AlgebricksException - */ - public static boolean functionIsConstantAtRuntime(AbstractFunctionCallExpression funcExpr) - throws AlgebricksException { - //make sure that there are no variables in the expression - Set<LogicalVariable> usedVariables = new HashSet<>(); - funcExpr.getUsedVariables(usedVariables); - return usedVariables.isEmpty(); - } - protected boolean inlineVariables(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException { AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue(); @@ -151,8 +132,7 @@ // Ignore functions that are either in the doNotInline set or are non-functional if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) { AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr; - if (doNotInlineFuncs.contains(funcExpr.getFunctionIdentifier()) || (!funcExpr.isFunctional() - && !InlineVariablesRule.functionIsConstantAtRuntime(funcExpr))) { + if (doNotInlineFuncs.contains(funcExpr.getFunctionIdentifier()) || !funcExpr.isFunctional()) { continue; } } diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SetExecutionModeRule.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SetExecutionModeRule.java index 63a33b5..13836bf 100644 --- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SetExecutionModeRule.java +++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SetExecutionModeRule.java @@ -1,25 +1,25 @@ /* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * 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 + * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.hyracks.algebricks.rewriter.rules; import org.apache.commons.lang3.mutable.Mutable; - +import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator; import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext; @@ -38,23 +38,24 @@ public class SetExecutionModeRule implements IAlgebraicRewriteRule { @Override - public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) { + public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) + throws AlgebricksException { AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue(); - boolean changed = OperatorManipulationUtil.setOperatorMode(op); + boolean changed = OperatorManipulationUtil.setOperatorMode(op, context); if (op.getExecutionMode() == AbstractLogicalOperator.ExecutionMode.UNPARTITIONED || op.getExecutionMode() == AbstractLogicalOperator.ExecutionMode.LOCAL) { return changed; } switch (op.getOperatorTag()) { - // case DISTINCT: - // case AGGREGATE: - // case GROUP: - // case ORDER: - // case INNERJOIN: - // case LEFTOUTERJOIN: { - // op.setExecutionMode(ExecutionMode.GLOBAL); - // return true; - // } + // case DISTINCT: + // case AGGREGATE: + // case GROUP: + // case ORDER: + // case INNERJOIN: + // case LEFTOUTERJOIN: { + // op.setExecutionMode(ExecutionMode.GLOBAL); + // return true; + // } case PARTITIONINGSPLIT: { throw new NotImplementedException(); -- To view, visit https://asterix-gerrit.ics.uci.edu/1057 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2dec322b30835625430c06acd7626d902bada137 Gerrit-PatchSet: 1 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Steven Jacobs <sjaco...@ucr.edu>