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:29 UTC

[41/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/edu/uci/ics/asterix/optimizer/rules/am/BTreeAccessMethod.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/BTreeAccessMethod.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/BTreeAccessMethod.java
deleted file mode 100644
index 22f3b80..0000000
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/BTreeAccessMethod.java
+++ /dev/null
@@ -1,660 +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.am;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.HashSet;
-import java.util.Iterator;
-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.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation;
-import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
-import edu.uci.ics.asterix.common.config.DatasetConfig.IndexType;
-import edu.uci.ics.asterix.metadata.entities.Dataset;
-import edu.uci.ics.asterix.metadata.entities.Index;
-import edu.uci.ics.asterix.om.types.ARecordType;
-import edu.uci.ics.asterix.optimizer.rules.util.EquivalenceClassUtils;
-import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
-import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
-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.LogicalVariable;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IndexedNLJoinExpressionAnnotation;
-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.AlgebricksBuiltinFunctions.ComparisonKind;
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractDataSourceOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ExternalDataLookupOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
-
-/**
- * Class for helping rewrite rules to choose and apply BTree indexes.
- */
-public class BTreeAccessMethod implements IAccessMethod {
-
-    // Describes whether a search predicate is an open/closed interval.
-    private enum LimitType {
-        LOW_INCLUSIVE,
-        LOW_EXCLUSIVE,
-        HIGH_INCLUSIVE,
-        HIGH_EXCLUSIVE,
-        EQUAL
-    }
-
-    // TODO: There is some redundancy here, since these are listed in AlgebricksBuiltinFunctions as well.
-    private static List<FunctionIdentifier> funcIdents = new ArrayList<FunctionIdentifier>();
-    static {
-        funcIdents.add(AlgebricksBuiltinFunctions.EQ);
-        funcIdents.add(AlgebricksBuiltinFunctions.LE);
-        funcIdents.add(AlgebricksBuiltinFunctions.GE);
-        funcIdents.add(AlgebricksBuiltinFunctions.LT);
-        funcIdents.add(AlgebricksBuiltinFunctions.GT);
-    }
-
-    public static BTreeAccessMethod INSTANCE = new BTreeAccessMethod();
-
-    @Override
-    public List<FunctionIdentifier> getOptimizableFunctions() {
-        return funcIdents;
-    }
-
-    @Override
-    public boolean analyzeFuncExprArgs(AbstractFunctionCallExpression funcExpr,
-            List<AbstractLogicalOperator> assignsAndUnnests, AccessMethodAnalysisContext analysisCtx) {
-        boolean matches = AccessMethodUtils.analyzeFuncExprArgsForOneConstAndVar(funcExpr, analysisCtx);
-        if (!matches) {
-            matches = AccessMethodUtils.analyzeFuncExprArgsForTwoVars(funcExpr, analysisCtx);
-        }
-        return matches;
-    }
-
-    @Override
-    public boolean matchAllIndexExprs() {
-        return false;
-    }
-
-    @Override
-    public boolean matchPrefixIndexExprs() {
-        return true;
-    }
-
-    @Override
-    public boolean applySelectPlanTransformation(Mutable<ILogicalOperator> selectRef,
-            OptimizableOperatorSubTree subTree, Index chosenIndex, AccessMethodAnalysisContext analysisCtx,
-            IOptimizationContext context) throws AlgebricksException {
-        SelectOperator select = (SelectOperator) selectRef.getValue();
-        Mutable<ILogicalExpression> conditionRef = select.getCondition();
-        ILogicalOperator primaryIndexUnnestOp = createSecondaryToPrimaryPlan(selectRef, conditionRef, subTree, null,
-                chosenIndex, analysisCtx, false, false, false, context);
-        if (primaryIndexUnnestOp == null) {
-            return false;
-        }
-        Mutable<ILogicalOperator> opRef = (subTree.assignsAndUnnestsRefs.isEmpty()) ? null
-                : subTree.assignsAndUnnestsRefs.get(0);
-        ILogicalOperator op = null;
-        if (opRef != null) {
-            op = opRef.getValue();
-        }
-        // Generate new select using the new condition.
-        if (conditionRef.getValue() != null) {
-            select.getInputs().clear();
-            if (op != null) {
-                subTree.dataSourceRef.setValue(primaryIndexUnnestOp);
-                select.getInputs().add(new MutableObject<ILogicalOperator>(op));
-            } else {
-                select.getInputs().add(new MutableObject<ILogicalOperator>(primaryIndexUnnestOp));
-            }
-        } else {
-            ((AbstractLogicalOperator) primaryIndexUnnestOp).setExecutionMode(ExecutionMode.PARTITIONED);
-            if (op != null) {
-                subTree.dataSourceRef.setValue(primaryIndexUnnestOp);
-                selectRef.setValue(op);
-            } else {
-                selectRef.setValue(primaryIndexUnnestOp);
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean applyJoinPlanTransformation(Mutable<ILogicalOperator> joinRef,
-            OptimizableOperatorSubTree leftSubTree, OptimizableOperatorSubTree rightSubTree, Index chosenIndex,
-            AccessMethodAnalysisContext analysisCtx, IOptimizationContext context, boolean isLeftOuterJoin,
-            boolean hasGroupBy) throws AlgebricksException {
-        AbstractBinaryJoinOperator joinOp = (AbstractBinaryJoinOperator) joinRef.getValue();
-        Mutable<ILogicalExpression> conditionRef = joinOp.getCondition();
-        // Determine if the index is applicable on the left or right side (if both, we arbitrarily prefer the left side).
-        Dataset dataset = analysisCtx.indexDatasetMap.get(chosenIndex);
-        // Determine probe and index subtrees based on chosen index.
-        OptimizableOperatorSubTree indexSubTree = null;
-        OptimizableOperatorSubTree probeSubTree = null;
-        if (!isLeftOuterJoin && leftSubTree.hasDataSourceScan()
-                && dataset.getDatasetName().equals(leftSubTree.dataset.getDatasetName())) {
-            indexSubTree = leftSubTree;
-            probeSubTree = rightSubTree;
-        } else if (rightSubTree.hasDataSourceScan()
-                && dataset.getDatasetName().equals(rightSubTree.dataset.getDatasetName())) {
-            indexSubTree = rightSubTree;
-            probeSubTree = leftSubTree;
-        }
-        if (indexSubTree == null) {
-            //This may happen for left outer join case
-            return false;
-        }
-
-        LogicalVariable newNullPlaceHolderVar = null;
-        if (isLeftOuterJoin) {
-            //get a new null place holder variable that is the first field variable of the primary key
-            //from the indexSubTree's datasourceScanOp
-            newNullPlaceHolderVar = indexSubTree.getDataSourceVariables().get(0);
-        }
-
-        ILogicalOperator primaryIndexUnnestOp = createSecondaryToPrimaryPlan(joinRef, conditionRef, indexSubTree,
-                probeSubTree, chosenIndex, analysisCtx, true, isLeftOuterJoin, true, context);
-        if (primaryIndexUnnestOp == null) {
-            return false;
-        }
-
-        if (isLeftOuterJoin && hasGroupBy) {
-            //reset the null place holder variable
-            AccessMethodUtils.resetLOJNullPlaceholderVariableInGroupByOp(analysisCtx, newNullPlaceHolderVar, context);
-        }
-
-        // If there are conditions left, add a new select operator on top.
-        indexSubTree.dataSourceRef.setValue(primaryIndexUnnestOp);
-        if (conditionRef.getValue() != null) {
-            SelectOperator topSelect = new SelectOperator(conditionRef, isLeftOuterJoin, newNullPlaceHolderVar);
-            topSelect.getInputs().add(indexSubTree.rootRef);
-            topSelect.setExecutionMode(ExecutionMode.LOCAL);
-            context.computeAndSetTypeEnvironmentForOperator(topSelect);
-            // Replace the original join with the new subtree rooted at the select op.
-            joinRef.setValue(topSelect);
-        } else {
-            joinRef.setValue(indexSubTree.rootRef.getValue());
-        }
-        return true;
-    }
-
-    private ILogicalOperator createSecondaryToPrimaryPlan(Mutable<ILogicalOperator> topOpRef,
-            Mutable<ILogicalExpression> conditionRef, OptimizableOperatorSubTree indexSubTree,
-            OptimizableOperatorSubTree probeSubTree, Index chosenIndex, AccessMethodAnalysisContext analysisCtx,
-            boolean retainInput, boolean retainNull, boolean requiresBroadcast, IOptimizationContext context)
-            throws AlgebricksException {
-        Dataset dataset = indexSubTree.dataset;
-        ARecordType recordType = indexSubTree.recordType;
-        // we made sure indexSubTree has datasource scan
-        AbstractDataSourceOperator dataSourceOp = (AbstractDataSourceOperator) indexSubTree.dataSourceRef.getValue();
-        List<Pair<Integer, Integer>> exprAndVarList = analysisCtx.indexExprsAndVars.get(chosenIndex);
-        List<IOptimizableFuncExpr> matchedFuncExprs = analysisCtx.matchedFuncExprs;
-        int numSecondaryKeys = analysisCtx.indexNumMatchedKeys.get(chosenIndex);
-        // List of function expressions that will be replaced by the secondary-index search.
-        // These func exprs will be removed from the select condition at the very end of this method.
-        Set<ILogicalExpression> replacedFuncExprs = new HashSet<ILogicalExpression>();
-
-        // Info on high and low keys for the BTree search predicate.
-        ILogicalExpression[] lowKeyExprs = new ILogicalExpression[numSecondaryKeys];
-        ILogicalExpression[] highKeyExprs = new ILogicalExpression[numSecondaryKeys];
-        LimitType[] lowKeyLimits = new LimitType[numSecondaryKeys];
-        LimitType[] highKeyLimits = new LimitType[numSecondaryKeys];
-        boolean[] lowKeyInclusive = new boolean[numSecondaryKeys];
-        boolean[] highKeyInclusive = new boolean[numSecondaryKeys];
-
-        // TODO: For now we don't do any sophisticated analysis of the func exprs to come up with "the best" range predicate.
-        // If we can't figure out how to integrate a certain funcExpr into the current predicate, we just bail by setting this flag.
-        boolean couldntFigureOut = false;
-        boolean doneWithExprs = false;
-        boolean isEqCondition = false;
-        // TODO: For now don't consider prefix searches.
-        BitSet setLowKeys = new BitSet(numSecondaryKeys);
-        BitSet setHighKeys = new BitSet(numSecondaryKeys);
-        // Go through the func exprs listed as optimizable by the chosen index,
-        // and formulate a range predicate on the secondary-index keys.
-
-        // checks whether a type casting happened from a real (FLOAT, DOUBLE) value to an INT value
-        // since we have a round issues when dealing with LT(<) OR GT(>) operator.
-        boolean realTypeConvertedToIntegerType = false;
-
-        for (Pair<Integer, Integer> exprIndex : exprAndVarList) {
-            // Position of the field of matchedFuncExprs.get(exprIndex) in the chosen index's indexed exprs.
-            IOptimizableFuncExpr optFuncExpr = matchedFuncExprs.get(exprIndex.first);
-            int keyPos = indexOf(optFuncExpr.getFieldName(0), chosenIndex.getKeyFieldNames());
-            if (keyPos < 0) {
-                if (optFuncExpr.getNumLogicalVars() > 1) {
-                    // If we are optimizing a join, the matching field may be the second field name.
-                    keyPos = indexOf(optFuncExpr.getFieldName(1), chosenIndex.getKeyFieldNames());
-                }
-            }
-            if (keyPos < 0) {
-                throw new AlgebricksException(
-                        "Could not match optimizable function expression to any index field name.");
-            }
-            Pair<ILogicalExpression, Boolean> returnedSearchKeyExpr = AccessMethodUtils.createSearchKeyExpr(
-                    optFuncExpr, indexSubTree, probeSubTree);
-            ILogicalExpression searchKeyExpr = returnedSearchKeyExpr.first;
-            realTypeConvertedToIntegerType = returnedSearchKeyExpr.second;
-
-            LimitType limit = getLimitType(optFuncExpr, probeSubTree);
-
-            // If a DOUBLE or FLOAT constant is converted to an INT type value,
-            // we need to check a corner case where two real values are located between an INT value.
-            // For example, for the following query,
-            //
-            // for $emp in dataset empDataset
-            // where $emp.age > double("2.3") and $emp.age < double("3.3")
-            // return $emp.id;
-            //
-            // It should generate a result if there is a tuple that satisfies the condition, which is 3,
-            // however, it does not generate the desired result since finding candidates
-            // fail after truncating the fraction part (there is no INT whose value is greater than 2 and less than 3.)
-            //
-            // Therefore, we convert LT(<) to LE(<=) and GT(>) to GE(>=) to find candidates.
-            // This does not change the result of an actual comparison since this conversion is only applied
-            // for finding candidates from an index.
-            //
-            if (realTypeConvertedToIntegerType) {
-                if (limit == LimitType.HIGH_EXCLUSIVE) {
-                    limit = LimitType.HIGH_INCLUSIVE;
-                } else if (limit == LimitType.LOW_EXCLUSIVE) {
-                    limit = LimitType.LOW_INCLUSIVE;
-                }
-            }
-
-            switch (limit) {
-                case EQUAL: {
-                    if (lowKeyLimits[keyPos] == null && highKeyLimits[keyPos] == null) {
-                        lowKeyLimits[keyPos] = highKeyLimits[keyPos] = limit;
-                        lowKeyInclusive[keyPos] = highKeyInclusive[keyPos] = true;
-                        lowKeyExprs[keyPos] = highKeyExprs[keyPos] = searchKeyExpr;
-                        setLowKeys.set(keyPos);
-                        setHighKeys.set(keyPos);
-                        isEqCondition = true;
-                    } else {
-                        // Has already been set to the identical values. When optimizing join we may encounter the same optimizable expression twice
-                        // (once from analyzing each side of the join)
-                        if (lowKeyLimits[keyPos] == limit && lowKeyInclusive[keyPos] == true
-                                && lowKeyExprs[keyPos].equals(searchKeyExpr) && highKeyLimits[keyPos] == limit
-                                && highKeyInclusive[keyPos] == true && highKeyExprs[keyPos].equals(searchKeyExpr)) {
-                            isEqCondition = true;
-                            break;
-                        }
-                        couldntFigureOut = true;
-                    }
-                    // TODO: For now don't consider prefix searches.
-                    // If high and low keys are set, we exit for now.
-                    if (setLowKeys.cardinality() == numSecondaryKeys && setHighKeys.cardinality() == numSecondaryKeys) {
-                        doneWithExprs = true;
-                    }
-                    break;
-                }
-                case HIGH_EXCLUSIVE: {
-                    if (highKeyLimits[keyPos] == null || (highKeyLimits[keyPos] != null && highKeyInclusive[keyPos])) {
-                        highKeyLimits[keyPos] = limit;
-                        highKeyExprs[keyPos] = searchKeyExpr;
-                        highKeyInclusive[keyPos] = false;
-                    } else {
-                        // Has already been set to the identical values. When optimizing join we may encounter the same optimizable expression twice
-                        // (once from analyzing each side of the join)
-                        if (highKeyLimits[keyPos] == limit && highKeyInclusive[keyPos] == false
-                                && highKeyExprs[keyPos].equals(searchKeyExpr)) {
-                            break;
-                        }
-                        couldntFigureOut = true;
-                        doneWithExprs = true;
-                    }
-                    break;
-                }
-                case HIGH_INCLUSIVE: {
-                    if (highKeyLimits[keyPos] == null) {
-                        highKeyLimits[keyPos] = limit;
-                        highKeyExprs[keyPos] = searchKeyExpr;
-                        highKeyInclusive[keyPos] = true;
-                    } else {
-                        // Has already been set to the identical values. When optimizing join we may encounter the same optimizable expression twice
-                        // (once from analyzing each side of the join)
-                        if (highKeyLimits[keyPos] == limit && highKeyInclusive[keyPos] == true
-                                && highKeyExprs[keyPos].equals(searchKeyExpr)) {
-                            break;
-                        }
-                        couldntFigureOut = true;
-                        doneWithExprs = true;
-                    }
-                    break;
-                }
-                case LOW_EXCLUSIVE: {
-                    if (lowKeyLimits[keyPos] == null || (lowKeyLimits[keyPos] != null && lowKeyInclusive[keyPos])) {
-                        lowKeyLimits[keyPos] = limit;
-                        lowKeyExprs[keyPos] = searchKeyExpr;
-                        lowKeyInclusive[keyPos] = false;
-                    } else {
-                        // Has already been set to the identical values. When optimizing join we may encounter the same optimizable expression twice
-                        // (once from analyzing each side of the join)
-                        if (lowKeyLimits[keyPos] == limit && lowKeyInclusive[keyPos] == false
-                                && lowKeyExprs[keyPos].equals(searchKeyExpr)) {
-                            break;
-                        }
-                        couldntFigureOut = true;
-                        doneWithExprs = true;
-                    }
-                    break;
-                }
-                case LOW_INCLUSIVE: {
-                    if (lowKeyLimits[keyPos] == null) {
-                        lowKeyLimits[keyPos] = limit;
-                        lowKeyExprs[keyPos] = searchKeyExpr;
-                        lowKeyInclusive[keyPos] = true;
-                    } else {
-                        // Has already been set to the identical values. When optimizing join we may encounter the same optimizable expression twice
-                        // (once from analyzing each side of the join)
-                        if (lowKeyLimits[keyPos] == limit && lowKeyInclusive[keyPos] == true
-                                && lowKeyExprs[keyPos].equals(searchKeyExpr)) {
-                            break;
-                        }
-                        couldntFigureOut = true;
-                        doneWithExprs = true;
-                    }
-                    break;
-                }
-                default: {
-                    throw new IllegalStateException();
-                }
-            }
-            if (!couldntFigureOut) {
-                // Remember to remove this funcExpr later.
-                replacedFuncExprs.add(matchedFuncExprs.get(exprIndex.first).getFuncExpr());
-            }
-            if (doneWithExprs) {
-                break;
-            }
-        }
-        if (couldntFigureOut) {
-            return null;
-        }
-
-        // If the select condition contains mixed open/closed intervals on multiple keys, then we make all intervals closed to obtain a superset of answers and leave the original selection in place.
-        boolean primaryIndexPostProccessingIsNeeded = false;
-        for (int i = 1; i < numSecondaryKeys; ++i) {
-            if (lowKeyInclusive[i] != lowKeyInclusive[0]) {
-                Arrays.fill(lowKeyInclusive, true);
-                primaryIndexPostProccessingIsNeeded = true;
-                break;
-            }
-        }
-        for (int i = 1; i < numSecondaryKeys; ++i) {
-            if (highKeyInclusive[i] != highKeyInclusive[0]) {
-                Arrays.fill(highKeyInclusive, true);
-                primaryIndexPostProccessingIsNeeded = true;
-                break;
-            }
-        }
-
-        // determine cases when prefix search could be applied
-        for (int i = 1; i < lowKeyExprs.length; i++) {
-            if (lowKeyLimits[0] == null && lowKeyLimits[i] != null || lowKeyLimits[0] != null
-                    && lowKeyLimits[i] == null || highKeyLimits[0] == null && highKeyLimits[i] != null
-                    || highKeyLimits[0] != null && highKeyLimits[i] == null) {
-                numSecondaryKeys--;
-                primaryIndexPostProccessingIsNeeded = true;
-            }
-        }
-        if (lowKeyLimits[0] == null) {
-            lowKeyInclusive[0] = true;
-        }
-        if (highKeyLimits[0] == null) {
-            highKeyInclusive[0] = true;
-        }
-
-        // Here we generate vars and funcs for assigning the secondary-index keys to be fed into the secondary-index search.
-        // List of variables for the assign.
-        ArrayList<LogicalVariable> keyVarList = new ArrayList<LogicalVariable>();
-        // List of variables and expressions for the assign.
-        ArrayList<LogicalVariable> assignKeyVarList = new ArrayList<LogicalVariable>();
-        ArrayList<Mutable<ILogicalExpression>> assignKeyExprList = new ArrayList<Mutable<ILogicalExpression>>();
-        int numLowKeys = createKeyVarsAndExprs(numSecondaryKeys, lowKeyLimits, lowKeyExprs, assignKeyVarList,
-                assignKeyExprList, keyVarList, context);
-        int numHighKeys = createKeyVarsAndExprs(numSecondaryKeys, highKeyLimits, highKeyExprs, assignKeyVarList,
-                assignKeyExprList, keyVarList, context);
-
-        BTreeJobGenParams jobGenParams = new BTreeJobGenParams(chosenIndex.getIndexName(), IndexType.BTREE,
-                dataset.getDataverseName(), dataset.getDatasetName(), retainInput, retainNull, requiresBroadcast);
-        jobGenParams.setLowKeyInclusive(lowKeyInclusive[0]);
-        jobGenParams.setHighKeyInclusive(highKeyInclusive[0]);
-        jobGenParams.setIsEqCondition(isEqCondition);
-        jobGenParams.setLowKeyVarList(keyVarList, 0, numLowKeys);
-        jobGenParams.setHighKeyVarList(keyVarList, numLowKeys, numHighKeys);
-
-        ILogicalOperator inputOp = null;
-        if (!assignKeyVarList.isEmpty()) {
-            // Assign operator that sets the constant secondary-index search-key fields if necessary.
-            AssignOperator assignConstantSearchKeys = new AssignOperator(assignKeyVarList, assignKeyExprList);
-            // Input to this assign is the EmptyTupleSource (which the dataSourceScan also must have had as input).
-            assignConstantSearchKeys.getInputs().add(dataSourceOp.getInputs().get(0));
-            assignConstantSearchKeys.setExecutionMode(dataSourceOp.getExecutionMode());
-            inputOp = assignConstantSearchKeys;
-        } else {
-            // All index search keys are variables.
-            inputOp = probeSubTree.root;
-        }
-
-        UnnestMapOperator secondaryIndexUnnestOp = AccessMethodUtils.createSecondaryIndexUnnestMap(dataset, recordType,
-                chosenIndex, inputOp, jobGenParams, context, false, retainInput);
-
-        // Generate the rest of the upstream plan which feeds the search results into the primary index.
-        UnnestMapOperator primaryIndexUnnestOp = null;
-        boolean isPrimaryIndex = chosenIndex.isPrimaryIndex();
-        if (dataset.getDatasetType() == DatasetType.EXTERNAL) {
-            // External dataset
-            ExternalDataLookupOperator externalDataAccessOp = AccessMethodUtils.createExternalDataLookupUnnestMap(
-                    dataSourceOp, dataset, recordType, secondaryIndexUnnestOp, context, chosenIndex, retainInput,
-                    retainNull);
-            indexSubTree.dataSourceRef.setValue(externalDataAccessOp);
-            return externalDataAccessOp;
-        } else if (!isPrimaryIndex) {
-            primaryIndexUnnestOp = AccessMethodUtils.createPrimaryIndexUnnestMap(dataSourceOp, dataset, recordType,
-                    secondaryIndexUnnestOp, context, true, retainInput, retainNull, false);
-
-            // Replace the datasource scan with the new plan rooted at
-            // primaryIndexUnnestMap.
-            indexSubTree.dataSourceRef.setValue(primaryIndexUnnestOp);
-        } else {
-            List<Object> primaryIndexOutputTypes = new ArrayList<Object>();
-            try {
-                AccessMethodUtils.appendPrimaryIndexTypes(dataset, recordType, primaryIndexOutputTypes);
-            } catch (IOException e) {
-                throw new AlgebricksException(e);
-            }
-            List<LogicalVariable> scanVariables = dataSourceOp.getVariables();
-            primaryIndexUnnestOp = new UnnestMapOperator(scanVariables, secondaryIndexUnnestOp.getExpressionRef(),
-                    primaryIndexOutputTypes, retainInput);
-            primaryIndexUnnestOp.getInputs().add(new MutableObject<ILogicalOperator>(inputOp));
-
-            if (!primaryIndexPostProccessingIsNeeded) {
-                List<Mutable<ILogicalExpression>> remainingFuncExprs = new ArrayList<Mutable<ILogicalExpression>>();
-                getNewConditionExprs(conditionRef, replacedFuncExprs, remainingFuncExprs);
-                // Generate new condition.
-                if (!remainingFuncExprs.isEmpty()) {
-                    ILogicalExpression pulledCond = createSelectCondition(remainingFuncExprs);
-                    conditionRef.setValue(pulledCond);
-                } else {
-                    conditionRef.setValue(null);
-                }
-            }
-
-            // Adds equivalence classes --- one equivalent class between a primary key
-            // variable and a record field-access expression.
-            EquivalenceClassUtils.addEquivalenceClassesForPrimaryIndexAccess(primaryIndexUnnestOp, scanVariables,
-                    recordType, dataset, context);
-        }
-
-        return primaryIndexUnnestOp;
-    }
-
-    private int createKeyVarsAndExprs(int numKeys, LimitType[] keyLimits, ILogicalExpression[] searchKeyExprs,
-            ArrayList<LogicalVariable> assignKeyVarList, ArrayList<Mutable<ILogicalExpression>> assignKeyExprList,
-            ArrayList<LogicalVariable> keyVarList, IOptimizationContext context) {
-        if (keyLimits[0] == null) {
-            return 0;
-        }
-        for (int i = 0; i < numKeys; i++) {
-            ILogicalExpression searchKeyExpr = searchKeyExprs[i];
-            LogicalVariable keyVar = null;
-            if (searchKeyExpr.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
-                keyVar = context.newVar();
-                assignKeyExprList.add(new MutableObject<ILogicalExpression>(searchKeyExpr));
-                assignKeyVarList.add(keyVar);
-            } else {
-                keyVar = ((VariableReferenceExpression) searchKeyExpr).getVariableReference();
-            }
-            keyVarList.add(keyVar);
-        }
-        return numKeys;
-    }
-
-    private void getNewConditionExprs(Mutable<ILogicalExpression> conditionRef,
-            Set<ILogicalExpression> replacedFuncExprs, List<Mutable<ILogicalExpression>> remainingFuncExprs) {
-        remainingFuncExprs.clear();
-        if (replacedFuncExprs.isEmpty()) {
-            return;
-        }
-        AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) conditionRef.getValue();
-        if (replacedFuncExprs.size() == 1) {
-            Iterator<ILogicalExpression> it = replacedFuncExprs.iterator();
-            if (!it.hasNext()) {
-                return;
-            }
-            if (funcExpr == it.next()) {
-                // There are no remaining function exprs.
-                return;
-            }
-        }
-        // The original select cond must be an AND. Check it just to be sure.
-        if (funcExpr.getFunctionIdentifier() != AlgebricksBuiltinFunctions.AND) {
-            throw new IllegalStateException();
-        }
-        // Clean the conjuncts.
-        for (Mutable<ILogicalExpression> arg : funcExpr.getArguments()) {
-            ILogicalExpression argExpr = arg.getValue();
-            if (argExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
-                continue;
-            }
-            // If the function expression was not replaced by the new index
-            // plan, then add it to the list of remaining function expressions.
-            if (!replacedFuncExprs.contains(argExpr)) {
-                remainingFuncExprs.add(arg);
-            }
-        }
-    }
-
-    private <T> int indexOf(T value, List<T> coll) {
-        int i = 0;
-        for (T member : coll) {
-            if (member.equals(value)) {
-                return i;
-            }
-            i++;
-        }
-        return -1;
-    }
-
-    private LimitType getLimitType(IOptimizableFuncExpr optFuncExpr, OptimizableOperatorSubTree probeSubTree) {
-        ComparisonKind ck = AlgebricksBuiltinFunctions.getComparisonType(optFuncExpr.getFuncExpr()
-                .getFunctionIdentifier());
-        LimitType limit = null;
-        switch (ck) {
-            case EQ: {
-                limit = LimitType.EQUAL;
-                break;
-            }
-            case GE: {
-                limit = probeIsOnLhs(optFuncExpr, probeSubTree) ? LimitType.HIGH_INCLUSIVE : LimitType.LOW_INCLUSIVE;
-                break;
-            }
-            case GT: {
-                limit = probeIsOnLhs(optFuncExpr, probeSubTree) ? LimitType.HIGH_EXCLUSIVE : LimitType.LOW_EXCLUSIVE;
-                break;
-            }
-            case LE: {
-                limit = probeIsOnLhs(optFuncExpr, probeSubTree) ? LimitType.LOW_INCLUSIVE : LimitType.HIGH_INCLUSIVE;
-                break;
-            }
-            case LT: {
-                limit = probeIsOnLhs(optFuncExpr, probeSubTree) ? LimitType.LOW_EXCLUSIVE : LimitType.HIGH_EXCLUSIVE;
-                break;
-            }
-            case NEQ: {
-                limit = null;
-                break;
-            }
-            default: {
-                throw new IllegalStateException();
-            }
-        }
-        return limit;
-    }
-
-    private boolean probeIsOnLhs(IOptimizableFuncExpr optFuncExpr, OptimizableOperatorSubTree probeSubTree) {
-        if (probeSubTree == null) {
-            // We are optimizing a selection query. Search key is a constant. Return true if constant is on lhs.
-            return optFuncExpr.getFuncExpr().getArguments().get(0) == optFuncExpr.getConstantVal(0);
-        } else {
-            // We are optimizing a join query. Determine whether the feeding variable is on the lhs.
-            return (optFuncExpr.getOperatorSubTree(0) == null || optFuncExpr.getOperatorSubTree(0) == probeSubTree);
-        }
-    }
-
-    private ILogicalExpression createSelectCondition(List<Mutable<ILogicalExpression>> predList) {
-        if (predList.size() > 1) {
-            IFunctionInfo finfo = FunctionUtils.getFunctionInfo(AlgebricksBuiltinFunctions.AND);
-            return new ScalarFunctionCallExpression(finfo, predList);
-        }
-        return predList.get(0).getValue();
-    }
-
-    @Override
-    public boolean exprIsOptimizable(Index index, IOptimizableFuncExpr optFuncExpr) {
-        // If we are optimizing a join, check for the indexed nested-loop join hint.
-        if (optFuncExpr.getNumLogicalVars() == 2) {
-            if (!optFuncExpr.getFuncExpr().getAnnotations().containsKey(IndexedNLJoinExpressionAnnotation.INSTANCE)) {
-                return false;
-            }
-        }
-        if (!index.isPrimaryIndex()
-                && optFuncExpr.getFuncExpr().getAnnotations()
-                        .containsKey(SkipSecondaryIndexSearchExpressionAnnotation.INSTANCE)) {
-            return false;
-        }
-        // No additional analysis required for BTrees.
-        return true;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/BTreeJobGenParams.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/BTreeJobGenParams.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/BTreeJobGenParams.java
deleted file mode 100644
index a3df9d3..0000000
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/BTreeJobGenParams.java
+++ /dev/null
@@ -1,134 +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.am;
-
-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.common.config.DatasetConfig.IndexType;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
-
-/**
- * Helper class for reading and writing job-gen parameters for BTree access methods to
- * and from a list of function arguments, typically of an unnest-map.
- */
-public class BTreeJobGenParams extends AccessMethodJobGenParams {
-
-    protected List<LogicalVariable> lowKeyVarList;
-    protected List<LogicalVariable> highKeyVarList;
-
-    protected boolean lowKeyInclusive;
-    protected boolean highKeyInclusive;
-    protected boolean isEqCondition;
-
-    public BTreeJobGenParams() {
-        super();
-    }
-
-    public BTreeJobGenParams(String indexName, IndexType indexType, String dataverseName, String datasetName,
-            boolean retainInput, boolean retainNull, boolean requiresBroadcast) {
-        super(indexName, indexType, dataverseName, datasetName, retainInput, retainNull, requiresBroadcast);
-    }
-
-    public void setLowKeyVarList(List<LogicalVariable> keyVarList, int startIndex, int numKeys) {
-        lowKeyVarList = new ArrayList<LogicalVariable>(numKeys);
-        setKeyVarList(keyVarList, lowKeyVarList, startIndex, numKeys);
-    }
-
-    public void setHighKeyVarList(List<LogicalVariable> keyVarList, int startIndex, int numKeys) {
-        highKeyVarList = new ArrayList<LogicalVariable>(numKeys);
-        setKeyVarList(keyVarList, highKeyVarList, startIndex, numKeys);
-    }
-
-    private void setKeyVarList(List<LogicalVariable> src, List<LogicalVariable> dest, int startIndex, int numKeys) {
-        for (int i = 0; i < numKeys; i++) {
-            dest.add(src.get(startIndex + i));
-        }
-    }
-
-    public void setLowKeyInclusive(boolean lowKeyInclusive) {
-        this.lowKeyInclusive = lowKeyInclusive;
-    }
-
-    public void setHighKeyInclusive(boolean highKeyInclusive) {
-        this.highKeyInclusive = highKeyInclusive;
-    }
-
-    public void setIsEqCondition(boolean isEqConsition) {
-        this.isEqCondition = isEqConsition;
-    }
-
-    public void writeToFuncArgs(List<Mutable<ILogicalExpression>> funcArgs) {
-        super.writeToFuncArgs(funcArgs);
-        writeVarList(lowKeyVarList, funcArgs);
-        writeVarList(highKeyVarList, funcArgs);
-        writeBoolean(lowKeyInclusive, funcArgs);
-        writeBoolean(highKeyInclusive, funcArgs);
-        writeBoolean(isEqCondition, funcArgs);
-    }
-
-    public void readFromFuncArgs(List<Mutable<ILogicalExpression>> funcArgs) {
-        super.readFromFuncArgs(funcArgs);
-        int index = super.getNumParams();
-        lowKeyVarList = new ArrayList<LogicalVariable>();
-        highKeyVarList = new ArrayList<LogicalVariable>();
-        int nextIndex = readVarList(funcArgs, index, lowKeyVarList);
-        nextIndex = readVarList(funcArgs, nextIndex, highKeyVarList);
-        nextIndex = readKeyInclusives(funcArgs, nextIndex);
-        readIsEqCondition(funcArgs, nextIndex);
-    }
-
-    private int readKeyInclusives(List<Mutable<ILogicalExpression>> funcArgs, int index) {
-        lowKeyInclusive = ((ConstantExpression) funcArgs.get(index).getValue()).getValue().isTrue();
-        // Read the next function argument at index + 1.
-        highKeyInclusive = ((ConstantExpression) funcArgs.get(index + 1).getValue()).getValue().isTrue();
-        // We have read two of the function arguments, so the next index is at index + 2.
-        return index + 2;
-    }
-
-    private void readIsEqCondition(List<Mutable<ILogicalExpression>> funcArgs, int index) {
-        isEqCondition = ((ConstantExpression) funcArgs.get(index).getValue()).getValue().isTrue();
-    }
-
-    private void writeBoolean(boolean val, List<Mutable<ILogicalExpression>> funcArgs) {
-        ILogicalExpression keyExpr = val ? ConstantExpression.TRUE : ConstantExpression.FALSE;
-        funcArgs.add(new MutableObject<ILogicalExpression>(keyExpr));
-    }
-
-    public List<LogicalVariable> getLowKeyVarList() {
-        return lowKeyVarList;
-    }
-
-    public List<LogicalVariable> getHighKeyVarList() {
-        return highKeyVarList;
-    }
-
-    public boolean isEqCondition() {
-        return isEqCondition;
-    }
-
-    public boolean isLowKeyInclusive() {
-        return lowKeyInclusive;
-    }
-
-    public boolean isHighKeyInclusive() {
-        return highKeyInclusive;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IAccessMethod.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IAccessMethod.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IAccessMethod.java
deleted file mode 100644
index d03d1a0..0000000
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IAccessMethod.java
+++ /dev/null
@@ -1,96 +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.am;
-
-import java.util.List;
-
-import org.apache.commons.lang3.mutable.Mutable;
-
-import edu.uci.ics.asterix.metadata.entities.Index;
-import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
-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.expressions.AbstractFunctionCallExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-
-/**
- * Interface that an access method should implement to work with the rewrite
- * rules to apply it for join and/or selection queries. This interface provides
- * methods for analyzing a select/join condition, and for rewriting the plan
- * with a given index.
- */
-public interface IAccessMethod {
-
-    /**
-     * @return A list of function identifiers that are optimizable by this
-     *         access method.
-     */
-    public List<FunctionIdentifier> getOptimizableFunctions();
-
-    /**
-     * Analyzes the arguments of a given optimizable funcExpr to see if this
-     * access method is applicable (e.g., one arg is a constant and one is a
-     * var). We assume that the funcExpr has already been determined to be
-     * optimizable by this access method based on its function identifier. If
-     * funcExpr has been found to be optimizable, this method adds an
-     * OptimizableFunction to analysisCtx.matchedFuncExprs for further analysis.
-     *
-     * @return true if funcExpr is optimizable by this access method, false
-     *         otherwise
-     */
-    public boolean analyzeFuncExprArgs(AbstractFunctionCallExpression funcExpr,
-            List<AbstractLogicalOperator> assignsAndUnnests, AccessMethodAnalysisContext analysisCtx);
-
-    /**
-     * Indicates whether all index expressions must be matched in order for this
-     * index to be applicable.
-     *
-     * @return boolean
-     */
-    public boolean matchAllIndexExprs();
-
-    /**
-     * Indicates whether this index is applicable if only a prefix of the index
-     * expressions are matched.
-     *
-     * @return boolean
-     */
-    public boolean matchPrefixIndexExprs();
-
-    /**
-     * Applies the plan transformation to use chosenIndex to optimize a selection query.
-     */
-    public boolean applySelectPlanTransformation(Mutable<ILogicalOperator> selectRef,
-            OptimizableOperatorSubTree subTree, Index chosenIndex, AccessMethodAnalysisContext analysisCtx,
-            IOptimizationContext context) throws AlgebricksException;
-
-    /**
-     * Applies the plan transformation to use chosenIndex to optimize a join query.
-     * In the case of a LeftOuterJoin, there may or may not be a needed groupby operation
-     * If there is, we will need to include it in the transformation
-     */
-    public boolean applyJoinPlanTransformation(Mutable<ILogicalOperator> joinRef,
-            OptimizableOperatorSubTree leftSubTree, OptimizableOperatorSubTree rightSubTree, Index chosenIndex,
-            AccessMethodAnalysisContext analysisCtx, IOptimizationContext context, boolean isLeftOuterJoin,
-            boolean hasGroupBy) throws AlgebricksException;
-
-    /**
-     * Analyzes expr to see whether it is optimizable by the given concrete index.
-     * 
-     * @throws AlgebricksException
-     */
-    public boolean exprIsOptimizable(Index index, IOptimizableFuncExpr optFuncExpr) throws AlgebricksException;
-}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IOptimizableFuncExpr.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IOptimizableFuncExpr.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IOptimizableFuncExpr.java
deleted file mode 100644
index 326d38b..0000000
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IOptimizableFuncExpr.java
+++ /dev/null
@@ -1,70 +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.am;
-
-import java.util.List;
-
-import edu.uci.ics.asterix.om.types.IAType;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-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.IAlgebricksConstantValue;
-
-/**
- * Describes a function expression that is optimizable by an access method.
- * Provides convenient methods for accessing arguments (constants, variables)
- * and metadata of such a function.
- */
-public interface IOptimizableFuncExpr {
-    public AbstractFunctionCallExpression getFuncExpr();
-
-    public int getNumLogicalVars();
-
-    public int getNumConstantVals();
-
-    public LogicalVariable getLogicalVar(int index);
-
-    public void setLogicalExpr(int index, ILogicalExpression logExpr);
-
-    public ILogicalExpression getLogicalExpr(int index);
-
-    public void setFieldName(int index, List<String> fieldName);
-
-    public List<String> getFieldName(int index);
-
-    public void setFieldType(int index, IAType fieldName);
-
-    public IAType getFieldType(int index);
-
-    public void setOptimizableSubTree(int index, OptimizableOperatorSubTree subTree);
-
-    public OptimizableOperatorSubTree getOperatorSubTree(int index);
-
-    public IAlgebricksConstantValue getConstantVal(int index);
-
-    public int findLogicalVar(LogicalVariable var);
-
-    public int findFieldName(List<String> fieldName);
-
-    public void substituteVar(LogicalVariable original, LogicalVariable substitution);
-
-    public void setPartialField(boolean partialField);
-
-    public boolean containsPartialField();
-
-    public void setSourceVar(int index, LogicalVariable var);
-
-    public LogicalVariable getSourceVar(int index);
-}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IntroduceJoinAccessMethodRule.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IntroduceJoinAccessMethodRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IntroduceJoinAccessMethodRule.java
deleted file mode 100644
index 7d93ecc..0000000
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IntroduceJoinAccessMethodRule.java
+++ /dev/null
@@ -1,246 +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.am;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.lang3.mutable.Mutable;
-
-import edu.uci.ics.asterix.metadata.declared.AqlMetadataProvider;
-import edu.uci.ics.asterix.metadata.entities.Index;
-import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
-import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
-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.expressions.AbstractFunctionCallExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
-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.GroupByOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
-
-/**
- * This rule optimizes a join with secondary indexes into an indexed nested-loop join.
- * Matches the following operator pattern:
- * (join) <-- (select)? <-- (assign | unnest)+ <-- (datasource scan)
- * <-- (select)? <-- (assign | unnest)+ <-- (datasource scan | unnest-map)
- * The order of the join inputs does not matter.
- * Replaces the above pattern with the following simplified plan:
- * (select) <-- (assign) <-- (btree search) <-- (sort) <-- (unnest(index search)) <-- (assign) <-- (datasource scan | unnest-map)
- * The sort is optional, and some access methods may choose not to sort.
- * Note that for some index-based optimizations we do not remove the triggering
- * condition from the join, since the secondary index may only act as a filter, and the
- * final verification must still be done with the original join condition.
- * The basic outline of this rule is:
- * 1. Match operator pattern.
- * 2. Analyze join condition to see if there are optimizable functions (delegated to IAccessMethods).
- * 3. Check metadata to see if there are applicable indexes.
- * 4. Choose an index to apply (for now only a single index will be chosen).
- * 5. Rewrite plan using index (delegated to IAccessMethods).
- * For left-outer-join, additional patterns are checked and additional treatment is needed as follows:
- * 1. First it checks if there is a groupByOp above the join: (groupby) <-- (leftouterjoin)
- * 2. Inherently, only the right-subtree of the lojOp can be used as indexSubtree.
- * So, the right-subtree must have at least one applicable index on join field(s)
- * 3. If there is a groupByOp, the null placeholder variable introduced in groupByOp should be taken care of correctly.
- * Here, the primary key variable from datasourceScanOp replaces the introduced null placeholder variable.
- * If the primary key is composite key, then the first variable of the primary key variables becomes the
- * null place holder variable. This null placeholder variable works for all three types of indexes.
- */
-public class IntroduceJoinAccessMethodRule extends AbstractIntroduceAccessMethodRule {
-
-    protected Mutable<ILogicalOperator> joinRef = null;
-    protected AbstractBinaryJoinOperator join = null;
-    protected AbstractFunctionCallExpression joinCond = null;
-    protected final OptimizableOperatorSubTree leftSubTree = new OptimizableOperatorSubTree();
-    protected final OptimizableOperatorSubTree rightSubTree = new OptimizableOperatorSubTree();
-    protected boolean isLeftOuterJoin = false;
-    protected boolean hasGroupBy = true;
-
-    // Register access methods.
-    protected static Map<FunctionIdentifier, List<IAccessMethod>> accessMethods = new HashMap<FunctionIdentifier, List<IAccessMethod>>();
-    static {
-        registerAccessMethod(BTreeAccessMethod.INSTANCE, accessMethods);
-        registerAccessMethod(RTreeAccessMethod.INSTANCE, accessMethods);
-        registerAccessMethod(InvertedIndexAccessMethod.INSTANCE, accessMethods);
-    }
-
-    @Override
-    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
-            throws AlgebricksException {
-        clear();
-        setMetadataDeclarations(context);
-
-        // Match operator pattern and initialize optimizable sub trees.
-        if (!matchesOperatorPattern(opRef, context)) {
-            return false;
-        }
-        // Analyze condition on those optimizable subtrees that have a datasource scan.
-        Map<IAccessMethod, AccessMethodAnalysisContext> analyzedAMs = new HashMap<IAccessMethod, AccessMethodAnalysisContext>();
-        boolean matchInLeftSubTree = false;
-        boolean matchInRightSubTree = false;
-        if (leftSubTree.hasDataSource()) {
-            matchInLeftSubTree = analyzeCondition(joinCond, leftSubTree.assignsAndUnnests, analyzedAMs);
-        }
-        if (rightSubTree.hasDataSource()) {
-            matchInRightSubTree = analyzeCondition(joinCond, rightSubTree.assignsAndUnnests, analyzedAMs);
-        }
-        if (!matchInLeftSubTree && !matchInRightSubTree) {
-            return false;
-        }
-
-        // Set dataset and type metadata.
-        AqlMetadataProvider metadataProvider = (AqlMetadataProvider) context.getMetadataProvider();
-        boolean checkLeftSubTreeMetadata = false;
-        boolean checkRightSubTreeMetadata = false;
-        if (matchInLeftSubTree) {
-            checkLeftSubTreeMetadata = leftSubTree.setDatasetAndTypeMetadata(metadataProvider);
-        }
-        if (matchInRightSubTree) {
-            checkRightSubTreeMetadata = rightSubTree.setDatasetAndTypeMetadata(metadataProvider);
-        }
-        if (!checkLeftSubTreeMetadata && !checkRightSubTreeMetadata) {
-            return false;
-        }
-        if (checkLeftSubTreeMetadata) {
-            fillSubTreeIndexExprs(leftSubTree, analyzedAMs, context);
-        }
-        if (checkRightSubTreeMetadata) {
-            fillSubTreeIndexExprs(rightSubTree, analyzedAMs, context);
-        }
-        pruneIndexCandidates(analyzedAMs);
-
-        //Remove possibly chosen indexes from left Tree
-        if (isLeftOuterJoin) {
-            Iterator<Map.Entry<IAccessMethod, AccessMethodAnalysisContext>> amIt = analyzedAMs.entrySet().iterator();
-            // Check applicability of indexes by access method type.
-            while (amIt.hasNext()) {
-                Map.Entry<IAccessMethod, AccessMethodAnalysisContext> entry = amIt.next();
-                AccessMethodAnalysisContext amCtx = entry.getValue();
-                Iterator<Map.Entry<Index, List<Pair<Integer, Integer>>>> indexIt = amCtx.indexExprsAndVars.entrySet()
-                        .iterator();
-                while (indexIt.hasNext()) {
-                    Map.Entry<Index, List<Pair<Integer, Integer>>> indexEntry = indexIt.next();
-
-                    Index chosenIndex = indexEntry.getKey();
-                    if (!chosenIndex.getDatasetName().equals(rightSubTree.dataset.getDatasetName())) {
-                        indexIt.remove();
-                    }
-                }
-            }
-        }
-
-        // Choose index to be applied.
-        Pair<IAccessMethod, Index> chosenIndex = chooseIndex(analyzedAMs);
-        if (chosenIndex == null) {
-            context.addToDontApplySet(this, join);
-            return false;
-        }
-
-        // Apply plan transformation using chosen index.
-        AccessMethodAnalysisContext analysisCtx = analyzedAMs.get(chosenIndex.first);
-
-        //For LOJ with GroupBy, prepare objects to reset LOJ nullPlaceHolderVariable in GroupByOp
-        if (isLeftOuterJoin && hasGroupBy) {
-            analysisCtx.setLOJGroupbyOpRef(opRef);
-            ScalarFunctionCallExpression isNullFuncExpr = AccessMethodUtils
-                    .findLOJIsNullFuncInGroupBy((GroupByOperator) opRef.getValue());
-            analysisCtx.setLOJIsNullFuncInGroupBy(isNullFuncExpr);
-        }
-        boolean res = chosenIndex.first.applyJoinPlanTransformation(joinRef, leftSubTree, rightSubTree,
-                chosenIndex.second, analysisCtx, context, isLeftOuterJoin, hasGroupBy);
-        if (res) {
-            OperatorPropertiesUtil.typeOpRec(opRef, context);
-        }
-        context.addToDontApplySet(this, join);
-        return res;
-    }
-
-    protected boolean matchesOperatorPattern(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
-        // First check that the operator is a join and its condition is a function call.
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
-        if (context.checkIfInDontApplySet(this, op1)) {
-            return false;
-        }
-
-        boolean isInnerJoin = isInnerJoin(op1);
-        isLeftOuterJoin = isLeftOuterJoin(op1);
-
-        if (!isInnerJoin && !isLeftOuterJoin) {
-            return false;
-        }
-
-        // Set and analyze select.
-        if (isInnerJoin) {
-            joinRef = opRef;
-            join = (InnerJoinOperator) op1;
-        } else {
-            joinRef = op1.getInputs().get(0);
-            join = (LeftOuterJoinOperator) joinRef.getValue();
-        }
-
-        // Check that the select's condition is a function call.
-        ILogicalExpression condExpr = join.getCondition().getValue();
-        if (condExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
-            return false;
-        }
-        joinCond = (AbstractFunctionCallExpression) condExpr;
-        leftSubTree.initFromSubTree(join.getInputs().get(0));
-        rightSubTree.initFromSubTree(join.getInputs().get(1));
-        // One of the subtrees must have a datasource scan.
-        if (leftSubTree.hasDataSourceScan() || rightSubTree.hasDataSourceScan()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean isLeftOuterJoin(AbstractLogicalOperator op1) {
-        if (op1.getInputs().size() != 1) {
-            return false;
-        }
-        if (((AbstractLogicalOperator) op1.getInputs().get(0).getValue()).getOperatorTag() != LogicalOperatorTag.LEFTOUTERJOIN) {
-            return false;
-        }
-        if (op1.getOperatorTag() == LogicalOperatorTag.GROUP) {
-            return true;
-        }
-        hasGroupBy = false;
-        return true;
-    }
-
-    private boolean isInnerJoin(AbstractLogicalOperator op1) {
-        return op1.getOperatorTag() == LogicalOperatorTag.INNERJOIN;
-    }
-
-    @Override
-    public Map<FunctionIdentifier, List<IAccessMethod>> getAccessMethods() {
-        return accessMethods;
-    }
-
-    private void clear() {
-        joinRef = null;
-        join = null;
-        joinCond = null;
-        isLeftOuterJoin = false;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/34d81630/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java
----------------------------------------------------------------------
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java
deleted file mode 100644
index e441a20..0000000
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java
+++ /dev/null
@@ -1,451 +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.am;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.commons.lang3.mutable.Mutable;
-import org.apache.commons.lang3.mutable.MutableObject;
-
-import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
-import edu.uci.ics.asterix.metadata.declared.AqlDataSource;
-import edu.uci.ics.asterix.metadata.declared.AqlMetadataProvider;
-import edu.uci.ics.asterix.metadata.declared.DatasetDataSource;
-import edu.uci.ics.asterix.metadata.entities.Dataset;
-import edu.uci.ics.asterix.metadata.entities.Index;
-import edu.uci.ics.asterix.metadata.utils.DatasetUtils;
-import edu.uci.ics.asterix.om.base.AInt32;
-import edu.uci.ics.asterix.om.base.AString;
-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.IAType;
-import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
-import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
-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.AbstractLogicalExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
-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.AlgebricksBuiltinFunctions.ComparisonKind;
-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.algebra.operators.logical.DataSourceScanOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
-import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
-
-public class IntroduceLSMComponentFilterRule 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 {
-
-        if (!checkIfRuleIsApplicable(opRef, context)) {
-            return false;
-        }
-
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
-        ILogicalExpression condExpr = ((SelectOperator) op).getCondition().getValue();
-        AccessMethodAnalysisContext analysisCtx = analyzeCondition(condExpr);
-        if (analysisCtx.matchedFuncExprs.isEmpty()) {
-            return false;
-        }
-
-        Dataset dataset = getDataset(op, context);
-        List<String> filterFieldName = null;
-        ARecordType recType = null;
-        if (dataset != null && dataset.getDatasetType() == DatasetType.INTERNAL) {
-            filterFieldName = DatasetUtils.getFilterField(dataset);
-            IAType itemType = ((AqlMetadataProvider) context.getMetadataProvider()).findType(
-                    dataset.getDataverseName(), dataset.getItemTypeName());
-            if (itemType.getTypeTag() == ATypeTag.RECORD) {
-                recType = (ARecordType) itemType;
-            }
-        }
-        if (filterFieldName == null || recType == null) {
-            return false;
-        }
-        List<Index> datasetIndexes = ((AqlMetadataProvider) context.getMetadataProvider()).getDatasetIndexes(
-                dataset.getDataverseName(), dataset.getDatasetName());
-
-        List<IOptimizableFuncExpr> optFuncExprs = new ArrayList<IOptimizableFuncExpr>();
-
-        for (int i = 0; i < analysisCtx.matchedFuncExprs.size(); i++) {
-            IOptimizableFuncExpr optFuncExpr = analysisCtx.matchedFuncExprs.get(i);
-            boolean found = findMacthedExprFieldName(optFuncExpr, op, dataset, recType, datasetIndexes);
-            if (found && optFuncExpr.getFieldName(0).equals(filterFieldName)) {
-                optFuncExprs.add(optFuncExpr);
-            }
-        }
-        if (optFuncExprs.isEmpty()) {
-            return false;
-        }
-        changePlan(optFuncExprs, op, dataset, context);
-
-        OperatorPropertiesUtil.typeOpRec(opRef, context);
-        context.addToDontApplySet(this, op);
-        return true;
-    }
-
-    private AssignOperator createAssignOperator(List<IOptimizableFuncExpr> optFuncExprs,
-            List<LogicalVariable> minFilterVars, List<LogicalVariable> maxFilterVars, IOptimizationContext context) {
-        List<LogicalVariable> assignKeyVarList = new ArrayList<LogicalVariable>();
-        List<Mutable<ILogicalExpression>> assignKeyExprList = new ArrayList<Mutable<ILogicalExpression>>();
-
-        for (IOptimizableFuncExpr optFuncExpr : optFuncExprs) {
-            ComparisonKind ck = AlgebricksBuiltinFunctions.getComparisonType(optFuncExpr.getFuncExpr()
-                    .getFunctionIdentifier());
-            ILogicalExpression searchKeyExpr = new ConstantExpression(optFuncExpr.getConstantVal(0));
-            LogicalVariable var = context.newVar();
-            assignKeyExprList.add(new MutableObject<ILogicalExpression>(searchKeyExpr));
-            assignKeyVarList.add(var);
-            if (ck == ComparisonKind.GE || ck == ComparisonKind.GT) {
-                minFilterVars.add(var);
-            } else if (ck == ComparisonKind.LE || ck == ComparisonKind.LT) {
-                maxFilterVars.add(var);
-            } else if (ck == ComparisonKind.EQ) {
-                minFilterVars.add(var);
-                maxFilterVars.add(var);
-            }
-        }
-        return new AssignOperator(assignKeyVarList, assignKeyExprList);
-    }
-
-    private void changePlan(List<IOptimizableFuncExpr> optFuncExprs, AbstractLogicalOperator op, Dataset dataset,
-            IOptimizationContext context) throws AlgebricksException {
-
-        AbstractLogicalOperator descendantOp = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
-        while (descendantOp != null) {
-            if (descendantOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
-                DataSourceScanOperator dataSourceScanOp = (DataSourceScanOperator) descendantOp;
-                AqlDataSource ds = (AqlDataSource) dataSourceScanOp.getDataSource();
-                if (dataset.getDatasetName().compareTo(((DatasetDataSource) ds).getDataset().getDatasetName()) == 0) {
-                    List<LogicalVariable> minFilterVars = new ArrayList<LogicalVariable>();
-                    List<LogicalVariable> maxFilterVars = new ArrayList<LogicalVariable>();
-
-                    AssignOperator assignOp = createAssignOperator(optFuncExprs, minFilterVars, maxFilterVars, context);
-
-                    dataSourceScanOp.setMinFilterVars(minFilterVars);
-                    dataSourceScanOp.setMaxFilterVars(maxFilterVars);
-
-                    List<Mutable<ILogicalExpression>> additionalFilteringExpressions = new ArrayList<Mutable<ILogicalExpression>>();;
-                    for (LogicalVariable var : assignOp.getVariables()) {
-                        additionalFilteringExpressions.add(new MutableObject<ILogicalExpression>(
-                                new VariableReferenceExpression(var)));
-                    }
-
-                    dataSourceScanOp.setAdditionalFilteringExpressions(additionalFilteringExpressions);
-
-                    assignOp.getInputs().add(
-                            new MutableObject<ILogicalOperator>(dataSourceScanOp.getInputs().get(0).getValue()));
-                    dataSourceScanOp.getInputs().get(0).setValue(assignOp);
-                }
-            } else if (descendantOp.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
-                UnnestMapOperator unnestMapOp = (UnnestMapOperator) descendantOp;
-                ILogicalExpression unnestExpr = unnestMapOp.getExpressionRef().getValue();
-                if (unnestExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
-                    AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) unnestExpr;
-                    FunctionIdentifier fid = f.getFunctionIdentifier();
-                    if (!fid.equals(AsterixBuiltinFunctions.INDEX_SEARCH)) {
-                        throw new IllegalStateException();
-                    }
-                    AccessMethodJobGenParams jobGenParams = new AccessMethodJobGenParams();
-                    jobGenParams.readFromFuncArgs(f.getArguments());
-                    if (dataset.getDatasetName().compareTo(jobGenParams.datasetName) == 0) {
-                        List<LogicalVariable> minFilterVars = new ArrayList<LogicalVariable>();
-                        List<LogicalVariable> maxFilterVars = new ArrayList<LogicalVariable>();
-
-                        AssignOperator assignOp = createAssignOperator(optFuncExprs, minFilterVars, maxFilterVars,
-                                context);
-
-                        unnestMapOp.setMinFilterVars(minFilterVars);
-                        unnestMapOp.setMaxFilterVars(maxFilterVars);
-
-                        List<Mutable<ILogicalExpression>> additionalFilteringExpressions = new ArrayList<Mutable<ILogicalExpression>>();;
-                        for (LogicalVariable var : assignOp.getVariables()) {
-                            additionalFilteringExpressions.add(new MutableObject<ILogicalExpression>(
-                                    new VariableReferenceExpression(var)));
-                        }
-                        unnestMapOp.setAdditionalFilteringExpressions(additionalFilteringExpressions);
-                        assignOp.getInputs().add(
-                                new MutableObject<ILogicalOperator>(unnestMapOp.getInputs().get(0).getValue()));
-                        unnestMapOp.getInputs().get(0).setValue(assignOp);
-                    }
-                }
-            }
-            if (descendantOp.getInputs().isEmpty()) {
-                break;
-            }
-            descendantOp = (AbstractLogicalOperator) descendantOp.getInputs().get(0).getValue();
-        }
-    }
-
-    private Dataset getDataset(AbstractLogicalOperator op, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator descendantOp = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
-        while (descendantOp != null) {
-            if (descendantOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
-                DataSourceScanOperator dataSourceScanOp = (DataSourceScanOperator) descendantOp;
-                AqlDataSource ds = (AqlDataSource) dataSourceScanOp.getDataSource();
-                return ((DatasetDataSource) ds).getDataset();
-            } else if (descendantOp.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
-                UnnestMapOperator unnestMapOp = (UnnestMapOperator) descendantOp;
-                ILogicalExpression unnestExpr = unnestMapOp.getExpressionRef().getValue();
-                if (unnestExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
-                    AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) unnestExpr;
-                    FunctionIdentifier fid = f.getFunctionIdentifier();
-                    if (!fid.equals(AsterixBuiltinFunctions.INDEX_SEARCH)) {
-                        throw new IllegalStateException();
-                    }
-                    AccessMethodJobGenParams jobGenParams = new AccessMethodJobGenParams();
-                    jobGenParams.readFromFuncArgs(f.getArguments());
-                    return ((AqlMetadataProvider) context.getMetadataProvider()).findDataset(
-                            jobGenParams.dataverseName, jobGenParams.datasetName);
-                }
-            }
-            if (descendantOp.getInputs().isEmpty()) {
-                break;
-            }
-            descendantOp = (AbstractLogicalOperator) descendantOp.getInputs().get(0).getValue();
-        }
-        return null;
-    }
-
-    private boolean checkIfRuleIsApplicable(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
-        // First check that the operator is a select and its condition is a function call.
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
-        if (context.checkIfInDontApplySet(this, op)) {
-            return false;
-        }
-        if (op.getOperatorTag() != LogicalOperatorTag.SELECT) {
-            return false;
-        }
-
-        ILogicalExpression condExpr = ((SelectOperator) op).getCondition().getValue();
-        if (condExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
-            return false;
-        }
-        return true;
-    }
-
-    private AccessMethodAnalysisContext analyzeCondition(ILogicalExpression cond) {
-        AccessMethodAnalysisContext analysisCtx = new AccessMethodAnalysisContext();
-        AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) cond;
-        FunctionIdentifier funcIdent = funcExpr.getFunctionIdentifier();
-        if (funcIdent != AlgebricksBuiltinFunctions.OR) {
-            analyzeFunctionExpr(funcExpr, analysisCtx);
-            for (Mutable<ILogicalExpression> arg : funcExpr.getArguments()) {
-                ILogicalExpression argExpr = arg.getValue();
-                if (argExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
-                    continue;
-                }
-                analyzeFunctionExpr((AbstractFunctionCallExpression) argExpr, analysisCtx);
-            }
-        }
-        return analysisCtx;
-    }
-
-    private void analyzeFunctionExpr(AbstractFunctionCallExpression funcExpr, AccessMethodAnalysisContext analysisCtx) {
-        FunctionIdentifier funcIdent = funcExpr.getFunctionIdentifier();
-        if (funcIdent == AlgebricksBuiltinFunctions.LE || funcIdent == AlgebricksBuiltinFunctions.GE
-                || funcIdent == AlgebricksBuiltinFunctions.LT || funcIdent == AlgebricksBuiltinFunctions.GT
-                || funcIdent == AlgebricksBuiltinFunctions.EQ) {
-            AccessMethodUtils.analyzeFuncExprArgsForOneConstAndVar(funcExpr, analysisCtx);
-        }
-    }
-
-    private boolean findMacthedExprFieldName(IOptimizableFuncExpr optFuncExpr, AbstractLogicalOperator op,
-            Dataset dataset, ARecordType recType, List<Index> datasetIndexes) throws AlgebricksException {
-        AbstractLogicalOperator descendantOp = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
-        while (descendantOp != null) {
-            if (descendantOp.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
-                AssignOperator assignOp = (AssignOperator) descendantOp;
-                List<LogicalVariable> varList = assignOp.getVariables();
-                for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
-                    LogicalVariable var = varList.get(varIndex);
-                    int funcVarIndex = optFuncExpr.findLogicalVar(var);
-                    if (funcVarIndex == -1) {
-                        continue;
-                    }
-                    List<String> fieldName = getFieldNameFromSubAssignTree(optFuncExpr, descendantOp, varIndex, recType).second;
-                    if (fieldName == null) {
-                        return false;
-                    }
-                    optFuncExpr.setFieldName(funcVarIndex, fieldName);
-                    return true;
-                }
-            } else if (descendantOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
-                DataSourceScanOperator scanOp = (DataSourceScanOperator) descendantOp;
-                List<LogicalVariable> varList = scanOp.getVariables();
-                for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
-                    LogicalVariable var = varList.get(varIndex);
-                    int funcVarIndex = optFuncExpr.findLogicalVar(var);
-                    if (funcVarIndex == -1) {
-                        continue;
-                    }
-                    // The variable value is one of the partitioning fields.
-                    List<String> fieldName = DatasetUtils.getPartitioningKeys(dataset).get(varIndex);
-                    if (fieldName == null) {
-                        return false;
-                    }
-                    optFuncExpr.setFieldName(funcVarIndex, fieldName);
-                    return true;
-                }
-            } else if (descendantOp.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
-                UnnestMapOperator unnestMapOp = (UnnestMapOperator) descendantOp;
-                List<LogicalVariable> varList = unnestMapOp.getVariables();
-                for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
-                    LogicalVariable var = varList.get(varIndex);
-                    int funcVarIndex = optFuncExpr.findLogicalVar(var);
-                    if (funcVarIndex == -1) {
-                        continue;
-                    }
-
-                    String indexName = null;
-                    Index index = null;
-                    ILogicalExpression unnestExpr = unnestMapOp.getExpressionRef().getValue();
-                    if (unnestExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
-                        AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) unnestExpr;
-                        FunctionIdentifier fid = f.getFunctionIdentifier();
-                        if (!fid.equals(AsterixBuiltinFunctions.INDEX_SEARCH)) {
-                            throw new IllegalStateException();
-                        }
-                        AccessMethodJobGenParams jobGenParams = new AccessMethodJobGenParams();
-                        jobGenParams.readFromFuncArgs(f.getArguments());
-                        indexName = jobGenParams.indexName;
-                        for (Index idx : datasetIndexes) {
-                            if (idx.getIndexName().compareTo(indexName) == 0) {
-                                index = idx;
-                                break;
-                            }
-                        }
-                    }
-
-                    int numSecondaryKeys = AccessMethodUtils.getNumSecondaryKeys(index, recType);
-                    List<String> fieldName;
-                    if (varIndex >= numSecondaryKeys) {
-                        fieldName = DatasetUtils.getPartitioningKeys(dataset).get(varIndex - numSecondaryKeys);
-                    } else {
-                        fieldName = index.getKeyFieldNames().get(varIndex);
-                    }
-                    if (fieldName == null) {
-                        return false;
-                    }
-                    optFuncExpr.setFieldName(funcVarIndex, fieldName);
-                    return true;
-                }
-            }
-
-            if (descendantOp.getInputs().isEmpty()) {
-                break;
-            }
-            descendantOp = (AbstractLogicalOperator) descendantOp.getInputs().get(0).getValue();
-        }
-        return false;
-    }
-
-    private Pair<ARecordType, List<String>> getFieldNameFromSubAssignTree(IOptimizableFuncExpr optFuncExpr,
-            AbstractLogicalOperator op, int varIndex, ARecordType recType) {
-        AbstractLogicalExpression expr = null;
-        if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
-            AssignOperator assignOp = (AssignOperator) op;
-            expr = (AbstractLogicalExpression) assignOp.getExpressions().get(varIndex).getValue();
-        }
-        if (expr == null || expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
-            return null;
-        }
-        AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
-        FunctionIdentifier funcIdent = funcExpr.getFunctionIdentifier();
-        if (funcIdent == AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME
-                || funcIdent == AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX) {
-
-            //get the variable from here. Figure out which input it came from. Go to that input!!!
-            ArrayList<LogicalVariable> usedVars = new ArrayList<LogicalVariable>();
-            expr.getUsedVariables(usedVars);
-            LogicalVariable usedVar = usedVars.get(0);
-            List<String> returnList = new ArrayList<String>();
-
-            //Find the input that it came from
-            for (int varCheck = 0; varCheck < op.getInputs().size(); varCheck++) {
-                AbstractLogicalOperator nestedOp = (AbstractLogicalOperator) op.getInputs().get(varCheck).getValue();
-                if (nestedOp.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
-                    if (varCheck == op.getInputs().size() - 1) {
-
-                    }
-                } else {
-                    int nestedAssignVar = ((AssignOperator) nestedOp).getVariables().indexOf(usedVar);
-                    if (nestedAssignVar == -1) {
-                        continue;
-                    }
-                    //get the nested info from the lower input
-                    Pair<ARecordType, List<String>> lowerInfo = getFieldNameFromSubAssignTree(optFuncExpr,
-                            (AbstractLogicalOperator) op.getInputs().get(varCheck).getValue(), nestedAssignVar, recType);
-                    if (lowerInfo != null) {
-                        recType = lowerInfo.first;
-                        returnList = lowerInfo.second;
-                    }
-                }
-            }
-
-            if (funcIdent == AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME) {
-                ILogicalExpression nameArg = funcExpr.getArguments().get(1).getValue();
-                if (nameArg.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
-                    return null;
-                }
-                ConstantExpression constExpr = (ConstantExpression) nameArg;
-                returnList.addAll(Arrays.asList(((AString) ((AsterixConstantValue) constExpr.getValue()).getObject())
-                        .getStringValue()));
-                return new Pair<ARecordType, List<String>>(recType, returnList);
-            } else if (funcIdent == AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX) {
-                ILogicalExpression idxArg = funcExpr.getArguments().get(1).getValue();
-                if (idxArg.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
-                    return null;
-                }
-                ConstantExpression constExpr = (ConstantExpression) idxArg;
-                int fieldIndex = ((AInt32) ((AsterixConstantValue) constExpr.getValue()).getObject()).getIntegerValue();
-                returnList.addAll(Arrays.asList(recType.getFieldNames()[fieldIndex]));
-                IAType subType = recType.getFieldTypes()[fieldIndex];
-                if (subType.getTypeTag() == ATypeTag.RECORD) {
-                    recType = (ARecordType) subType;
-                }
-                return new Pair<ARecordType, List<String>>(recType, returnList);
-            }
-
-        }
-
-        ILogicalExpression argExpr = funcExpr.getArguments().get(0).getValue();
-        if (argExpr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
-            return null;
-        }
-
-        return null;
-    }
-}
\ No newline at end of file