blob: a2107e50965adb54b9fdb33621ceafd8d015b97e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.mutable.Mutable;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.common.utils.Pair;
import org.apache.hyracks.algebricks.common.utils.Triple;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestMapOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestNonMapOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.DelegateOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.DistinctOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.DistributeResultOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.ExchangeOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.ForwardOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.IndexInsertDeleteUpsertOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.InsertDeleteUpsertOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.IntersectOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.MaterializeOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.RunningAggregateOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.ScriptOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SinkOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SplitOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.TokenizeOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.WindowOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.WriteOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.WriteResultOperator;
import org.apache.hyracks.algebricks.core.algebra.properties.LocalOrderProperty;
import org.apache.hyracks.algebricks.core.algebra.properties.OrderColumn;
import org.apache.hyracks.algebricks.core.algebra.typing.ITypingContext;
import org.apache.hyracks.algebricks.core.algebra.visitors.ILogicalOperatorVisitor;
public class SubstituteVariableVisitor
implements ILogicalOperatorVisitor<Void, Pair<LogicalVariable, LogicalVariable>> {
private final ITypingContext ctx;
//TODO(dmitry):unused -> remove
private final boolean goThroughNts;
public SubstituteVariableVisitor(boolean goThroughNts, ITypingContext ctx) {
this.goThroughNts = goThroughNts;
this.ctx = ctx;
}
@Override
public Void visitAggregateOperator(AggregateOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound =
substAssignVariables(op.getVariables(), op.getExpressions(), pair.first, pair.second);
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
}
return null;
}
@Override
public Void visitAssignOperator(AssignOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound =
substAssignVariables(op.getVariables(), op.getExpressions(), pair.first, pair.second);
if (producedVarFound) {
// Substitute variables stored in ordering property
if (op.getExplicitOrderingProperty() != null) {
List<OrderColumn> orderColumns = op.getExplicitOrderingProperty().getOrderColumns();
List<OrderColumn> newOrderColumns = new ArrayList<>(orderColumns.size());
for (OrderColumn oc : orderColumns) {
LogicalVariable columnVar = oc.getColumn();
LogicalVariable newColumnVar = columnVar.equals(pair.first) ? pair.second : columnVar;
newOrderColumns.add(new OrderColumn(newColumnVar, oc.getOrder()));
}
op.setExplicitOrderingProperty(new LocalOrderProperty(newOrderColumns));
}
substProducedVarInTypeEnvironment(op, pair);
}
return null;
}
@Override
public Void visitDataScanOperator(DataSourceScanOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound = substProducedVariables(op.getVariables(), pair.first, pair.second);
if (!producedVarFound) {
if (op.isProjectPushed()) {
producedVarFound = substProducedVariables(op.getProjectVariables(), pair.first, pair.second);
}
}
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
} else {
substUsedVariablesInExpr(op.getSelectCondition(), pair.first, pair.second);
substUsedVariablesInExpr(op.getAdditionalFilteringExpressions(), pair.first, pair.second);
substUsedVariables(op.getMinFilterVars(), pair.first, pair.second);
substUsedVariables(op.getMaxFilterVars(), pair.first, pair.second);
}
return null;
}
@Override
public Void visitDistinctOperator(DistinctOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substUsedVariablesInExpr(op.getExpressions(), pair.first, pair.second);
return null;
}
@Override
public Void visitEmptyTupleSourceOperator(EmptyTupleSourceOperator op,
Pair<LogicalVariable, LogicalVariable> pair) {
// does not produce/use any variables
return null;
}
@Override
public Void visitExchangeOperator(ExchangeOperator op, Pair<LogicalVariable, LogicalVariable> pair) {
// does not produce/use any variables
return null;
}
@Override
public Void visitGroupByOperator(GroupByOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound = substGbyVariables(op.getGroupByList(), pair.first, pair.second);
if (!producedVarFound) {
producedVarFound = substGbyVariables(op.getDecorList(), pair.first, pair.second);
}
if (!producedVarFound) {
substInNestedPlans(op, pair.first, pair.second);
}
// GROUP BY operator may add its used variables
// to its own output type environment as produced variables
// therefore we need perform variable substitution in its own type environment
// TODO (dmitry): this needs to be revisited
substProducedVarInTypeEnvironment(op, pair);
return null;
}
@Override
public Void visitInnerJoinOperator(InnerJoinOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substUsedVariablesInExpr(op.getCondition(), pair.first, pair.second);
return null;
}
@Override
public Void visitLeftOuterJoinOperator(LeftOuterJoinOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substUsedVariablesInExpr(op.getCondition(), pair.first, pair.second);
// LEFT OUTER JOIN operator adds its right branch variables
// to its own output type environment as 'correlatedMissableVariables'
// therefore we need perform variable substitution in its own type environment
substProducedVarInTypeEnvironment(op, pair);
return null;
}
@Override
public Void visitLimitOperator(LimitOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substUsedVariablesInExpr(op.getMaxObjects(), pair.first, pair.second);
substUsedVariablesInExpr(op.getOffset(), pair.first, pair.second);
return null;
}
@Override
public Void visitNestedTupleSourceOperator(NestedTupleSourceOperator op,
Pair<LogicalVariable, LogicalVariable> pair) throws AlgebricksException {
// does not produce/use any variables
return null;
}
@Override
public Void visitOrderOperator(OrderOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
for (Pair<IOrder, Mutable<ILogicalExpression>> oe : op.getOrderExpressions()) {
substUsedVariablesInExpr(oe.second, pair.first, pair.second);
}
return null;
}
@Override
public Void visitProjectOperator(ProjectOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substUsedVariables(op.getVariables(), pair.first, pair.second);
return null;
}
@Override
public Void visitRunningAggregateOperator(RunningAggregateOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound =
substAssignVariables(op.getVariables(), op.getExpressions(), pair.first, pair.second);
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
}
return null;
}
@Override
public Void visitScriptOperator(ScriptOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound = substProducedVariables(op.getOutputVariables(), pair.first, pair.second);
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
} else {
substUsedVariables(op.getInputVariables(), pair.first, pair.second);
}
return null;
}
@Override
public Void visitSelectOperator(SelectOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substUsedVariablesInExpr(op.getCondition(), pair.first, pair.second);
// SELECT operator may add its used variable
// to its own output type environment as 'nonMissableVariable' (not(is-missing($used_var))
// therefore we need perform variable substitution in its own type environment
substProducedVarInTypeEnvironment(op, pair);
return null;
}
@Override
public Void visitSubplanOperator(SubplanOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substInNestedPlans(op, pair.first, pair.second);
// do not call substProducedVarInTypeEnvironment() because the variables are produced by nested plans
return null;
}
@Override
public Void visitUnionOperator(UnionAllOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound = substUnionAllVariables(op.getVariableMappings(), pair.first, pair.second);
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
}
return null;
}
@Override
public Void visitIntersectOperator(IntersectOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound = substProducedVariables(op.getOutputCompareVariables(), pair.first, pair.second);
if (!producedVarFound) {
if (op.hasExtraVariables()) {
producedVarFound = substProducedVariables(op.getOutputExtraVariables(), pair.first, pair.second);
}
}
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
} else {
for (int i = 0, n = op.getNumInput(); i < n; i++) {
substUsedVariables(op.getInputCompareVariables(i), pair.first, pair.second);
if (op.hasExtraVariables()) {
substUsedVariables(op.getInputExtraVariables(i), pair.first, pair.second);
}
}
}
return null;
}
@Override
public Void visitUnnestMapOperator(UnnestMapOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound = substituteVarsForAbstractUnnestMapOp(op, pair.first, pair.second);
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
} else {
substUsedVariablesInExpr(op.getSelectCondition(), pair.first, pair.second);
}
return null;
}
@Override
public Void visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator op,
Pair<LogicalVariable, LogicalVariable> pair) throws AlgebricksException {
boolean producedVarFound = substituteVarsForAbstractUnnestMapOp(op, pair.first, pair.second);
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
}
return null;
}
private boolean substituteVarsForAbstractUnnestMapOp(AbstractUnnestMapOperator op, LogicalVariable v1,
LogicalVariable v2) {
boolean producedVarFound = substProducedVariables(op.getVariables(), v1, v2);
if (!producedVarFound) {
substUsedVariablesInExpr(op.getExpressionRef(), v1, v2);
substUsedVariablesInExpr(op.getAdditionalFilteringExpressions(), v1, v2);
substUsedVariables(op.getMinFilterVars(), v1, v2);
substUsedVariables(op.getMaxFilterVars(), v1, v2);
}
return producedVarFound;
}
@Override
public Void visitUnnestOperator(UnnestOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound = substituteVarsForAbstractUnnestNonMapOp(op, pair.first, pair.second);
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
}
return null;
}
@Override
public Void visitLeftOuterUnnestOperator(LeftOuterUnnestOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound = substituteVarsForAbstractUnnestNonMapOp(op, pair.first, pair.second);
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
}
return null;
}
private boolean substituteVarsForAbstractUnnestNonMapOp(AbstractUnnestNonMapOperator op, LogicalVariable v1,
LogicalVariable v2) {
boolean producedVarFound = substProducedVariables(op.getVariables(), v1, v2);
if (!producedVarFound) {
if (op.hasPositionalVariable() && op.getPositionalVariable().equals(v1)) {
op.setPositionalVariable(v2);
producedVarFound = true;
}
}
if (!producedVarFound) {
substUsedVariablesInExpr(op.getExpressionRef(), v1, v2);
}
return producedVarFound;
}
@Override
public Void visitWriteOperator(WriteOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substUsedVariablesInExpr(op.getExpressions(), pair.first, pair.second);
return null;
}
@Override
public Void visitDistributeResultOperator(DistributeResultOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substUsedVariablesInExpr(op.getExpressions(), pair.first, pair.second);
return null;
}
@Override
public Void visitWriteResultOperator(WriteResultOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substUsedVariablesInExpr(op.getPayloadExpression(), pair.first, pair.second);
substUsedVariablesInExpr(op.getKeyExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getAdditionalFilteringExpressions(), pair.first, pair.second);
return null;
}
@Override
public Void visitReplicateOperator(ReplicateOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
// does not produce/use any variables
return null;
}
@Override
public Void visitSplitOperator(SplitOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substUsedVariablesInExpr(op.getBranchingExpression(), pair.first, pair.second);
return null;
}
@Override
public Void visitMaterializeOperator(MaterializeOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
// does not produce/use any variables
return null;
}
@Override
public Void visitInsertDeleteUpsertOperator(InsertDeleteUpsertOperator op,
Pair<LogicalVariable, LogicalVariable> pair) throws AlgebricksException {
boolean producedVarFound = false;
if (op.getOperation() == InsertDeleteUpsertOperator.Kind.UPSERT) {
if (op.getUpsertIndicatorVar() != null && op.getUpsertIndicatorVar().equals(pair.first)) {
op.setUpsertIndicatorVar(pair.second);
producedVarFound = true;
} else if (op.getBeforeOpRecordVar() != null && op.getBeforeOpRecordVar().equals(pair.first)) {
op.setPrevRecordVar(pair.second);
producedVarFound = true;
} else if (op.getBeforeOpFilterVar() != null && op.getBeforeOpFilterVar().equals(pair.first)) {
op.setPrevFilterVar(pair.second);
producedVarFound = true;
} else {
producedVarFound =
substProducedVariables(op.getBeforeOpAdditionalNonFilteringVars(), pair.first, pair.second);
}
}
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
} else {
substUsedVariablesInExpr(op.getPayloadExpression(), pair.first, pair.second);
substUsedVariablesInExpr(op.getPrimaryKeyExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getAdditionalFilteringExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getAdditionalNonFilteringExpressions(), pair.first, pair.second);
}
return null;
}
@Override
public Void visitIndexInsertDeleteUpsertOperator(IndexInsertDeleteUpsertOperator op,
Pair<LogicalVariable, LogicalVariable> pair) throws AlgebricksException {
substUsedVariablesInExpr(op.getPrimaryKeyExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getSecondaryKeyExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getFilterExpression(), pair.first, pair.second);
substUsedVariablesInExpr(op.getAdditionalFilteringExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getUpsertIndicatorExpr(), pair.first, pair.second);
substUsedVariablesInExpr(op.getPrevSecondaryKeyExprs(), pair.first, pair.second);
substUsedVariablesInExpr(op.getPrevAdditionalFilteringExpression(), pair.first, pair.second);
return null;
}
@Override
public Void visitTokenizeOperator(TokenizeOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound = substProducedVariables(op.getTokenizeVars(), pair.first, pair.second);
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
} else {
substUsedVariablesInExpr(op.getPrimaryKeyExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getSecondaryKeyExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getFilterExpression(), pair.first, pair.second);
substUsedVariablesInExpr(op.getAdditionalFilteringExpressions(), pair.first, pair.second);
}
return null;
}
@Override
public Void visitForwardOperator(ForwardOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
substUsedVariablesInExpr(op.getSideDataExpression(), pair.first, pair.second);
return null;
}
@Override
public Void visitSinkOperator(SinkOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
// does not produce/use any variables
return null;
}
@Override
public Void visitDelegateOperator(DelegateOperator op, Pair<LogicalVariable, LogicalVariable> arg)
throws AlgebricksException {
// does not produce/use any variables
return null;
}
@Override
public Void visitWindowOperator(WindowOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
boolean producedVarFound =
substAssignVariables(op.getVariables(), op.getExpressions(), pair.first, pair.second);
if (producedVarFound) {
substProducedVarInTypeEnvironment(op, pair);
} else {
substUsedVariablesInExpr(op.getPartitionExpressions(), pair.first, pair.second);
for (Pair<IOrder, Mutable<ILogicalExpression>> p : op.getOrderExpressions()) {
substUsedVariablesInExpr(p.second, pair.first, pair.second);
}
for (Pair<IOrder, Mutable<ILogicalExpression>> p : op.getFrameValueExpressions()) {
substUsedVariablesInExpr(p.second, pair.first, pair.second);
}
substUsedVariablesInExpr(op.getFrameStartExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getFrameStartValidationExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getFrameEndExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getFrameEndValidationExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getFrameExcludeExpressions(), pair.first, pair.second);
substUsedVariablesInExpr(op.getFrameExcludeUnaryExpression(), pair.first, pair.second);
substUsedVariablesInExpr(op.getFrameOffsetExpression(), pair.first, pair.second);
substInNestedPlans(op, pair.first, pair.second);
}
return null;
}
private void substUsedVariablesInExpr(Mutable<ILogicalExpression> exprRef, LogicalVariable v1, LogicalVariable v2) {
if (exprRef != null && exprRef.getValue() != null) {
exprRef.getValue().substituteVar(v1, v2);
}
}
private void substUsedVariablesInExpr(List<Mutable<ILogicalExpression>> expressions, LogicalVariable v1,
LogicalVariable v2) {
if (expressions != null) {
for (Mutable<ILogicalExpression> exprRef : expressions) {
substUsedVariablesInExpr(exprRef, v1, v2);
}
}
}
private void substUsedVariables(List<LogicalVariable> variables, LogicalVariable v1, LogicalVariable v2) {
if (variables != null) {
for (int i = 0, n = variables.size(); i < n; i++) {
if (variables.get(i).equals(v1)) {
variables.set(i, v2);
}
}
}
}
private boolean substProducedVariables(List<LogicalVariable> variables, LogicalVariable v1, LogicalVariable v2) {
if (variables != null) {
for (int i = 0, n = variables.size(); i < n; i++) {
if (variables.get(i).equals(v1)) {
variables.set(i, v2);
return true; // found produced var
}
}
}
return false;
}
private boolean substAssignVariables(List<LogicalVariable> variables, List<Mutable<ILogicalExpression>> expressions,
LogicalVariable v1, LogicalVariable v2) {
for (int i = 0, n = variables.size(); i < n; i++) {
if (variables.get(i).equals(v1)) {
variables.set(i, v2);
return true; // found produced var
} else {
expressions.get(i).getValue().substituteVar(v1, v2);
}
}
return false;
}
private boolean substGbyVariables(List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> gbyPairList,
LogicalVariable v1, LogicalVariable v2) {
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> ve : gbyPairList) {
if (ve.first != null && ve.first.equals(v1)) {
ve.first = v2;
return true; // found produced var
}
ve.second.getValue().substituteVar(v1, v2);
}
return false;
}
private boolean substUnionAllVariables(List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> varMap,
LogicalVariable v1, LogicalVariable v2) {
for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> t : varMap) {
if (t.first.equals(v1)) {
t.first = v2;
}
if (t.second.equals(v1)) {
t.second = v2;
}
if (t.third.equals(v1)) {
t.third = v2;
return true; // found produced var
}
}
return false;
}
private void substInNestedPlans(AbstractOperatorWithNestedPlans op, LogicalVariable v1, LogicalVariable v2)
throws AlgebricksException {
for (ILogicalPlan p : op.getNestedPlans()) {
for (Mutable<ILogicalOperator> r : p.getRoots()) {
VariableUtilities.substituteVariablesInDescendantsAndSelf(r.getValue(), v1, v2, ctx);
}
}
}
private void substProducedVarInTypeEnvironment(ILogicalOperator op, Pair<LogicalVariable, LogicalVariable> pair)
throws AlgebricksException {
if (ctx == null) {
return;
}
IVariableTypeEnvironment env = ctx.getOutputTypeEnvironment(op);
if (env != null) {
env.substituteProducedVariable(pair.first, pair.second);
}
}
}