| package edu.uci.ics.asterix.optimizer.rules; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.commons.lang3.mutable.Mutable; |
| import org.apache.commons.lang3.mutable.MutableObject; |
| |
| import edu.uci.ics.asterix.algebra.base.AsterixOperatorAnnotations; |
| import edu.uci.ics.asterix.aql.util.FunctionUtils; |
| import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions; |
| import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression; |
| import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator; |
| import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext; |
| import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag; |
| import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag; |
| import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable; |
| import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression; |
| import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression; |
| import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression; |
| import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator; |
| import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator; |
| import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule; |
| |
| public class ByNameToByHandleFieldAccessRule implements IAlgebraicRewriteRule { |
| |
| @Override |
| public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) { |
| return false; |
| } |
| |
| @Override |
| public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) { |
| AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue(); |
| if (op.getOperatorTag() != LogicalOperatorTag.ASSIGN) { |
| return false; |
| } |
| AssignOperator assign = (AssignOperator) op; |
| if (assign.getAnnotations().get(AsterixOperatorAnnotations.PUSHED_FIELD_ACCESS) == null) { |
| return false; |
| } |
| byNameToByHandle(assign, context); |
| return true; |
| } |
| |
| private static void byNameToByHandle(AssignOperator fieldAccessOp, IOptimizationContext context) { |
| Mutable<ILogicalOperator> opUnder = fieldAccessOp.getInputs().get(0); |
| AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) fieldAccessOp.getExpressions().get(0) |
| .getValue(); |
| ILogicalExpression a1 = fce.getArguments().get(0).getValue(); |
| |
| VariableReferenceExpression x; |
| if (a1.getExpressionTag() == LogicalExpressionTag.VARIABLE) { |
| x = (VariableReferenceExpression) a1; |
| } else { |
| LogicalVariable var1 = context.newVar(); |
| ArrayList<LogicalVariable> varArray = new ArrayList<LogicalVariable>(1); |
| varArray.add(var1); |
| ArrayList<Mutable<ILogicalExpression>> exprArray = new ArrayList<Mutable<ILogicalExpression>>(1); |
| exprArray.add(new MutableObject<ILogicalExpression>(a1)); |
| AssignOperator assignVar = new AssignOperator(varArray, exprArray); |
| x = new VariableReferenceExpression(var1); |
| assignVar.getInputs().add(opUnder); |
| opUnder = new MutableObject<ILogicalOperator>(assignVar); |
| } |
| |
| // let $t := type-of(x) |
| LogicalVariable t = context.newVar(); |
| |
| AbstractFunctionCallExpression typeOf = new ScalarFunctionCallExpression( |
| FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.TYPE_OF)); |
| typeOf.getArguments().add(new MutableObject<ILogicalExpression>(x)); |
| AssignOperator typAssign = new AssignOperator(t, new MutableObject<ILogicalExpression>(typeOf)); |
| typAssign.getInputs().add(opUnder); |
| |
| // let $w := get-handle($t, path-expression) |
| LogicalVariable w = context.newVar(); |
| AbstractFunctionCallExpression getHandle = new ScalarFunctionCallExpression( |
| FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.GET_HANDLE)); |
| getHandle.getArguments().add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(t))); |
| // the accessed field |
| getHandle.getArguments().add(new MutableObject<ILogicalExpression>(fce.getArguments().get(1).getValue())); |
| AssignOperator handleAssign = new AssignOperator(w, new MutableObject<ILogicalExpression>(getHandle)); |
| handleAssign.getInputs().add(new MutableObject<ILogicalOperator>(typAssign)); |
| |
| // let $y := get-data(x, $w) |
| AbstractFunctionCallExpression getData = new ScalarFunctionCallExpression( |
| FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.GET_DATA)); |
| VariableReferenceExpression ref2 = new VariableReferenceExpression(x.getVariableReference()); |
| getData.getArguments().add(new MutableObject<ILogicalExpression>(ref2)); |
| getData.getArguments().add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(w))); |
| fieldAccessOp.getExpressions().get(0).setValue(getData); |
| List<Mutable<ILogicalOperator>> faInputs = fieldAccessOp.getInputs(); |
| faInputs.clear(); |
| faInputs.add(new MutableObject<ILogicalOperator>(handleAssign)); |
| |
| // fieldAccess.setAnnotation(OperatorAnnotation.FIELD_ACCESS, |
| // fce.getArguments().get(0)); |
| fieldAccessOp.removeAnnotation(AsterixOperatorAnnotations.PUSHED_FIELD_ACCESS); |
| } |
| |
| } |