>From Preetham Poluparthi <[email protected]>:
Preetham Poluparthi has uploaded this change for review. (
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20794?usp=email )
Change subject: [ASTERIXDB-3677][COMP] Add Inline IfMissing Rule
......................................................................
[ASTERIXDB-3677][COMP] Add Inline IfMissing Rule
- user model changes: no
- storage format changes: no
- interface changes: no
Ext-ref: MB-70076
Details: Inlining of functions like IfMissingOrNull when the types of their
arguments are known at compile time.
Change-Id: I557b9992d047c6fc53bddd5b90ff814bb678cedf
---
M
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
A
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InlineIfMissingFunctionRule.java
2 files changed, 127 insertions(+), 0 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/94/20794/1
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
index 3cea23f..6bb9535 100644
---
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
@@ -55,6 +55,7 @@
import org.apache.asterix.optimizer.rules.FuzzyEqRule;
import
org.apache.asterix.optimizer.rules.InjectTypeCastForFunctionArgumentsRule;
import org.apache.asterix.optimizer.rules.InjectTypeCastForUnionRule;
+import org.apache.asterix.optimizer.rules.InlineIfMissingFunctionRule;
import org.apache.asterix.optimizer.rules.InlineUnnestFunctionRule;
import org.apache.asterix.optimizer.rules.IntroduceAutogenerateIDRule;
import
org.apache.asterix.optimizer.rules.IntroduceDynamicTypeCastForExternalFunctionRule;
@@ -347,6 +348,7 @@
planCleanupRules.add(new
IntroduceDynamicTypeCastForExternalFunctionRule());
planCleanupRules.add(new RemoveUnusedAssignAndAggregateRule());
planCleanupRules.add(new RemoveCartesianProductWithEmptyBranchRule());
+ planCleanupRules.add(new InlineIfMissingFunctionRule());
planCleanupRules.add(new InjectTypeCastForFunctionArgumentsRule());
planCleanupRules.add(new InjectTypeCastForUnionRule());
// (1) RemoveOrReplaceDefaultNullCastRule and (2)
RemoveUnknownCheckForKnownTypesRule has to run in this order
diff --git
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InlineIfMissingFunctionRule.java
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InlineIfMissingFunctionRule.java
new file mode 100644
index 0000000..a45d3d3
--- /dev/null
+++
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InlineIfMissingFunctionRule.java
@@ -0,0 +1,125 @@
+/*
+ * 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;
+
+import java.util.List;
+
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.IAType;
+import org.apache.commons.lang3.mutable.Mutable;
+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.IOptimizationContext;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+import
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import
org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
+import
org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+
+public class InlineIfMissingFunctionRule implements IAlgebraicRewriteRule {
+
+ @Override
+ public boolean rewritePost(Mutable<ILogicalOperator> opRef,
IOptimizationContext context)
+ throws AlgebricksException {
+
+ ILogicalOperator op = opRef.getValue();
+ if (op.getInputs().isEmpty()) {
+ return false;
+ }
+ // Populates the latest type information.
+ context.computeAndSetTypeEnvironmentForOperator(op);
+ if (op.acceptExpressionTransform(exprRef -> inlineIfMissing(op,
exprRef, context))) {
+ // Generates the up-to-date type information.
+ context.computeAndSetTypeEnvironmentForOperator(op);
+ return true;
+ }
+ return false;
+ }
+
+ private static boolean inlineIfMissing(ILogicalOperator op,
Mutable<ILogicalExpression> exprRef,
+ IOptimizationContext context) throws AlgebricksException {
+
+ ILogicalExpression expr = exprRef.getValue();
+ if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
+ return false;
+ }
+ boolean rewritten = false;
+ AbstractFunctionCallExpression func = (AbstractFunctionCallExpression)
expr;
+
+ for (Mutable<ILogicalExpression> argRef : func.getArguments()) {
+ if (inlineIfMissing(op, argRef, context)) {
+ context.computeAndSetTypeEnvironmentForOperator(op);
+ rewritten = true;
+ }
+ }
+ rewritten |= rewriteFunction(op, exprRef, context);
+ return rewritten;
+ }
+
+ private static boolean rewriteFunction(ILogicalOperator op,
Mutable<ILogicalExpression> exprRef,
+ IOptimizationContext context) throws AlgebricksException {
+
+ ILogicalExpression expr = exprRef.getValue();
+ AbstractFunctionCallExpression func = (AbstractFunctionCallExpression)
expr;
+
+ if (func.getFunctionIdentifier() !=
BuiltinFunctions.IF_MISSING_OR_NULL) {
+ return false;
+ }
+
+ List<Mutable<ILogicalExpression>> argRefList = func.getArguments();
+ if (argRefList.isEmpty()) {
+ exprRef.setValue(ConstantExpression.NULL);
+ return true;
+ }
+
+ IVariableTypeEnvironment env = op.computeInputTypeEnvironment(context);
+
+ IAType type = (IAType) env.getType(argRefList.get(0).get());
+
+ if (type.getTypeTag() != ATypeTag.MISSING && type.getTypeTag() !=
ATypeTag.NULL
+ && type.getTypeTag() != ATypeTag.ANY) {
+ exprRef.setValue(argRefList.get(0).get());
+ return true;
+ }
+
+ List<Mutable<ILogicalExpression>> newArgsList = func.getArguments();
+
+ for (Mutable<ILogicalExpression> argRef : argRefList) {
+ ILogicalExpression argExpr = argRef.getValue();
+ IAType argType = (IAType) env.getType(argExpr);
+
+ if (argType.getTypeTag() == ATypeTag.ANY) {
+ newArgsList.add(argRef);
+ } else if (argType.getTypeTag() != ATypeTag.MISSING &&
argType.getTypeTag() != ATypeTag.NULL) {
+ newArgsList.add(argRef);
+ break;
+ }
+
+ }
+
+ argRefList.clear();
+ argRefList.addAll(newArgsList);
+ return true;
+
+ }
+
+}
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20794?usp=email
To unsubscribe, or for help writing mail filters, visit
https://asterix-gerrit.ics.uci.edu/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: asterixdb
Gerrit-Branch: trinity
Gerrit-Change-Id: I557b9992d047c6fc53bddd5b90ff814bb678cedf
Gerrit-Change-Number: 20794
Gerrit-PatchSet: 1
Gerrit-Owner: Preetham Poluparthi <[email protected]>