Example usage for org.apache.commons.lang3.mutable Mutable getValue

List of usage examples for org.apache.commons.lang3.mutable Mutable getValue

Introduction

In this page you can find the example usage for org.apache.commons.lang3.mutable Mutable getValue.

Prototype

T getValue();

Source Link

Document

Gets the value of this mutable.

Usage

From source file:edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil.java

public static void typeOpRec(Mutable<ILogicalOperator> r, IOptimizationContext context)
        throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) r.getValue();
    for (Mutable<ILogicalOperator> i : op.getInputs()) {
        typeOpRec(i, context);// w  w  w . j a  va  2 s .c om
    }
    if (op.hasNestedPlans()) {
        for (ILogicalPlan p : ((AbstractOperatorWithNestedPlans) op).getNestedPlans()) {
            typePlan(p, context);
        }
    }
    context.computeAndSetTypeEnvironmentForOperator(op);
}

From source file:edu.uci.ics.hyracks.algebricks.rewriter.rules.PushProjectDownRule.java

private static boolean pushNeededProjections(HashSet<LogicalVariable> toPush, Mutable<ILogicalOperator> opRef,
        IOptimizationContext context, ILogicalOperator initialOp) throws AlgebricksException {
    HashSet<LogicalVariable> allP = new HashSet<LogicalVariable>();
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    VariableUtilities.getLiveVariables(op, allP);

    HashSet<LogicalVariable> toProject = new HashSet<LogicalVariable>();
    for (LogicalVariable v : toPush) {
        if (allP.contains(v)) {
            toProject.add(v);/*from w  w  w .  ja  v  a  2s.c om*/
        }
    }
    if (toProject.equals(allP)) {
        // projection would be redundant, since we would project everything
        // but we can try with the children
        boolean push = false;
        if (pushThroughOp(toProject, opRef, initialOp, context).first) {
            push = true;
        }
        return push;
    } else {
        return pushAllProjectionsOnTopOf(toProject, opRef, context, initialOp);
    }
}

From source file:edu.uci.ics.hyracks.algebricks.rewriter.rules.PushProjectDownRule.java

private static boolean pushAllProjectionsOnTopOf(Collection<LogicalVariable> toPush,
        Mutable<ILogicalOperator> opRef, IOptimizationContext context, ILogicalOperator initialOp)
        throws AlgebricksException {
    if (toPush.isEmpty()) {
        return false;
    }//from  w w w.ja va2 s .co m
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();

    if (context.checkAndAddToAlreadyCompared(initialOp, op)) {
        return false;
    }

    switch (op.getOperatorTag()) {
    case EXCHANGE: {
        opRef = opRef.getValue().getInputs().get(0);
        op = (AbstractLogicalOperator) opRef.getValue();
        break;
    }
    case PROJECT: {
        return false;
    }
    }

    ProjectOperator pi2 = new ProjectOperator(new ArrayList<LogicalVariable>(toPush));
    pi2.getInputs().add(new MutableObject<ILogicalOperator>(op));
    opRef.setValue(pi2);
    pi2.setExecutionMode(op.getExecutionMode());
    context.computeAndSetTypeEnvironmentForOperator(pi2);
    return true;
}

From source file:edu.uci.ics.hyracks.algebricks.rewriter.rules.SetAlgebricksPhysicalOperatorsRule.java

private static void getKeys(List<Mutable<ILogicalExpression>> keyExpressions, List<LogicalVariable> keys) {
    for (Mutable<ILogicalExpression> kExpr : keyExpressions) {
        ILogicalExpression e = kExpr.getValue();
        if (e.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
            throw new NotImplementedException();
        }/*from www  .  j av  a 2s.  c  om*/
        keys.add(((VariableReferenceExpression) e).getVariableReference());
    }
}

From source file:edu.uci.ics.asterix.optimizer.rules.LoadRecordFieldsRule.java

private static ILogicalExpression findFieldExpression(AbstractLogicalOperator op, LogicalVariable recordVar,
        String fldName) {// w w w .  j av  a  2s.co m
    for (Mutable<ILogicalOperator> child : op.getInputs()) {
        AbstractLogicalOperator opChild = (AbstractLogicalOperator) child.getValue();
        if (opChild.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
            AssignOperator op2 = (AssignOperator) opChild;
            int i = 0;
            for (LogicalVariable var : op2.getVariables()) {
                if (var == recordVar) {
                    AbstractLogicalExpression constr = (AbstractLogicalExpression) op2.getExpressions().get(i)
                            .getValue();
                    if (constr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
                        return null;
                    }
                    AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) constr;
                    if (!fce.getFunctionIdentifier().equals(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR)
                            && !fce.getFunctionIdentifier()
                                    .equals(AsterixBuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR)) {
                        return null;
                    }
                    Iterator<Mutable<ILogicalExpression>> fldIter = fce.getArguments().iterator();
                    while (fldIter.hasNext()) {
                        ILogicalExpression fldExpr = fldIter.next().getValue();
                        if (fldExpr.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
                            ConstantExpression ce = (ConstantExpression) fldExpr;
                            String f2 = ((AString) ((AsterixConstantValue) ce.getValue()).getObject())
                                    .getStringValue();
                            if (fldName.equals(f2)) {
                                return fldIter.next().getValue();
                            }
                        }
                        fldIter.next();
                    }
                    return null;
                }
                i++;
            }
        } else if (opChild.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
            NestedTupleSourceOperator nts = (NestedTupleSourceOperator) opChild;
            AbstractLogicalOperator opBelowNestedPlan = (AbstractLogicalOperator) nts.getDataSourceReference()
                    .getValue().getInputs().get(0).getValue();
            ILogicalExpression expr1 = findFieldExpression(opBelowNestedPlan, recordVar, fldName);
            if (expr1 != null) {
                return expr1;
            }
        }
        ILogicalExpression expr2 = findFieldExpression(opChild, recordVar, fldName);
        if (expr2 != null) {
            return expr2;
        }
    }
    return null;
}

From source file:edu.uci.ics.hyracks.algebricks.rewriter.rules.SetAlgebricksPhysicalOperatorsRule.java

private static void setPhysicalOperators(ILogicalPlan plan, boolean topLevelOp, IOptimizationContext context)
        throws AlgebricksException {
    for (Mutable<ILogicalOperator> root : plan.getRoots()) {
        computeDefaultPhysicalOp((AbstractLogicalOperator) root.getValue(), topLevelOp, context);
    }/*  w  ww .j ava2  s  . c  o m*/
}

From source file:edu.uci.ics.asterix.optimizer.rules.SetAsterixPhysicalOperatorsRule.java

private static void computeDefaultPhysicalOp(AbstractLogicalOperator op, IOptimizationContext context)
        throws AlgebricksException {
    PhysicalOptimizationConfig physicalOptimizationConfig = context.getPhysicalOptimizationConfig();
    if (op.getOperatorTag().equals(LogicalOperatorTag.GROUP)) {
        GroupByOperator gby = (GroupByOperator) op;
        if (gby.getNestedPlans().size() == 1) {
            ILogicalPlan p0 = gby.getNestedPlans().get(0);
            if (p0.getRoots().size() == 1) {
                Mutable<ILogicalOperator> r0 = p0.getRoots().get(0);
                if (((AbstractLogicalOperator) (r0.getValue())).getOperatorTag()
                        .equals(LogicalOperatorTag.AGGREGATE)) {
                    AggregateOperator aggOp = (AggregateOperator) r0.getValue();
                    boolean serializable = true;
                    for (Mutable<ILogicalExpression> exprRef : aggOp.getExpressions()) {
                        AbstractFunctionCallExpression expr = (AbstractFunctionCallExpression) exprRef
                                .getValue();
                        if (!AsterixBuiltinFunctions
                                .isAggregateFunctionSerializable(expr.getFunctionIdentifier())) {
                            serializable = false;
                            break;
                        }//  w w  w .j a  v a2 s. c  o m
                    }

                    if ((gby.getAnnotations().get(OperatorAnnotations.USE_HASH_GROUP_BY) == Boolean.TRUE || gby
                            .getAnnotations().get(OperatorAnnotations.USE_EXTERNAL_GROUP_BY) == Boolean.TRUE)) {
                        boolean setToExternalGby = false;
                        if (serializable) {
                            // if serializable, use external group-by
                            // now check whether the serialized version aggregation function has corresponding intermediate agg
                            boolean hasIntermediateAgg = true;
                            IMergeAggregationExpressionFactory mergeAggregationExpressionFactory = context
                                    .getMergeAggregationExpressionFactory();
                            List<LogicalVariable> originalVariables = aggOp.getVariables();
                            List<Mutable<ILogicalExpression>> aggExprs = aggOp.getExpressions();
                            int aggNum = aggExprs.size();
                            for (int i = 0; i < aggNum; i++) {
                                AbstractFunctionCallExpression expr = (AbstractFunctionCallExpression) aggExprs
                                        .get(i).getValue();
                                AggregateFunctionCallExpression serialAggExpr = AsterixBuiltinFunctions
                                        .makeSerializableAggregateFunctionExpression(
                                                expr.getFunctionIdentifier(), expr.getArguments());
                                if (mergeAggregationExpressionFactory.createMergeAggregation(
                                        originalVariables.get(i), serialAggExpr, context) == null) {
                                    hasIntermediateAgg = false;
                                    break;
                                }
                            }

                            if (hasIntermediateAgg) {
                                for (int i = 0; i < aggNum; i++) {
                                    AbstractFunctionCallExpression expr = (AbstractFunctionCallExpression) aggExprs
                                            .get(i).getValue();
                                    AggregateFunctionCallExpression serialAggExpr = AsterixBuiltinFunctions
                                            .makeSerializableAggregateFunctionExpression(
                                                    expr.getFunctionIdentifier(), expr.getArguments());
                                    aggOp.getExpressions().get(i).setValue(serialAggExpr);
                                }
                                ExternalGroupByPOperator externalGby = new ExternalGroupByPOperator(
                                        gby.getGroupByList(),
                                        physicalOptimizationConfig.getMaxFramesExternalGroupBy(),
                                        physicalOptimizationConfig.getExternalGroupByTableSize());
                                generateMergeAggregationExpressions(gby, context);
                                op.setPhysicalOperator(externalGby);
                                setToExternalGby = true;
                            }
                        }

                        if (!setToExternalGby) {
                            // if not serializable or no intermediate agg, use pre-clustered group-by
                            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> gbyList = gby
                                    .getGroupByList();
                            List<LogicalVariable> columnList = new ArrayList<LogicalVariable>(gbyList.size());
                            for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gbyList) {
                                ILogicalExpression expr = p.second.getValue();
                                if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                                    VariableReferenceExpression varRef = (VariableReferenceExpression) expr;
                                    columnList.add(varRef.getVariableReference());
                                }
                            }
                            op.setPhysicalOperator(new PreclusteredGroupByPOperator(columnList));
                        }
                    }
                } else if (((AbstractLogicalOperator) (r0.getValue())).getOperatorTag()
                        .equals(LogicalOperatorTag.RUNNINGAGGREGATE)) {
                    List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> gbyList = gby.getGroupByList();
                    List<LogicalVariable> columnList = new ArrayList<LogicalVariable>(gbyList.size());
                    for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gbyList) {
                        ILogicalExpression expr = p.second.getValue();
                        if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                            VariableReferenceExpression varRef = (VariableReferenceExpression) expr;
                            columnList.add(varRef.getVariableReference());
                        }
                    }
                    op.setPhysicalOperator(new PreclusteredGroupByPOperator(columnList));
                } else {
                    throw new AlgebricksException("Unsupported nested operator within a group-by: "
                            + ((AbstractLogicalOperator) (r0.getValue())).getOperatorTag().name());
                }
            }
        }
    }
    if (op.getPhysicalOperator() == null) {
        switch (op.getOperatorTag()) {
        case INNERJOIN: {
            JoinUtils.setJoinAlgorithmAndExchangeAlgo((InnerJoinOperator) op, context);
            break;
        }
        case LEFTOUTERJOIN: {
            JoinUtils.setJoinAlgorithmAndExchangeAlgo((LeftOuterJoinOperator) op, context);
            break;
        }
        case UNNEST_MAP: {
            UnnestMapOperator unnestMap = (UnnestMapOperator) op;
            ILogicalExpression unnestExpr = unnestMap.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());
                AqlMetadataProvider mp = (AqlMetadataProvider) context.getMetadataProvider();
                AqlSourceId dataSourceId = new AqlSourceId(jobGenParams.getDataverseName(),
                        jobGenParams.getDatasetName());
                IDataSourceIndex<String, AqlSourceId> dsi = mp.findDataSourceIndex(jobGenParams.getIndexName(),
                        dataSourceId);
                if (dsi == null) {
                    throw new AlgebricksException("Could not find index " + jobGenParams.getIndexName()
                            + " for dataset " + dataSourceId);
                }
                IndexType indexType = jobGenParams.getIndexType();
                boolean requiresBroadcast = jobGenParams.getRequiresBroadcast();
                switch (indexType) {
                case BTREE: {
                    BTreeJobGenParams btreeJobGenParams = new BTreeJobGenParams();
                    btreeJobGenParams.readFromFuncArgs(f.getArguments());
                    op.setPhysicalOperator(new BTreeSearchPOperator(dsi, requiresBroadcast,
                            btreeJobGenParams.isPrimaryIndex(), btreeJobGenParams.isEqCondition(),
                            btreeJobGenParams.getLowKeyVarList(), btreeJobGenParams.getHighKeyVarList()));
                    break;
                }
                case RTREE: {
                    op.setPhysicalOperator(new RTreeSearchPOperator(dsi, requiresBroadcast));
                    break;
                }
                case SINGLE_PARTITION_WORD_INVIX:
                case SINGLE_PARTITION_NGRAM_INVIX: {
                    op.setPhysicalOperator(new InvertedIndexPOperator(dsi, requiresBroadcast, false));
                    break;
                }
                case LENGTH_PARTITIONED_WORD_INVIX:
                case LENGTH_PARTITIONED_NGRAM_INVIX: {
                    op.setPhysicalOperator(new InvertedIndexPOperator(dsi, requiresBroadcast, true));
                    break;
                }
                default: {
                    throw new NotImplementedException(indexType + " indexes are not implemented.");
                }
                }
            }
            break;
        }
        }
    }
    if (op.hasNestedPlans()) {
        AbstractOperatorWithNestedPlans nested = (AbstractOperatorWithNestedPlans) op;
        for (ILogicalPlan p : nested.getNestedPlans()) {
            setPhysicalOperators(p, context);
        }
    }
    for (Mutable<ILogicalOperator> opRef : op.getInputs()) {
        computeDefaultPhysicalOp((AbstractLogicalOperator) opRef.getValue(), context);
    }
}

From source file:edu.uci.ics.hyracks.algebricks.rewriter.rules.PushProjectDownRule.java

private static Pair<Boolean, Boolean> pushThroughOp(HashSet<LogicalVariable> toPush,
        Mutable<ILogicalOperator> opRef2, ILogicalOperator initialOp, IOptimizationContext context)
        throws AlgebricksException {
    List<LogicalVariable> initProjectList = new ArrayList<LogicalVariable>(toPush);
    AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
    do {//  w w  w.  j  a  va 2  s . c  o m
        if (op2.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE
                || op2.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE
                || op2.getOperatorTag() == LogicalOperatorTag.PROJECT
                || op2.getOperatorTag() == LogicalOperatorTag.REPLICATE
                || op2.getOperatorTag() == LogicalOperatorTag.UNIONALL) {
            return new Pair<Boolean, Boolean>(false, false);
        }
        if (!op2.isMap()) {
            break;
        }
        LinkedList<LogicalVariable> usedVars = new LinkedList<LogicalVariable>();
        VariableUtilities.getUsedVariables(op2, usedVars);
        toPush.addAll(usedVars);
        LinkedList<LogicalVariable> producedVars = new LinkedList<LogicalVariable>();
        VariableUtilities.getProducedVariables(op2, producedVars);
        toPush.removeAll(producedVars);
        // we assume pipelineable ops. have only one input
        opRef2 = op2.getInputs().get(0);
        op2 = (AbstractLogicalOperator) opRef2.getValue();
    } while (true);

    LinkedList<LogicalVariable> produced2 = new LinkedList<LogicalVariable>();
    VariableUtilities.getProducedVariables(op2, produced2);
    LinkedList<LogicalVariable> used2 = new LinkedList<LogicalVariable>();
    VariableUtilities.getUsedVariables(op2, used2);

    boolean canCommuteProjection = initProjectList.containsAll(toPush) && initProjectList.containsAll(produced2)
            && initProjectList.containsAll(used2);
    // if true, we can get rid of the initial projection

    // get rid of useless decor vars.
    if (!canCommuteProjection && op2.getOperatorTag() == LogicalOperatorTag.GROUP) {
        boolean gbyChanged = false;
        GroupByOperator gby = (GroupByOperator) op2;
        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> newDecorList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getDecorList()) {
            LogicalVariable decorVar = GroupByOperator.getDecorVariable(p);
            if (!toPush.contains(decorVar)) {
                used2.remove(decorVar);
                gbyChanged = true;
            } else {
                newDecorList.add(p);
            }
        }
        gby.getDecorList().clear();
        gby.getDecorList().addAll(newDecorList);
        if (gbyChanged) {
            context.computeAndSetTypeEnvironmentForOperator(gby);
        }
    }
    used2.clear();
    VariableUtilities.getUsedVariables(op2, used2);

    toPush.addAll(used2); // remember that toPush is a Set
    toPush.removeAll(produced2);

    if (toPush.isEmpty()) {
        return new Pair<Boolean, Boolean>(false, false);
    }

    boolean smthWasPushed = false;
    for (Mutable<ILogicalOperator> c : op2.getInputs()) {
        if (pushNeededProjections(toPush, c, context, initialOp)) {
            smthWasPushed = true;
        }
    }
    if (op2.hasNestedPlans()) {
        AbstractOperatorWithNestedPlans n = (AbstractOperatorWithNestedPlans) op2;
        for (ILogicalPlan p : n.getNestedPlans()) {
            for (Mutable<ILogicalOperator> r : p.getRoots()) {
                if (pushNeededProjections(toPush, r, context, initialOp)) {
                    smthWasPushed = true;
                }
            }
        }
    }
    return new Pair<Boolean, Boolean>(smthWasPushed, canCommuteProjection);
}

From source file:edu.uci.ics.hyracks.algebricks.rewriter.rules.SetAlgebricksPhysicalOperatorsRule.java

private static boolean generateMergeAggregationExpressions(GroupByOperator gby, IOptimizationContext context)
        throws AlgebricksException {
    if (gby.getNestedPlans().size() != 1) {
        //External/Sort group-by currently works only for one nested plan with one root containing
        //an aggregate and a nested-tuple-source.
        throw new AlgebricksException(
                "External group-by currently works only for one nested plan with one root containing"
                        + "an aggregate and a nested-tuple-source.");
    }//w  w  w  .j ava2 s . com
    ILogicalPlan p0 = gby.getNestedPlans().get(0);
    if (p0.getRoots().size() != 1) {
        //External/Sort group-by currently works only for one nested plan with one root containing
        //an aggregate and a nested-tuple-source.
        throw new AlgebricksException(
                "External group-by currently works only for one nested plan with one root containing"
                        + "an aggregate and a nested-tuple-source.");
    }
    IMergeAggregationExpressionFactory mergeAggregationExpressionFactory = context
            .getMergeAggregationExpressionFactory();
    Mutable<ILogicalOperator> r0 = p0.getRoots().get(0);
    AbstractLogicalOperator r0Logical = (AbstractLogicalOperator) r0.getValue();
    if (r0Logical.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
        return false;
    }
    AggregateOperator aggOp = (AggregateOperator) r0.getValue();
    List<Mutable<ILogicalExpression>> aggFuncRefs = aggOp.getExpressions();
    List<LogicalVariable> originalAggVars = aggOp.getVariables();
    int n = aggOp.getExpressions().size();
    List<Mutable<ILogicalExpression>> mergeExpressionRefs = new ArrayList<Mutable<ILogicalExpression>>();
    for (int i = 0; i < n; i++) {
        ILogicalExpression mergeExpr = mergeAggregationExpressionFactory
                .createMergeAggregation(originalAggVars.get(i), aggFuncRefs.get(i).getValue(), context);
        if (mergeExpr == null) {
            return false;
        }
        mergeExpressionRefs.add(new MutableObject<ILogicalExpression>(mergeExpr));
    }
    aggOp.setMergeExpressions(mergeExpressionRefs);
    return true;
}

From source file:edu.uci.ics.asterix.optimizer.rules.LoadRecordFieldsRule.java

private static boolean pushFieldLoads(Mutable<ILogicalExpression> exprRef, AbstractLogicalOperator topOp,
        IOptimizationContext context) throws AlgebricksException {
    ILogicalExpression expr = exprRef.getValue();
    if (expr == null) {
        return false;
    }/*from   w w  w  . jav a  2 s .  c  o m*/
    switch (expr.getExpressionTag()) {
    case FUNCTION_CALL: {
        AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expr;
        FunctionIdentifier fi = f.getFunctionIdentifier();
        if (AlgebricksBuiltinFunctions.isComparisonFunction(fi)) {
            boolean b1 = pushFieldLoads(f.getArguments().get(0), topOp, context);
            boolean b2 = pushFieldLoads(f.getArguments().get(1), topOp, context);
            return b1 || b2;
        }
        if (fi.equals(AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME)) {
            if (AnalysisUtil.numberOfVarsInExpr(f) == 0) {
                return false;
            }
            // create an assign
            LogicalVariable v = context.newVar();
            AssignOperator a2 = new AssignOperator(v, new MutableObject<ILogicalExpression>(f));
            pushFieldAssign(a2, topOp, context);
            context.computeAndSetTypeEnvironmentForOperator(a2);
            ILogicalExpression arg = f.getArguments().get(0).getValue();
            if (arg.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                VariableReferenceExpression ref = (VariableReferenceExpression) arg;
                LogicalVariable var = ref.getVariableReference();
                List<LogicalVariable> keys = context.findPrimaryKey(var);
                if (keys != null) {
                    List<LogicalVariable> tail = new ArrayList<LogicalVariable>();
                    tail.add(v);
                    FunctionalDependency pk = new FunctionalDependency(keys, tail);
                    context.addPrimaryKey(pk);
                }
            }
            exprRef.setValue(new VariableReferenceExpression(v));
            return true;
        } else {
            boolean pushed = false;
            for (Mutable<ILogicalExpression> argRef : f.getArguments()) {
                if (pushFieldLoads(argRef, topOp, context)) {
                    pushed = true;
                }
            }
            return pushed;
        }
    }
    case CONSTANT:
    case VARIABLE: {
        return false;
    }
    default: {
        assert false;
        throw new IllegalArgumentException();
    }
    }
}