| /* |
| * 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.vxquery.compiler.rewriter.rules.util; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.commons.lang3.mutable.Mutable; |
| import org.apache.commons.lang3.mutable.MutableObject; |
| 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.LogicalOperatorTag; |
| import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable; |
| import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractAssignOperator; |
| import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator; |
| import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator; |
| import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractScanOperator; |
| import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestOperator; |
| import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator; |
| import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator; |
| |
| public class OperatorToolbox { |
| |
| public static Mutable<ILogicalOperator> findLastSubplanOperator(Mutable<ILogicalOperator> opRef) { |
| AbstractLogicalOperator op = (AbstractLogicalOperator) opRef; |
| AbstractLogicalOperator next; |
| while (op.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) { |
| opRef = op.getInputs().get(0); |
| op = (AbstractLogicalOperator) opRef; |
| next = (AbstractLogicalOperator) op.getInputs().get(0).getValue(); |
| if (next.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) { |
| break; |
| } |
| } |
| return opRef; |
| } |
| |
| public static AbstractLogicalOperator findLastSubplanOperator(AbstractLogicalOperator op) { |
| AbstractLogicalOperator next; |
| while (op.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) { |
| op = (AbstractLogicalOperator) op.getInputs().get(0).getValue(); |
| next = (AbstractLogicalOperator) op.getInputs().get(0).getValue(); |
| if (next.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) { |
| break; |
| } |
| } |
| return op; |
| } |
| |
| public static List<Mutable<ILogicalExpression>> getExpressions(Mutable<ILogicalOperator> opRef) { |
| AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue(); |
| List<Mutable<ILogicalExpression>> result = new ArrayList<Mutable<ILogicalExpression>>(); |
| switch (op.getOperatorTag()) { |
| case AGGREGATE: |
| case ASSIGN: |
| case RUNNINGAGGREGATE: |
| AbstractAssignOperator aao = (AbstractAssignOperator) op; |
| result.addAll(aao.getExpressions()); |
| break; |
| case INNERJOIN: |
| case LEFTOUTERJOIN: |
| AbstractBinaryJoinOperator abjo = (AbstractBinaryJoinOperator) op; |
| result.add(abjo.getCondition()); |
| break; |
| case SELECT: |
| SelectOperator so = (SelectOperator) op; |
| result.add(so.getCondition()); |
| break; |
| case UNNEST: |
| case UNNEST_MAP: |
| AbstractUnnestOperator auo = (AbstractUnnestOperator) op; |
| result.add(auo.getExpressionRef()); |
| break; |
| default: |
| // TODO Not yet implemented. |
| break; |
| } |
| return result; |
| } |
| |
| public static Mutable<ILogicalExpression> getExpressionOf(Mutable<ILogicalOperator> opRef, LogicalVariable lv) { |
| AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue(); |
| switch (op.getOperatorTag()) { |
| case AGGREGATE: |
| case ASSIGN: |
| case RUNNINGAGGREGATE: |
| AbstractAssignOperator aao = (AbstractAssignOperator) op; |
| if (!aao.getVariables().contains(lv)) { |
| return null; |
| } |
| return aao.getExpressions().get(aao.getVariables().indexOf(lv)); |
| case UNNEST: |
| case UNNEST_MAP: |
| AbstractUnnestOperator ano = (AbstractUnnestOperator) op; |
| return ano.getExpressionRef(); |
| default: |
| // TODO Not yet implemented. |
| break; |
| } |
| return null; |
| } |
| |
| public static Mutable<ILogicalOperator> findProducerOf(Mutable<ILogicalOperator> opRef, LogicalVariable lv) { |
| AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue(); |
| switch (op.getOperatorTag()) { |
| case AGGREGATE: |
| case ASSIGN: |
| case RUNNINGAGGREGATE: |
| AbstractAssignOperator aao = (AbstractAssignOperator) op; |
| if (aao.getVariables().contains(lv)) { |
| return opRef; |
| } |
| for (Mutable<ILogicalOperator> input : op.getInputs()) { |
| Mutable<ILogicalOperator> opInput = findProducerOf(input, lv); |
| if (opInput != null) { |
| return opInput; |
| } |
| } |
| break; |
| case DATASOURCESCAN: |
| case UNNEST: |
| case UNNEST_MAP: |
| AbstractScanOperator aso = (AbstractScanOperator) op; |
| if (aso.getVariables().contains(lv)) { |
| return opRef; |
| } |
| for (Mutable<ILogicalOperator> input : op.getInputs()) { |
| Mutable<ILogicalOperator> opInput = findProducerOf(input, lv); |
| if (opInput != null) { |
| return opInput; |
| } |
| } |
| break; |
| case NESTEDTUPLESOURCE: |
| NestedTupleSourceOperator nts = (NestedTupleSourceOperator) op; |
| return findProducerOf(nts.getDataSourceReference(), lv); |
| case EMPTYTUPLESOURCE: |
| return null; |
| default: |
| // Skip operators and go look at input. |
| for (Mutable<ILogicalOperator> input : op.getInputs()) { |
| Mutable<ILogicalOperator> opInput = findProducerOf(input, lv); |
| if (opInput != null) { |
| return opInput; |
| } |
| } |
| break; |
| } |
| return null; |
| } |
| } |