You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by im...@apache.org on 2015/08/25 18:44:22 UTC
[34/51] [partial] incubator-asterixdb git commit: Change folder
structure for Java repackage
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
new file mode 100644
index 0000000..a200874
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
@@ -0,0 +1,331 @@
+/*
+ * 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.base;
+
+import java.util.LinkedList;
+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;
+import edu.uci.ics.asterix.optimizer.rules.ConstantFoldingRule;
+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.ExtractOrderExpressionsRule;
+import edu.uci.ics.asterix.optimizer.rules.FeedScanCollectionToUnnest;
+import edu.uci.ics.asterix.optimizer.rules.FuzzyEqRule;
+import edu.uci.ics.asterix.optimizer.rules.IfElseToSwitchCaseFunctionRule;
+import edu.uci.ics.asterix.optimizer.rules.InlineUnnestFunctionRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceAutogenerateIDRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceDynamicTypeCastForExternalFunctionRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceDynamicTypeCastRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceEnforcedListTypeRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceInstantLockSearchCallbackRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceMaterializationForInsertWithSelfScanRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceRandomPartitioningFeedComputationRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceRapidFrameFlushProjectAssignRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceSecondaryIndexInsertDeleteRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceStaticTypeCastForInsertRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceUnionRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceUnnestForCollectionToSequenceRule;
+import edu.uci.ics.asterix.optimizer.rules.LoadRecordFieldsRule;
+import edu.uci.ics.asterix.optimizer.rules.NestGroupByRule;
+import edu.uci.ics.asterix.optimizer.rules.PushAggFuncIntoStandaloneAggregateRule;
+import edu.uci.ics.asterix.optimizer.rules.PushAggregateIntoGroupbyRule;
+import edu.uci.ics.asterix.optimizer.rules.PushFieldAccessRule;
+import edu.uci.ics.asterix.optimizer.rules.PushGroupByThroughProduct;
+import edu.uci.ics.asterix.optimizer.rules.PushProperJoinThroughProduct;
+import edu.uci.ics.asterix.optimizer.rules.PushSimilarityFunctionsBelowJoin;
+import edu.uci.ics.asterix.optimizer.rules.RemoveRedundantListifyRule;
+import edu.uci.ics.asterix.optimizer.rules.RemoveRedundantSelectRule;
+import edu.uci.ics.asterix.optimizer.rules.RemoveSortInFeedIngestionRule;
+import edu.uci.ics.asterix.optimizer.rules.RemoveUnusedOneToOneEquiJoinRule;
+import edu.uci.ics.asterix.optimizer.rules.ReplaceSinkOpWithCommitOpRule;
+import edu.uci.ics.asterix.optimizer.rules.SetAsterixPhysicalOperatorsRule;
+import edu.uci.ics.asterix.optimizer.rules.SetClosedRecordConstructorsRule;
+import edu.uci.ics.asterix.optimizer.rules.SimilarityCheckRule;
+import edu.uci.ics.asterix.optimizer.rules.SweepIllegalNonfunctionalFunctions;
+import edu.uci.ics.asterix.optimizer.rules.UnnestToDataScanRule;
+import edu.uci.ics.asterix.optimizer.rules.am.IntroduceJoinAccessMethodRule;
+import edu.uci.ics.asterix.optimizer.rules.am.IntroduceLSMComponentFilterRule;
+import edu.uci.ics.asterix.optimizer.rules.am.IntroduceSelectAccessMethodRule;
+import edu.uci.ics.asterix.optimizer.rules.temporal.TranslateIntervalExpressionRule;
+import edu.uci.ics.hyracks.algebricks.core.rewriter.base.HeuristicOptimizer;
+import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.BreakSelectIntoConjunctsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ComplexJoinInferenceRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ComplexUnnestToProductRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ConsolidateAssignsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ConsolidateSelectsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.CopyLimitDownRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.EliminateGroupByEmptyKeyRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.EliminateSubplanRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.EliminateSubplanWithInputCardinalityOneRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.EnforceOrderByAfterSubplan;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.EnforceStructuralPropertiesRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ExtractCommonExpressionsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ExtractCommonOperatorsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ExtractGbyExpressionsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.FactorRedundantGroupAndDecorVarsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.InferTypesRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.InlineAssignIntoAggregateRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.InlineSingleReferenceVariablesRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.InsertOuterJoinRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.InsertProjectBeforeUnionRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.IntroHashPartitionMergeExchange;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.IntroJoinInsideSubplanRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.IntroduceAggregateCombinerRule;
+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.NestedSubplanToJoinRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PullSelectOutOfEqJoin;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushAssignBelowUnionAllRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushGroupByIntoSortRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushMapOperatorDownThroughProductRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushNestedOrderByUnderPreSortedGroupByRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushProjectDownRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushSelectDownRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushSelectIntoJoinRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushSubplanIntoGroupByRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushSubplanWithAggregateDownThroughProductRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushUnnestDownThroughUnionRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.ReinferAllTypesRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.RemoveRedundantGroupByDecorVars;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.RemoveRedundantVariablesRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.RemoveUnusedAssignAndAggregateRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.SetAlgebricksPhysicalOperatorsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.SetExecutionModeRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.SimpleUnnestToProductRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.SubplanOutOfGroupRule;
+
+public final class RuleCollections {
+
+ public final static List<IAlgebraicRewriteRule> buildInitialTranslationRuleCollection() {
+ List<IAlgebraicRewriteRule> typeInfer = new LinkedList<IAlgebraicRewriteRule>();
+ typeInfer.add(new TranslateIntervalExpressionRule());
+ return typeInfer;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildTypeInferenceRuleCollection() {
+ List<IAlgebraicRewriteRule> typeInfer = new LinkedList<IAlgebraicRewriteRule>();
+ typeInfer.add(new InlineUnnestFunctionRule());
+ typeInfer.add(new InferTypesRule());
+ typeInfer.add(new CheckFilterExpressionTypeRule());
+ return typeInfer;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildAutogenerateIDRuleCollection() {
+ List<IAlgebraicRewriteRule> autogen = new LinkedList<>();
+ autogen.add(new IntroduceAutogenerateIDRule());
+ return autogen;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildNormalizationRuleCollection() {
+ List<IAlgebraicRewriteRule> normalization = new LinkedList<IAlgebraicRewriteRule>();
+ normalization.add(new IntroduceUnnestForCollectionToSequenceRule());
+ normalization.add(new EliminateSubplanRule());
+ normalization.add(new EnforceOrderByAfterSubplan());
+ normalization.add(new PushAggFuncIntoStandaloneAggregateRule());
+ normalization.add(new BreakSelectIntoConjunctsRule());
+ normalization.add(new ExtractGbyExpressionsRule());
+ normalization.add(new ExtractDistinctByExpressionsRule());
+ normalization.add(new ExtractOrderExpressionsRule());
+ normalization.add(new AsterixMoveFreeVariableOperatorOutOfSubplanRule());
+
+ // IntroduceStaticTypeCastRule should go before
+ // IntroduceDynamicTypeCastRule to
+ // avoid unnecessary dynamic casting
+ normalization.add(new IntroduceStaticTypeCastForInsertRule());
+ normalization.add(new IntroduceDynamicTypeCastRule());
+ normalization.add(new IntroduceDynamicTypeCastForExternalFunctionRule());
+ normalization.add(new IntroduceEnforcedListTypeRule());
+ normalization.add(new ExtractCommonExpressionsRule());
+ normalization.add(new ConstantFoldingRule());
+ normalization.add(new RemoveRedundantSelectRule());
+ normalization.add(new UnnestToDataScanRule());
+ normalization.add(new IfElseToSwitchCaseFunctionRule());
+ normalization.add(new FuzzyEqRule());
+ normalization.add(new SimilarityCheckRule());
+ return normalization;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildCondPushDownAndJoinInferenceRuleCollection() {
+ List<IAlgebraicRewriteRule> condPushDownAndJoinInference = new LinkedList<IAlgebraicRewriteRule>();
+
+ condPushDownAndJoinInference.add(new PushSelectDownRule());
+ condPushDownAndJoinInference.add(new RemoveRedundantListifyRule());
+ condPushDownAndJoinInference.add(new CancelUnnestWithNestedListifyRule());
+ condPushDownAndJoinInference.add(new SimpleUnnestToProductRule());
+ condPushDownAndJoinInference.add(new ComplexUnnestToProductRule());
+ condPushDownAndJoinInference.add(new ComplexJoinInferenceRule());
+ condPushDownAndJoinInference.add(new DisjunctivePredicateToJoinRule());
+ condPushDownAndJoinInference.add(new PushSelectIntoJoinRule());
+ condPushDownAndJoinInference.add(new IntroJoinInsideSubplanRule());
+ condPushDownAndJoinInference.add(new PushMapOperatorDownThroughProductRule());
+ condPushDownAndJoinInference.add(new PushSubplanWithAggregateDownThroughProductRule());
+ condPushDownAndJoinInference.add(new IntroduceGroupByForSubplanRule());
+ condPushDownAndJoinInference.add(new SubplanOutOfGroupRule());
+ condPushDownAndJoinInference.add(new InsertOuterJoinRule());
+ condPushDownAndJoinInference.add(new AsterixExtractFunctionsFromJoinConditionRule());
+
+ condPushDownAndJoinInference.add(new RemoveRedundantVariablesRule());
+ condPushDownAndJoinInference.add(new AsterixInlineVariablesRule());
+ condPushDownAndJoinInference.add(new RemoveUnusedAssignAndAggregateRule());
+
+ condPushDownAndJoinInference.add(new FactorRedundantGroupAndDecorVarsRule());
+ condPushDownAndJoinInference.add(new PushAggregateIntoGroupbyRule());
+ condPushDownAndJoinInference.add(new EliminateSubplanRule());
+ condPushDownAndJoinInference.add(new PushProperJoinThroughProduct());
+ condPushDownAndJoinInference.add(new PushGroupByThroughProduct());
+ condPushDownAndJoinInference.add(new NestGroupByRule());
+ condPushDownAndJoinInference.add(new EliminateGroupByEmptyKeyRule());
+ condPushDownAndJoinInference.add(new PushSubplanIntoGroupByRule());
+ condPushDownAndJoinInference.add(new NestedSubplanToJoinRule());
+ condPushDownAndJoinInference.add(new EliminateSubplanWithInputCardinalityOneRule());
+
+ return condPushDownAndJoinInference;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildLoadFieldsRuleCollection() {
+ List<IAlgebraicRewriteRule> fieldLoads = new LinkedList<IAlgebraicRewriteRule>();
+ fieldLoads.add(new LoadRecordFieldsRule());
+ fieldLoads.add(new PushFieldAccessRule());
+ // fieldLoads.add(new ByNameToByHandleFieldAccessRule()); -- disabled
+ fieldLoads.add(new ByNameToByIndexFieldAccessRule());
+ fieldLoads.add(new RemoveRedundantVariablesRule());
+ fieldLoads.add(new AsterixInlineVariablesRule());
+ fieldLoads.add(new RemoveUnusedAssignAndAggregateRule());
+ fieldLoads.add(new ConstantFoldingRule());
+ fieldLoads.add(new FeedScanCollectionToUnnest());
+ fieldLoads.add(new ComplexJoinInferenceRule());
+ return fieldLoads;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildFuzzyJoinRuleCollection() {
+ List<IAlgebraicRewriteRule> fuzzy = new LinkedList<IAlgebraicRewriteRule>();
+ // fuzzy.add(new FuzzyJoinRule()); -- The non-indexed fuzzy join will be temporarily disabled. It should be enabled some time in the near future.
+ fuzzy.add(new InferTypesRule());
+ return fuzzy;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildConsolidationRuleCollection() {
+ List<IAlgebraicRewriteRule> consolidation = new LinkedList<IAlgebraicRewriteRule>();
+ consolidation.add(new ConsolidateSelectsRule());
+ consolidation.add(new ConsolidateAssignsRule());
+ consolidation.add(new InlineAssignIntoAggregateRule());
+ consolidation.add(new AsterixIntroduceGroupByCombinerRule());
+ consolidation.add(new IntroduceAggregateCombinerRule());
+ consolidation.add(new CountVarToCountOneRule());
+ consolidation.add(new RemoveUnusedAssignAndAggregateRule());
+ consolidation.add(new RemoveRedundantGroupByDecorVars());
+ consolidation.add(new NestedSubplanToJoinRule());
+ //unionRule => PushUnnestDownUnion => RemoveRedundantListifyRule cause these rules are correlated
+ consolidation.add(new IntroduceUnionRule());
+ consolidation.add(new PushUnnestDownThroughUnionRule());
+ consolidation.add(new RemoveRedundantListifyRule());
+
+ return consolidation;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildAccessMethodRuleCollection() {
+ List<IAlgebraicRewriteRule> accessMethod = new LinkedList<IAlgebraicRewriteRule>();
+ accessMethod.add(new IntroduceSelectAccessMethodRule());
+ accessMethod.add(new IntroduceJoinAccessMethodRule());
+ accessMethod.add(new IntroduceLSMComponentFilterRule());
+ accessMethod.add(new IntroduceSecondaryIndexInsertDeleteRule());
+ accessMethod.add(new RemoveUnusedOneToOneEquiJoinRule());
+ accessMethod.add(new PushSimilarityFunctionsBelowJoin());
+ accessMethod.add(new RemoveUnusedAssignAndAggregateRule());
+ return accessMethod;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildPlanCleanupRuleCollection() {
+ List<IAlgebraicRewriteRule> planCleanupRules = new LinkedList<IAlgebraicRewriteRule>();
+ planCleanupRules.add(new PushAssignBelowUnionAllRule());
+ planCleanupRules.add(new ExtractCommonExpressionsRule());
+ planCleanupRules.add(new RemoveRedundantVariablesRule());
+ planCleanupRules.add(new PushProjectDownRule());
+ planCleanupRules.add(new PushSelectDownRule());
+ planCleanupRules.add(new SetClosedRecordConstructorsRule());
+ planCleanupRules.add(new IntroduceDynamicTypeCastRule());
+ planCleanupRules.add(new IntroduceDynamicTypeCastForExternalFunctionRule());
+ planCleanupRules.add(new RemoveUnusedAssignAndAggregateRule());
+ return planCleanupRules;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildDataExchangeRuleCollection() {
+ List<IAlgebraicRewriteRule> dataExchange = new LinkedList<IAlgebraicRewriteRule>();
+ dataExchange.add(new SetExecutionModeRule());
+ return dataExchange;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildPhysicalRewritesAllLevelsRuleCollection() {
+ List<IAlgebraicRewriteRule> physicalRewritesAllLevels = new LinkedList<IAlgebraicRewriteRule>();
+ physicalRewritesAllLevels.add(new PullSelectOutOfEqJoin());
+ //Turned off the following rule for now not to change OptimizerTest results.
+ //physicalRewritesAllLevels.add(new IntroduceTransactionCommitByAssignOpRule());
+ physicalRewritesAllLevels.add(new ReplaceSinkOpWithCommitOpRule());
+ physicalRewritesAllLevels.add(new SetAlgebricksPhysicalOperatorsRule());
+ physicalRewritesAllLevels.add(new SetAsterixPhysicalOperatorsRule());
+ physicalRewritesAllLevels.add(new IntroduceInstantLockSearchCallbackRule());
+ physicalRewritesAllLevels.add(new AddEquivalenceClassForRecordConstructorRule());
+ physicalRewritesAllLevels.add(new EnforceStructuralPropertiesRule());
+ physicalRewritesAllLevels.add(new RemoveSortInFeedIngestionRule());
+ physicalRewritesAllLevels.add(new IntroHashPartitionMergeExchange());
+ physicalRewritesAllLevels.add(new PushProjectDownRule());
+ physicalRewritesAllLevels.add(new InsertProjectBeforeUnionRule());
+ physicalRewritesAllLevels.add(new IntroduceMaterializationForInsertWithSelfScanRule());
+ physicalRewritesAllLevels.add(new InlineSingleReferenceVariablesRule());
+ physicalRewritesAllLevels.add(new RemoveUnusedAssignAndAggregateRule());
+ physicalRewritesAllLevels.add(new ConsolidateAssignsRule());
+ // After adding projects, we may need need to set physical operators again.
+ physicalRewritesAllLevels.add(new SetAlgebricksPhysicalOperatorsRule());
+ return physicalRewritesAllLevels;
+ }
+
+ public final static List<IAlgebraicRewriteRule> buildPhysicalRewritesTopLevelRuleCollection() {
+ List<IAlgebraicRewriteRule> physicalRewritesTopLevel = new LinkedList<IAlgebraicRewriteRule>();
+ physicalRewritesTopLevel.add(new PushNestedOrderByUnderPreSortedGroupByRule());
+ physicalRewritesTopLevel.add(new CopyLimitDownRule());
+ physicalRewritesTopLevel.add(new IntroduceProjectsRule());
+ physicalRewritesTopLevel.add(new SetAlgebricksPhysicalOperatorsRule());
+ physicalRewritesTopLevel.add(new IntroduceRapidFrameFlushProjectAssignRule());
+ physicalRewritesTopLevel.add(new SetExecutionModeRule());
+ physicalRewritesTopLevel.add(new IntroduceRandomPartitioningFeedComputationRule());
+ return physicalRewritesTopLevel;
+ }
+
+ public final static List<IAlgebraicRewriteRule> prepareForJobGenRuleCollection() {
+ List<IAlgebraicRewriteRule> prepareForJobGenRewrites = new LinkedList<IAlgebraicRewriteRule>();
+ prepareForJobGenRewrites.add(new IsolateHyracksOperatorsRule(
+ HeuristicOptimizer.hyraxOperatorsBelowWhichJobGenIsDisabled));
+ prepareForJobGenRewrites.add(new ExtractCommonOperatorsRule());
+ // Re-infer all types, so that, e.g., the effect of not-is-null is
+ // propagated.
+ prepareForJobGenRewrites.add(new ReinferAllTypesRule());
+ prepareForJobGenRewrites.add(new PushGroupByIntoSortRule());
+ prepareForJobGenRewrites.add(new SetExecutionModeRule());
+ prepareForJobGenRewrites.add(new SweepIllegalNonfunctionalFunctions());
+ return prepareForJobGenRewrites;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/FieldIndexAndTypeHandle.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/FieldIndexAndTypeHandle.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/FieldIndexAndTypeHandle.java
new file mode 100644
index 0000000..7eee1ff
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/FieldIndexAndTypeHandle.java
@@ -0,0 +1,41 @@
+/*
+ * 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.handle;
+
+import edu.uci.ics.asterix.om.types.IAType;
+
+public class FieldIndexAndTypeHandle implements IHandle {
+
+ private int fieldIndex;
+ private IAType fieldType;
+
+ public FieldIndexAndTypeHandle(int fieldIndex, IAType fieldType) {
+ this.fieldIndex = fieldIndex;
+ this.fieldType = fieldType;
+ }
+
+ @Override
+ public HandleType getHandleType() {
+ return HandleType.FIELD_INDEX_AND_TYPE;
+ }
+
+ public int getFieldIndex() {
+ return fieldIndex;
+ }
+
+ public IAType getFieldType() {
+ return fieldType;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/FieldNameHandle.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/FieldNameHandle.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/FieldNameHandle.java
new file mode 100644
index 0000000..a1b8409
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/FieldNameHandle.java
@@ -0,0 +1,44 @@
+/*
+ * 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.handle;
+
+import edu.uci.ics.asterix.om.types.IAType;
+
+public class FieldNameHandle implements IHandle {
+
+ private String fieldName;
+ private IAType fieldType;
+
+ public FieldNameHandle(String fieldName) {
+ this.fieldName = fieldName;
+ }
+
+ public IAType getFieldType() {
+ return fieldType;
+ }
+
+ public void setFieldType(IAType fieldType) {
+ this.fieldType = fieldType;
+ }
+
+ @Override
+ public HandleType getHandleType() {
+ return HandleType.FIELD_NAME;
+ }
+
+ public String getFieldName() {
+ return fieldName;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/IHandle.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/IHandle.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/IHandle.java
new file mode 100644
index 0000000..80103b2
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/handle/IHandle.java
@@ -0,0 +1,31 @@
+/*
+ * 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.handle;
+
+/**
+ * A handle is a way of accessing an ADM instance or a collection of ADM
+ * instances nested within another ADM instance.
+ *
+ * @author Nicola
+ */
+
+public interface IHandle {
+ public enum HandleType {
+ FIELD_INDEX_AND_TYPE,
+ FIELD_NAME
+ }
+
+ public HandleType getHandleType();
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AddEquivalenceClassForRecordConstructorRule.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AddEquivalenceClassForRecordConstructorRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AddEquivalenceClassForRecordConstructorRule.java
new file mode 100644
index 0000000..c738720
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AddEquivalenceClassForRecordConstructorRule.java
@@ -0,0 +1,127 @@
+/*
+ * 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.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.mortbay.util.SingletonList;
+
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
+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.EquivalenceClass;
+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.ConstantExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+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.rewriter.base.IAlgebraicRewriteRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.util.PhysicalOptimizationsUtil;
+
+/**
+ * Adds equivalent classes for record-constructors.
+ * For example, for $x:=record-constructor("field1": $v, "field2": $t),
+ * two equivalent classes will be added:
+ * <$v, field-access-by-index($x, 0)>
+ * <$t, field-access-by-index($x, 1)>
+ *
+ * @author yingyi
+ */
+public class AddEquivalenceClassForRecordConstructorRule 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.ASSIGN) {
+ return false;
+ }
+ // Computes FDs and equivalence classes for the operator.
+ PhysicalOptimizationsUtil.computeFDsAndEquivalenceClasses(op, context);
+ AssignOperator assignOp = (AssignOperator) op;
+ List<LogicalVariable> vars = assignOp.getVariables();
+ List<Mutable<ILogicalExpression>> exprRefs = assignOp.getExpressions();
+ return addEquivalenceClassesForRecordConstructor(vars, exprRefs, assignOp, context);
+ }
+
+ private boolean addEquivalenceClassesForRecordConstructor(List<LogicalVariable> vars,
+ List<Mutable<ILogicalExpression>> exprRefs, AssignOperator assignOp, IOptimizationContext context) {
+ boolean changed = false;
+ for (int exprIndex = 0; exprIndex < exprRefs.size(); ++exprIndex) {
+ ILogicalExpression expr = exprRefs.get(exprIndex).getValue();
+ if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+ ScalarFunctionCallExpression funcExpr = (ScalarFunctionCallExpression) expr;
+ FunctionIdentifier fid = funcExpr.getFunctionIdentifier();
+ if (fid == AsterixBuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR
+ || fid == AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR) {
+ changed |= propagateEquivalenceClassesForRecordConstructor(vars.get(exprIndex), funcExpr, assignOp,
+ context);
+ }
+ }
+ }
+ return changed;
+ }
+
+ @SuppressWarnings("unchecked")
+ private boolean propagateEquivalenceClassesForRecordConstructor(LogicalVariable recordVar,
+ ScalarFunctionCallExpression funcExpr, AssignOperator assignOp, IOptimizationContext context) {
+ List<Mutable<ILogicalExpression>> argRefs = funcExpr.getArguments();
+ boolean changed = false;
+ // Only odd position arguments are field value expressions.
+ for (int parameterIndex = 1; parameterIndex < argRefs.size(); parameterIndex += 2) {
+ ILogicalExpression fieldExpr = argRefs.get(parameterIndex).getValue();
+ // Adds equivalent classes if a field is from a variable reference.
+ if (fieldExpr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
+ VariableReferenceExpression varExpr = (VariableReferenceExpression) fieldExpr;
+ LogicalVariable fieldVar = varExpr.getVariableReference();
+ Map<LogicalVariable, EquivalenceClass> ecs = context.getEquivalenceClassMap(assignOp);
+ if (ecs == null) {
+ ecs = new HashMap<LogicalVariable, EquivalenceClass>();
+ context.putEquivalenceClassMap(assignOp, ecs);
+ }
+ ILogicalExpression expr = new ScalarFunctionCallExpression(
+ FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX),
+ new MutableObject<ILogicalExpression>(new VariableReferenceExpression(recordVar)),
+ new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(
+ new AInt32(parameterIndex / 2))))); // Every two parameters corresponds to a field.
+ EquivalenceClass equivClass = new EquivalenceClass(SingletonList.newSingletonList(fieldVar), fieldVar,
+ SingletonList.newSingletonList(expr));
+ ecs.put(fieldVar, equivClass);
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixExtractFunctionsFromJoinConditionRule.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixExtractFunctionsFromJoinConditionRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixExtractFunctionsFromJoinConditionRule.java
new file mode 100644
index 0000000..5457e55
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/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);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java
new file mode 100644
index 0000000..296bbb2
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java
@@ -0,0 +1,38 @@
+/*
+ * 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.rewriter.rules.InlineVariablesRule;
+
+public class AsterixInlineVariablesRule extends InlineVariablesRule {
+
+ public AsterixInlineVariablesRule() {
+ // Do not inline field accesses and spatial functions because doing so would interfere with our access method rewrites.
+ // TODO: For now we must also exclude record constructor functions to avoid breaking our type casting rules
+ // IntroduceStaticTypeCastRule and IntroduceDynamicTypeCastRule.
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME);
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX);
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR);
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR);
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.CAST_RECORD);
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.CREATE_CIRCLE);
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.CREATE_LINE);
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.CREATE_MBR);
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.CREATE_POINT);
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.CREATE_POLYGON);
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.CREATE_RECTANGLE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixIntroduceGroupByCombinerRule.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixIntroduceGroupByCombinerRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixIntroduceGroupByCombinerRule.java
new file mode 100644
index 0000000..b71ffab
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixIntroduceGroupByCombinerRule.java
@@ -0,0 +1,74 @@
+/*
+ * 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.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.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+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.IFunctionInfo;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.AbstractIntroduceGroupByCombinerRule;
+
+public class AsterixIntroduceGroupByCombinerRule extends AbstractIntroduceGroupByCombinerRule {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void processNullTest(IOptimizationContext context, GroupByOperator nestedGby,
+ List<LogicalVariable> aggregateVarsProducedByCombiner) {
+ IFunctionInfo finfoEq = context.getMetadataProvider().lookupFunction(AsterixBuiltinFunctions.IS_SYSTEM_NULL);
+ SelectOperator selectNonSystemNull;
+
+ if (aggregateVarsProducedByCombiner.size() == 1) {
+ ILogicalExpression isSystemNullTest = new ScalarFunctionCallExpression(finfoEq,
+ new MutableObject<ILogicalExpression>(new VariableReferenceExpression(
+ aggregateVarsProducedByCombiner.get(0))));
+ IFunctionInfo finfoNot = context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.NOT);
+ ScalarFunctionCallExpression nonSystemNullTest = new ScalarFunctionCallExpression(finfoNot,
+ new MutableObject<ILogicalExpression>(isSystemNullTest));
+ selectNonSystemNull = new SelectOperator(new MutableObject<ILogicalExpression>(nonSystemNullTest), false,
+ null);
+ } else {
+ List<Mutable<ILogicalExpression>> isSystemNullTestList = new ArrayList<Mutable<ILogicalExpression>>();
+ for (LogicalVariable aggVar : aggregateVarsProducedByCombiner) {
+ ILogicalExpression isSystemNullTest = new ScalarFunctionCallExpression(finfoEq,
+ new MutableObject<ILogicalExpression>(new VariableReferenceExpression(aggVar)));
+ IFunctionInfo finfoNot = context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.NOT);
+ ScalarFunctionCallExpression nonSystemNullTest = new ScalarFunctionCallExpression(finfoNot,
+ new MutableObject<ILogicalExpression>(isSystemNullTest));
+ isSystemNullTestList.add(new MutableObject<ILogicalExpression>(nonSystemNullTest));
+ }
+ IFunctionInfo finfoAnd = context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.AND);
+ selectNonSystemNull = new SelectOperator(new MutableObject<ILogicalExpression>(
+ new ScalarFunctionCallExpression(finfoAnd, isSystemNullTestList)), false, null);
+ }
+
+ //add the not-system-null check into the nested pipeline
+ Mutable<ILogicalOperator> ntsBeforeNestedGby = nestedGby.getInputs().get(0);
+ nestedGby.getInputs().set(0, new MutableObject<ILogicalOperator>(selectNonSystemNull));
+ selectNonSystemNull.getInputs().add(ntsBeforeNestedGby);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java
new file mode 100644
index 0000000..c42fa15
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/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
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByHandleFieldAccessRule.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByHandleFieldAccessRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByHandleFieldAccessRule.java
new file mode 100644
index 0000000..9c04564
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByHandleFieldAccessRule.java
@@ -0,0 +1,116 @@
+/*
+ * 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.algebra.base.AsterixOperatorAnnotations;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+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.ScalarFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+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.rewriter.base.IAlgebraicRewriteRule;
+
+public class ByNameToByHandleFieldAccessRule implements IAlgebraicRewriteRule {
+
+ @Override
+ public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
+ return false;
+ }
+
+ @Override
+ public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
+ AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
+ if (op.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
+ return false;
+ }
+ AssignOperator assign = (AssignOperator) op;
+ if (assign.getAnnotations().get(AsterixOperatorAnnotations.PUSHED_FIELD_ACCESS) == null) {
+ return false;
+ }
+ byNameToByHandle(assign, context);
+ return true;
+ }
+
+ private static void byNameToByHandle(AssignOperator fieldAccessOp, IOptimizationContext context) {
+ Mutable<ILogicalOperator> opUnder = fieldAccessOp.getInputs().get(0);
+ AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) fieldAccessOp.getExpressions().get(0)
+ .getValue();
+ ILogicalExpression a1 = fce.getArguments().get(0).getValue();
+
+ VariableReferenceExpression x;
+ if (a1.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
+ x = (VariableReferenceExpression) a1;
+ } else {
+ LogicalVariable var1 = context.newVar();
+ ArrayList<LogicalVariable> varArray = new ArrayList<LogicalVariable>(1);
+ varArray.add(var1);
+ ArrayList<Mutable<ILogicalExpression>> exprArray = new ArrayList<Mutable<ILogicalExpression>>(1);
+ exprArray.add(new MutableObject<ILogicalExpression>(a1));
+ AssignOperator assignVar = new AssignOperator(varArray, exprArray);
+ x = new VariableReferenceExpression(var1);
+ assignVar.getInputs().add(opUnder);
+ opUnder = new MutableObject<ILogicalOperator>(assignVar);
+ }
+
+ // let $t := type-of(x)
+ LogicalVariable t = context.newVar();
+
+ AbstractFunctionCallExpression typeOf = new ScalarFunctionCallExpression(
+ FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.TYPE_OF));
+ typeOf.getArguments().add(new MutableObject<ILogicalExpression>(x));
+ AssignOperator typAssign = new AssignOperator(t, new MutableObject<ILogicalExpression>(typeOf));
+ typAssign.getInputs().add(opUnder);
+
+ // let $w := get-handle($t, path-expression)
+ LogicalVariable w = context.newVar();
+ AbstractFunctionCallExpression getHandle = new ScalarFunctionCallExpression(
+ FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.GET_HANDLE));
+ getHandle.getArguments().add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(t)));
+ // the accessed field
+ getHandle.getArguments().add(new MutableObject<ILogicalExpression>(fce.getArguments().get(1).getValue()));
+ AssignOperator handleAssign = new AssignOperator(w, new MutableObject<ILogicalExpression>(getHandle));
+ handleAssign.getInputs().add(new MutableObject<ILogicalOperator>(typAssign));
+
+ // let $y := get-data(x, $w)
+ AbstractFunctionCallExpression getData = new ScalarFunctionCallExpression(
+ FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.GET_DATA));
+ VariableReferenceExpression ref2 = new VariableReferenceExpression(x.getVariableReference());
+ getData.getArguments().add(new MutableObject<ILogicalExpression>(ref2));
+ getData.getArguments().add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(w)));
+ fieldAccessOp.getExpressions().get(0).setValue(getData);
+ List<Mutable<ILogicalOperator>> faInputs = fieldAccessOp.getInputs();
+ faInputs.clear();
+ faInputs.add(new MutableObject<ILogicalOperator>(handleAssign));
+
+ // fieldAccess.setAnnotation(OperatorAnnotation.FIELD_ACCESS,
+ // fce.getArguments().get(0));
+ fieldAccessOp.removeAnnotation(AsterixOperatorAnnotations.PUSHED_FIELD_ACCESS);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
new file mode 100644
index 0000000..0dee2be
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
@@ -0,0 +1,175 @@
+/*
+ * 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.io.IOException;
+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.algebra.base.AsterixOperatorAnnotations;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AString;
+import edu.uci.ics.asterix.om.base.IAObject;
+import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
+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.ConstantExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+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.rewriter.base.IAlgebraicRewriteRule;
+
+public class ByNameToByIndexFieldAccessRule 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.ASSIGN) {
+ return false;
+ }
+ AssignOperator assign = (AssignOperator) op;
+ if (assign.getExpressions().get(0).getValue().getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
+ return false;
+ }
+
+ List<Mutable<ILogicalExpression>> expressions = assign.getExpressions();
+ boolean changed = false;
+ for (int i = 0; i < expressions.size(); i++) {
+ AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expressions.get(i).getValue();
+ if (fce.getFunctionIdentifier() != AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME) {
+ continue;
+ }
+ IVariableTypeEnvironment env = context.getOutputTypeEnvironment(op);
+
+ ILogicalExpression a0 = fce.getArguments().get(0).getValue();
+ if (a0.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+ LogicalVariable var1 = context.newVar();
+ ArrayList<LogicalVariable> varArray = new ArrayList<LogicalVariable>(1);
+ varArray.add(var1);
+ ArrayList<Mutable<ILogicalExpression>> exprArray = new ArrayList<Mutable<ILogicalExpression>>(1);
+ exprArray.add(new MutableObject<ILogicalExpression>(a0));
+ AssignOperator assignVar = new AssignOperator(varArray, exprArray);
+ fce.getArguments().get(0).setValue(new VariableReferenceExpression(var1));
+ assignVar.getInputs().add(new MutableObject<ILogicalOperator>(assign.getInputs().get(0).getValue()));
+ assign.getInputs().get(0).setValue(assignVar);
+ context.computeAndSetTypeEnvironmentForOperator(assignVar);
+ context.computeAndSetTypeEnvironmentForOperator(assign);
+ //access by name was not replaced to access by index, but the plan was altered, hence changed is true
+ changed = true;
+ }
+
+ IAType t = (IAType) env.getType(fce.getArguments().get(0).getValue());
+ try {
+ switch (t.getTypeTag()) {
+ case ANY: {
+ return false || changed;
+ }
+ case RECORD: {
+ ARecordType recType = (ARecordType) t;
+ ILogicalExpression fai = createFieldAccessByIndex(recType, fce);
+ if (fai == null) {
+ return false || changed;
+ }
+ expressions.get(i).setValue(fai);
+ changed = true;
+ break;
+ }
+ case UNION: {
+ AUnionType unionT = (AUnionType) t;
+ if (unionT.isNullableType()) {
+ IAType t2 = unionT.getNullableType();
+ if (t2.getTypeTag() == ATypeTag.RECORD) {
+ ARecordType recType = (ARecordType) t2;
+ ILogicalExpression fai = createFieldAccessByIndex(recType, fce);
+ if (fai == null) {
+ return false || changed;
+ }
+ expressions.get(i).setValue(fai);
+ changed = true;
+ break;
+ }
+ }
+ throw new NotImplementedException("Union " + unionT);
+ }
+ default: {
+ throw new AlgebricksException("Cannot call field-access on data of type " + t);
+ }
+ }
+ } catch (IOException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+ assign.removeAnnotation(AsterixOperatorAnnotations.PUSHED_FIELD_ACCESS);
+ return changed;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static ILogicalExpression createFieldAccessByIndex(ARecordType recType, AbstractFunctionCallExpression fce)
+ throws IOException {
+ String s = getStringSecondArgument(fce);
+ if (s == null) {
+ return null;
+ }
+ int k = recType.findFieldPosition(s);
+ if (k < 0) {
+ return null;
+ }
+ return new ScalarFunctionCallExpression(
+ FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX),
+ fce.getArguments().get(0), new MutableObject<ILogicalExpression>(new ConstantExpression(
+ new AsterixConstantValue(new AInt32(k)))));
+ }
+
+ private static String getStringSecondArgument(AbstractFunctionCallExpression expr) {
+ ILogicalExpression e2 = expr.getArguments().get(1).getValue();
+ if (e2.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
+ return null;
+ }
+ ConstantExpression c = (ConstantExpression) e2;
+ if (!(c.getValue() instanceof AsterixConstantValue)) {
+ return null;
+ }
+ IAObject v = ((AsterixConstantValue) c.getValue()).getObject();
+ if (v.getType().getTypeTag() != ATypeTag.STRING) {
+ return null;
+ }
+ return ((AString) v).getStringValue();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java
new file mode 100644
index 0000000..73b0de7
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java
@@ -0,0 +1,282 @@
+/*
+ * 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.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
+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.ILogicalPlan;
+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.AbstractLogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.StatefulFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.RunningAggregateOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.RunningAggregatePOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.UnpartitionedPropertyComputer;
+import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+
+/**
+ * This rule cancels the unnest with the nested listify. Formally, the following plan<br/>
+ *
+ * <pre>
+ * unnset $x <- $y
+ * group-by($k){
+ * aggregate $y <- listify($z)
+ * ...
+ * }
+ * </pre>
+ *
+ * will be converted into<br/>
+ *
+ * <pre>
+ * assign $x <- $z
+ * sort($k)
+ * </pre>
+ *
+ * When the positional variable exists, for example the original plan is like<br/>
+ *
+ * <pre>
+ * unnset $x at $p <- $y
+ * group-by($k){
+ * aggregate $y <- listify($z)
+ * ...
+ * }
+ * </pre>
+ *
+ * will be converted into<br/>
+ *
+ * <pre>
+ * group-by($k){
+ * running-aggregate $p <- tid()
+ * }
+ * </pre>
+ */
+public class CancelUnnestWithNestedListifyRule implements IAlgebraicRewriteRule {
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule#rewritePost(org.apache.commons.lang3.mutable.Mutable, edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext)
+ */
+ @Override
+ public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+ throws AlgebricksException {
+ return false;
+ }
+
+ @Override
+ public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+ // apply it only at the top of the plan
+ ILogicalOperator op = opRef.getValue();
+ if (context.checkIfInDontApplySet(this, op)) {
+ return false;
+ }
+ Set<LogicalVariable> varSet = new HashSet<LogicalVariable>();
+ return applyRuleDown(opRef, varSet, context);
+ }
+
+ private boolean applyRuleDown(Mutable<ILogicalOperator> opRef, Set<LogicalVariable> varSet,
+ IOptimizationContext context) throws AlgebricksException {
+ boolean changed = applies(opRef, varSet, context);
+ AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
+ VariableUtilities.getUsedVariables(op, varSet);
+ if (op.hasNestedPlans()) {
+ AbstractOperatorWithNestedPlans aonp = (AbstractOperatorWithNestedPlans) op;
+ for (ILogicalPlan p : aonp.getNestedPlans()) {
+ for (Mutable<ILogicalOperator> r : p.getRoots()) {
+ if (applyRuleDown(r, varSet, context)) {
+ changed = true;
+ }
+ context.addToDontApplySet(this, r.getValue());
+ }
+ }
+ }
+ for (Mutable<ILogicalOperator> i : op.getInputs()) {
+ if (applyRuleDown(i, varSet, context)) {
+ changed = true;
+ }
+ context.addToDontApplySet(this, i.getValue());
+ }
+ return changed;
+ }
+
+ private boolean applies(Mutable<ILogicalOperator> opRef, Set<LogicalVariable> varUsedAbove,
+ IOptimizationContext context) throws AlgebricksException {
+ AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
+ if (op1.getOperatorTag() != LogicalOperatorTag.UNNEST) {
+ return false;
+ }
+ UnnestOperator unnest1 = (UnnestOperator) op1;
+ ILogicalExpression expr = unnest1.getExpressionRef().getValue();
+ LogicalVariable unnestedVar;
+ switch (expr.getExpressionTag()) {
+ case VARIABLE:
+ unnestedVar = ((VariableReferenceExpression) expr).getVariableReference();
+ break;
+ case FUNCTION_CALL:
+ if (((AbstractFunctionCallExpression) expr).getFunctionIdentifier() != AsterixBuiltinFunctions.SCAN_COLLECTION) {
+ return false;
+ }
+ AbstractFunctionCallExpression functionCall = (AbstractFunctionCallExpression) expr;
+ ILogicalExpression functionCallArgExpr = functionCall.getArguments().get(0).getValue();
+ if (functionCallArgExpr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
+ return false;
+ }
+ unnestedVar = ((VariableReferenceExpression) functionCallArgExpr).getVariableReference();
+ break;
+ default:
+ return false;
+ }
+ if (varUsedAbove.contains(unnestedVar)) {
+ return false;
+ }
+
+ Mutable<ILogicalOperator> opRef2 = op1.getInputs().get(0);
+ AbstractLogicalOperator r = (AbstractLogicalOperator) opRef2.getValue();
+
+ if (r.getOperatorTag() != LogicalOperatorTag.GROUP) {
+ return false;
+ }
+
+ // go inside of a group-by plan
+ GroupByOperator gby = (GroupByOperator) r;
+ if (gby.getNestedPlans().size() != 1) {
+ return false;
+ }
+ if (gby.getNestedPlans().get(0).getRoots().size() != 1) {
+ return false;
+ }
+
+ AbstractLogicalOperator nestedPlanRoot = (AbstractLogicalOperator) gby.getNestedPlans().get(0).getRoots()
+ .get(0).getValue();
+ if (nestedPlanRoot.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
+ return false;
+ }
+ AggregateOperator agg = (AggregateOperator) nestedPlanRoot;
+ Mutable<ILogicalOperator> aggInputOpRef = agg.getInputs().get(0);
+
+ if (agg.getVariables().size() > 1) {
+ return false;
+ }
+
+ LogicalVariable aggVar = agg.getVariables().get(0);
+ ILogicalExpression aggFun = agg.getExpressions().get(0).getValue();
+ if (!aggVar.equals(unnestedVar)
+ || ((AbstractLogicalExpression) aggFun).getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
+ return false;
+ }
+ AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) aggFun;
+ if (!AsterixBuiltinFunctions.LISTIFY.equals(f.getFunctionIdentifier())) {
+ return false;
+ }
+ if (f.getArguments().size() != 1) {
+ return false;
+ }
+ ILogicalExpression arg0 = f.getArguments().get(0).getValue();
+ if (((AbstractLogicalExpression) arg0).getExpressionTag() != LogicalExpressionTag.VARIABLE) {
+ return false;
+ }
+ LogicalVariable paramVar = ((VariableReferenceExpression) arg0).getVariableReference();
+
+ ArrayList<LogicalVariable> assgnVars = new ArrayList<LogicalVariable>(1);
+ assgnVars.add(unnest1.getVariable());
+ ArrayList<Mutable<ILogicalExpression>> assgnExprs = new ArrayList<Mutable<ILogicalExpression>>(1);
+ assgnExprs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(paramVar)));
+ AssignOperator assign = new AssignOperator(assgnVars, assgnExprs);
+
+ LogicalVariable posVar = unnest1.getPositionalVariable();
+ if (posVar == null) {
+ // Creates assignment for group-by keys.
+ ArrayList<LogicalVariable> gbyKeyAssgnVars = new ArrayList<LogicalVariable>();
+ ArrayList<Mutable<ILogicalExpression>> gbyKeyAssgnExprs = new ArrayList<Mutable<ILogicalExpression>>();
+ for (int i = 0; i < gby.getGroupByList().size(); i++) {
+ if (gby.getGroupByList().get(i).first != null) {
+ gbyKeyAssgnVars.add(gby.getGroupByList().get(i).first);
+ gbyKeyAssgnExprs.add(gby.getGroupByList().get(i).second);
+ }
+ }
+
+ // Moves the nested pipeline before aggregation out of the group-by op.
+ Mutable<ILogicalOperator> bottomOpRef = aggInputOpRef;
+ AbstractLogicalOperator bottomOp = (AbstractLogicalOperator) bottomOpRef.getValue();
+ while (bottomOp.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) {
+ bottomOpRef = bottomOp.getInputs().get(0);
+ bottomOp = (AbstractLogicalOperator) bottomOpRef.getValue();
+ }
+
+ // Removes the group-by operator.
+ opRef.setValue(assign);
+ assign.getInputs().add(aggInputOpRef);
+ AssignOperator gbyKeyAssign = new AssignOperator(gbyKeyAssgnVars, gbyKeyAssgnExprs);
+ gbyKeyAssign.getInputs().add(gby.getInputs().get(0));
+ bottomOpRef.setValue(gbyKeyAssign);
+
+ context.computeAndSetTypeEnvironmentForOperator(gbyKeyAssign);
+ context.computeAndSetTypeEnvironmentForOperator(assign);
+ } else {
+ // if positional variable is used in unnest, the unnest will be pushed into the group-by as a running-aggregate
+
+ // First create assign for the unnest variable
+ List<LogicalVariable> nestedAssignVars = new ArrayList<LogicalVariable>();
+ List<Mutable<ILogicalExpression>> nestedAssignExprs = new ArrayList<Mutable<ILogicalExpression>>();
+ nestedAssignVars.add(unnest1.getVariable());
+ nestedAssignExprs.add(new MutableObject<ILogicalExpression>(arg0));
+ AssignOperator nestedAssign = new AssignOperator(nestedAssignVars, nestedAssignExprs);
+ nestedAssign.getInputs().add(opRef2);
+
+ // Then create running aggregation for the positional variable
+ List<LogicalVariable> raggVars = new ArrayList<LogicalVariable>();
+ List<Mutable<ILogicalExpression>> raggExprs = new ArrayList<Mutable<ILogicalExpression>>();
+ raggVars.add(posVar);
+ StatefulFunctionCallExpression fce = new StatefulFunctionCallExpression(
+ FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.TID), UnpartitionedPropertyComputer.INSTANCE);
+ raggExprs.add(new MutableObject<ILogicalExpression>(fce));
+ RunningAggregateOperator raggOp = new RunningAggregateOperator(raggVars, raggExprs);
+ raggOp.setExecutionMode(unnest1.getExecutionMode());
+ RunningAggregatePOperator raggPOp = new RunningAggregatePOperator();
+ raggOp.setPhysicalOperator(raggPOp);
+ raggOp.getInputs().add(nestedPlanRoot.getInputs().get(0));
+ gby.getNestedPlans().get(0).getRoots().set(0, new MutableObject<ILogicalOperator>(raggOp));
+
+ opRef.setValue(nestedAssign);
+
+ context.computeAndSetTypeEnvironmentForOperator(nestedAssign);
+ context.computeAndSetTypeEnvironmentForOperator(raggOp);
+ context.computeAndSetTypeEnvironmentForOperator(gby);
+
+ }
+
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CheckFilterExpressionTypeRule.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CheckFilterExpressionTypeRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CheckFilterExpressionTypeRule.java
new file mode 100644
index 0000000..7e9ebcc
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CheckFilterExpressionTypeRule.java
@@ -0,0 +1,83 @@
+/*
+ * 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 org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+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.LogicalOperatorTag;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
+import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+
+/**
+ * This rule is to check if all the filter expression are of the boolean type or a possible (determined
+ * at the runtime) boolean type.
+ * If that is not the case, an exception should be thrown.
+ *
+ * @author yingyib
+ */
+public class CheckFilterExpressionTypeRule 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.SELECT) {
+ return false;
+ }
+ SelectOperator select = (SelectOperator) op;
+ ILogicalExpression condition = select.getCondition().getValue();
+ IVariableTypeEnvironment env = select.computeOutputTypeEnvironment(context);
+ IAType condType = (IAType) env.getType(condition);
+ if (condType.getTypeTag() != ATypeTag.BOOLEAN && condType.getTypeTag() != ATypeTag.ANY
+ && !isPossibleBoolean(condType)) {
+ throw new AlgebricksException("The select condition " + condition.toString()
+ + " should be of the boolean type.");
+ }
+ return false;
+ }
+
+ /**
+ * Check if the type is optional boolean or not
+ *
+ * @param type
+ * @return true if it is; false otherwise.
+ */
+ private boolean isPossibleBoolean(IAType type) {
+ while (NonTaggedFormatUtil.isOptional(type)) {
+ type = ((AUnionType) type).getNullableType();
+ if (type.getTypeTag() == ATypeTag.BOOLEAN || type.getTypeTag() == ATypeTag.ANY) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}