Abstracting algebricks rules out of AsterixDB.
Change-Id: Id184cc1cdfa738964705007ac42027d90b84cf58
Reviewed-on: https://asterix-gerrit.ics.uci.edu/353
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Preston Carman <prestonc@apache.org>
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
index 10ab856..a200874 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
@@ -19,8 +19,10 @@
import java.util.List;
import edu.uci.ics.asterix.optimizer.rules.AddEquivalenceClassForRecordConstructorRule;
+import edu.uci.ics.asterix.optimizer.rules.AsterixExtractFunctionsFromJoinConditionRule;
import edu.uci.ics.asterix.optimizer.rules.AsterixInlineVariablesRule;
import edu.uci.ics.asterix.optimizer.rules.AsterixIntroduceGroupByCombinerRule;
+import edu.uci.ics.asterix.optimizer.rules.AsterixMoveFreeVariableOperatorOutOfSubplanRule;
import edu.uci.ics.asterix.optimizer.rules.ByNameToByIndexFieldAccessRule;
import edu.uci.ics.asterix.optimizer.rules.CancelUnnestWithNestedListifyRule;
import edu.uci.ics.asterix.optimizer.rules.CheckFilterExpressionTypeRule;
@@ -28,7 +30,6 @@
import edu.uci.ics.asterix.optimizer.rules.CountVarToCountOneRule;
import edu.uci.ics.asterix.optimizer.rules.DisjunctivePredicateToJoinRule;
import edu.uci.ics.asterix.optimizer.rules.ExtractDistinctByExpressionsRule;
-import edu.uci.ics.asterix.optimizer.rules.ExtractFunctionsFromJoinConditionRule;
import edu.uci.ics.asterix.optimizer.rules.ExtractOrderExpressionsRule;
import edu.uci.ics.asterix.optimizer.rules.FeedScanCollectionToUnnest;
import edu.uci.ics.asterix.optimizer.rules.FuzzyEqRule;
@@ -96,7 +97,6 @@
import edu.uci.ics.hyracks.algebricks.rewriter.rules.IntroduceGroupByForSubplanRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.IntroduceProjectsRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.IsolateHyracksOperatorsRule;
-import edu.uci.ics.hyracks.algebricks.rewriter.rules.MoveFreeVariableOperatorOutOfSubplanRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.NestedSubplanToJoinRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.PullSelectOutOfEqJoin;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushAssignBelowUnionAllRule;
@@ -150,7 +150,7 @@
normalization.add(new ExtractGbyExpressionsRule());
normalization.add(new ExtractDistinctByExpressionsRule());
normalization.add(new ExtractOrderExpressionsRule());
- normalization.add(new MoveFreeVariableOperatorOutOfSubplanRule());
+ normalization.add(new AsterixMoveFreeVariableOperatorOutOfSubplanRule());
// IntroduceStaticTypeCastRule should go before
// IntroduceDynamicTypeCastRule to
@@ -186,7 +186,7 @@
condPushDownAndJoinInference.add(new IntroduceGroupByForSubplanRule());
condPushDownAndJoinInference.add(new SubplanOutOfGroupRule());
condPushDownAndJoinInference.add(new InsertOuterJoinRule());
- condPushDownAndJoinInference.add(new ExtractFunctionsFromJoinConditionRule());
+ condPushDownAndJoinInference.add(new AsterixExtractFunctionsFromJoinConditionRule());
condPushDownAndJoinInference.add(new RemoveRedundantVariablesRule());
condPushDownAndJoinInference.add(new AsterixInlineVariablesRule());
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixExtractFunctionsFromJoinConditionRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixExtractFunctionsFromJoinConditionRule.java
new file mode 100644
index 0000000..5457e55
--- /dev/null
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixExtractFunctionsFromJoinConditionRule.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.optimizer.rules;
+
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ExtractFunctionsFromJoinConditionRule;
+
+public class AsterixExtractFunctionsFromJoinConditionRule extends ExtractFunctionsFromJoinConditionRule {
+
+ @Override
+ protected boolean processArgumentsToFunction(FunctionIdentifier fi) {
+ return fi.equals(AsterixBuiltinFunctions.GET_ITEM);
+ }
+
+ @Override
+ protected boolean isComparisonFunction(FunctionIdentifier fi) {
+ return AsterixBuiltinFunctions.isSimilarityFunction(fi);
+ }
+
+}
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java
new file mode 100644
index 0000000..c42fa15
--- /dev/null
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.optimizer.rules;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.MoveFreeVariableOperatorOutOfSubplanRule;
+
+public class AsterixMoveFreeVariableOperatorOutOfSubplanRule extends MoveFreeVariableOperatorOutOfSubplanRule {
+
+ @Override
+ protected boolean movableOperator(LogicalOperatorTag operatorTag) {
+ return (operatorTag == LogicalOperatorTag.ASSIGN);
+ }
+}
\ No newline at end of file
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ExtractFunctionsFromJoinConditionRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ExtractFunctionsFromJoinConditionRule.java
deleted file mode 100644
index 37066f1..0000000
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ExtractFunctionsFromJoinConditionRule.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2009-2013 by The Regents of the University of California
- * Licensed 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 from
- *
- * 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 edu.uci.ics.asterix.optimizer.rules;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.lang3.mutable.Mutable;
-import org.apache.commons.lang3.mutable.MutableObject;
-
-import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
-import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
-import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
-
-/**
- * Factors out function expressions from each comparison function or similarity function in join condition by assigning them to a variables, and replacing the function expressions with references to those variables.
- * Examples:
- * Plan with function expressions in comparison or similarity condition of join expression. Generates one assign operator per extracted function expression.
- * Example
- * Before plan:
- * join ( eq( funcX($$1), funcX($$2) ) )
- * After plan:
- * join (eq($$3,$$4))
- * assign [$$4] <- [funcY($$2)]
- * assign [$$3] <- [funcX($$1)]
- */
-public class ExtractFunctionsFromJoinConditionRule implements IAlgebraicRewriteRule {
-
- @Override
- public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
- return false;
- }
-
- @Override
- public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
- throws AlgebricksException {
- AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
-
- if (op.getOperatorTag() != LogicalOperatorTag.INNERJOIN
- && op.getOperatorTag() != LogicalOperatorTag.LEFTOUTERJOIN) {
- return false;
- }
- AbstractBinaryJoinOperator joinOp = (AbstractBinaryJoinOperator) op;
- ILogicalExpression expr = joinOp.getCondition().getValue();
-
- return assignFunctionExpressions(joinOp, expr, context);
-
- }
-
- private boolean assignFunctionExpressions(AbstractLogicalOperator joinOp, ILogicalExpression expr,
- IOptimizationContext context) throws AlgebricksException {
- if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
- return false;
- }
- AbstractFunctionCallExpression fexp = (AbstractFunctionCallExpression) expr;
- FunctionIdentifier fi = fexp.getFunctionIdentifier();
-
- boolean modified = false;
- if (fi.equals(AlgebricksBuiltinFunctions.AND) || fi.equals(AlgebricksBuiltinFunctions.OR)
- || fi.equals(AsterixBuiltinFunctions.GET_ITEM)) {
- for (Mutable<ILogicalExpression> a : fexp.getArguments()) {
- if (assignFunctionExpressions(joinOp, a.getValue(), context)) {
- modified = true;
- }
- }
- return modified;
- } else if (AlgebricksBuiltinFunctions.isComparisonFunction(fi)
- || AsterixBuiltinFunctions.isSimilarityFunction(fi)) {
- for (Mutable<ILogicalExpression> exprRef : fexp.getArguments()) {
- if (exprRef.getValue().getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
- LogicalVariable newVar = context.newVar();
- AssignOperator newAssign = new AssignOperator(newVar, new MutableObject<ILogicalExpression>(exprRef
- .getValue().cloneExpression()));
- newAssign.setExecutionMode(joinOp.getExecutionMode());
-
- // Place assign below joinOp.
- List<LogicalVariable> used = new ArrayList<LogicalVariable>();
- VariableUtilities.getUsedVariables(newAssign, used);
-
- Mutable<ILogicalOperator> leftBranchRef = joinOp.getInputs().get(0);
- ILogicalOperator leftBranch = leftBranchRef.getValue();
- List<LogicalVariable> leftBranchVariables = new ArrayList<LogicalVariable>();
- VariableUtilities.getLiveVariables(leftBranch, leftBranchVariables);
- if (leftBranchVariables.containsAll(used)) {
- // place assign on left branch
- newAssign.getInputs().add(new MutableObject<ILogicalOperator>(leftBranch));
- leftBranchRef.setValue(newAssign);
- modified = true;
- } else {
- Mutable<ILogicalOperator> rightBranchRef = joinOp.getInputs().get(1);
- ILogicalOperator rightBranch = rightBranchRef.getValue();
- List<LogicalVariable> rightBranchVariables = new ArrayList<LogicalVariable>();
- VariableUtilities.getLiveVariables(rightBranch, rightBranchVariables);
- if (rightBranchVariables.containsAll(used)) {
- // place assign on right branch
- newAssign.getInputs().add(new MutableObject<ILogicalOperator>(rightBranch));
- rightBranchRef.setValue(newAssign);
- modified = true;
- }
- }
-
- if (modified) {
- // Replace original expr with variable reference.
- exprRef.setValue(new VariableReferenceExpression(newVar));
- context.computeAndSetTypeEnvironmentForOperator(newAssign);
- context.computeAndSetTypeEnvironmentForOperator(joinOp);
- }
- }
- }
- return modified;
- } else {
- return false;
- }
- }
-
-}