Search in sources :

Example 1 with AbstractLogicalExpression

use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression in project asterixdb by apache.

the class RemoveRedundantListifyRule method applies.

private boolean applies(Mutable<ILogicalOperator> opRef, Set<LogicalVariable> varUsedAbove, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
    if (op1.getOperatorTag() != LogicalOperatorTag.UNNEST) {
        return false;
    }
    UnnestOperator unnest1 = (UnnestOperator) op1;
    ILogicalExpression expr = unnest1.getExpressionRef().getValue();
    if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return false;
    }
    if (((AbstractFunctionCallExpression) expr).getFunctionIdentifier() != BuiltinFunctions.SCAN_COLLECTION) {
        return false;
    }
    AbstractFunctionCallExpression functionCall = (AbstractFunctionCallExpression) expr;
    ILogicalExpression functionCallArgExpr = functionCall.getArguments().get(0).getValue();
    if (functionCallArgExpr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
        return false;
    }
    LogicalVariable unnestedVar = ((VariableReferenceExpression) functionCallArgExpr).getVariableReference();
    if (varUsedAbove.contains(unnestedVar)) {
        return false;
    }
    Mutable<ILogicalOperator> aggregateParentRef = opRef;
    AbstractLogicalOperator r = op1;
    boolean metAggregate = false;
    while (r.getInputs().size() == 1) {
        aggregateParentRef = r.getInputs().get(0);
        r = (AbstractLogicalOperator) aggregateParentRef.getValue();
        if (r.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
            AssignOperator assign = (AssignOperator) r;
            List<LogicalVariable> variables = assign.getVariables();
            // The assign operator doesn't produce any variable that is used by the unnest.
            if (variables.contains(unnestedVar)) {
                return false;
            }
        } else {
            if (r.getOperatorTag() == LogicalOperatorTag.AGGREGATE) {
                metAggregate = true;
            }
            break;
        }
    }
    if (!metAggregate) {
        return false;
    }
    AggregateOperator agg = (AggregateOperator) r;
    if (agg.getVariables().size() > 1) {
        return false;
    }
    LogicalVariable aggVar = agg.getVariables().get(0);
    ILogicalExpression aggFun = agg.getExpressions().get(0).getValue();
    if (!aggVar.equals(unnestedVar) || ((AbstractLogicalExpression) aggFun).getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return false;
    }
    AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) aggFun;
    if (!BuiltinFunctions.LISTIFY.equals(f.getFunctionIdentifier())) {
        return false;
    }
    if (f.getArguments().size() != 1) {
        return false;
    }
    ILogicalExpression arg0 = f.getArguments().get(0).getValue();
    if (((AbstractLogicalExpression) arg0).getExpressionTag() != LogicalExpressionTag.VARIABLE) {
        return false;
    }
    LogicalVariable paramVar = ((VariableReferenceExpression) arg0).getVariableReference();
    List<LogicalVariable> assgnVars = new ArrayList<>(1);
    assgnVars.add(unnest1.getVariable());
    List<Mutable<ILogicalExpression>> assgnExprs = new ArrayList<>(1);
    assgnExprs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(paramVar)));
    AssignOperator assign = new AssignOperator(assgnVars, assgnExprs);
    assign.getInputs().add(agg.getInputs().get(0));
    context.computeAndSetTypeEnvironmentForOperator(assign);
    LogicalVariable posVar = unnest1.getPositionalVariable();
    if (posVar == null) {
        // Removes the aggregate operator.
        aggregateParentRef.setValue(assign);
    } else {
        List<LogicalVariable> raggVars = new ArrayList<>(1);
        raggVars.add(posVar);
        List<Mutable<ILogicalExpression>> rAggExprs = new ArrayList<>(1);
        StatefulFunctionCallExpression tidFun = new StatefulFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.TID), UnpartitionedPropertyComputer.INSTANCE);
        rAggExprs.add(new MutableObject<ILogicalExpression>(tidFun));
        RunningAggregateOperator rAgg = new RunningAggregateOperator(raggVars, rAggExprs);
        rAgg.getInputs().add(new MutableObject<ILogicalOperator>(assign));
        aggregateParentRef.setValue(rAgg);
        context.computeAndSetTypeEnvironmentForOperator(rAgg);
    }
    // Removes the unnest operator.
    opRef.setValue(unnest1.getInputs().get(0).getValue());
    return true;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) AbstractLogicalExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression) StatefulFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.StatefulFunctionCallExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ArrayList(java.util.ArrayList) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) UnnestOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) AggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator) RunningAggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.RunningAggregateOperator) RunningAggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.RunningAggregateOperator)

Example 2 with AbstractLogicalExpression

use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression in project asterixdb by apache.

the class RecordRemoveFieldsTypeComputer method computeType.

@Override
public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
    AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expression;
    String funcName = funcExpr.getFunctionIdentifier().getName();
    IAType type0 = (IAType) env.getType(funcExpr.getArguments().get(0).getValue());
    List<List<String>> pathList = new ArrayList<>();
    Set<String> fieldNameSet = new HashSet<>();
    Deque<String> fieldPathStack = new ArrayDeque<>();
    ARecordType inputRecordType = getRecordTypeFromType(funcName, type0);
    if (inputRecordType == null) {
        return BuiltinType.ANY;
    }
    AbstractLogicalExpression arg1 = (AbstractLogicalExpression) funcExpr.getArguments().get(1).getValue();
    IAType inputListType = (IAType) env.getType(arg1);
    AOrderedListType inputOrderedListType = TypeComputeUtils.extractOrderedListType(inputListType);
    if (inputOrderedListType == null) {
        throw new TypeMismatchException(funcName, 1, inputListType.getTypeTag(), ATypeTag.ARRAY);
    }
    ATypeTag tt = inputOrderedListType.getItemType().getTypeTag();
    if (tt == ATypeTag.STRING) {
        // If top-fieldlist
        if (setFieldNameSet(arg1, fieldNameSet)) {
            return buildOutputType(fieldPathStack, inputRecordType, fieldNameSet, pathList);
        } else {
            return DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
        }
    } else {
        // tt == ATypeTag.ANY, meaning the list is nested
        computeTypeFromNonConstantExpression(funcName, arg1, fieldNameSet, pathList);
        IAType resultType = buildOutputType(fieldPathStack, inputRecordType, fieldNameSet, pathList);
        return resultType;
    }
}
Also used : AbstractLogicalExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) AOrderedListType(org.apache.asterix.om.types.AOrderedListType) TypeMismatchException(org.apache.asterix.om.exceptions.TypeMismatchException) ArrayList(java.util.ArrayList) AString(org.apache.asterix.om.base.AString) ArrayDeque(java.util.ArrayDeque) ATypeTag(org.apache.asterix.om.types.ATypeTag) AOrderedList(org.apache.asterix.om.base.AOrderedList) ArrayList(java.util.ArrayList) List(java.util.List) ARecordType(org.apache.asterix.om.types.ARecordType) IAType(org.apache.asterix.om.types.IAType) HashSet(java.util.HashSet)

Example 3 with AbstractLogicalExpression

use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression in project asterixdb by apache.

the class IntroduceLSMComponentFilterRule method getFieldNameFromSubAssignTree.

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 == BuiltinFunctions.FIELD_ACCESS_BY_NAME || funcIdent == BuiltinFunctions.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<>();
        expr.getUsedVariables(usedVars);
        LogicalVariable usedVar = usedVars.get(0);
        List<String> returnList = new ArrayList<>();
        //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 == BuiltinFunctions.FIELD_ACCESS_BY_NAME) {
            String fieldName = ConstantExpressionUtil.getStringArgument(funcExpr, 1);
            if (fieldName == null) {
                return null;
            }
            returnList.add(fieldName);
            return new Pair<>(recType, returnList);
        } else if (funcIdent == BuiltinFunctions.FIELD_ACCESS_BY_INDEX) {
            Integer fieldIndex = ConstantExpressionUtil.getIntArgument(funcExpr, 1);
            if (fieldIndex == null) {
                return null;
            }
            returnList.add(recType.getFieldNames()[fieldIndex]);
            IAType subType = recType.getFieldTypes()[fieldIndex];
            if (subType.getTypeTag() == ATypeTag.OBJECT) {
                recType = (ARecordType) subType;
            }
            return new Pair<>(recType, returnList);
        }
    }
    ILogicalExpression argExpr = funcExpr.getArguments().get(0).getValue();
    if (argExpr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
        return null;
    }
    return null;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractLogicalExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ArrayList(java.util.ArrayList) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) FunctionIdentifier(org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) ARecordType(org.apache.asterix.om.types.ARecordType) Pair(org.apache.hyracks.algebricks.common.utils.Pair) IAType(org.apache.asterix.om.types.IAType)

Example 4 with AbstractLogicalExpression

use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression in project asterixdb by apache.

the class PushFunctionsBelowJoin method gatherFunctionCalls.

private void gatherFunctionCalls(Mutable<ILogicalExpression> exprRef, List<Mutable<ILogicalExpression>> funcExprs) {
    AbstractLogicalExpression expr = (AbstractLogicalExpression) exprRef.getValue();
    if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return;
    }
    // Check whether the function is a function we want to push.
    AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
    if (toPushFuncIdents.contains(funcExpr.getFunctionIdentifier())) {
        funcExprs.add(exprRef);
    }
    // Traverse arguments.
    for (Mutable<ILogicalExpression> funcArg : funcExpr.getArguments()) {
        gatherFunctionCalls(funcArg, funcExprs);
    }
}
Also used : ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AbstractLogicalExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)

Example 5 with AbstractLogicalExpression

use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression in project asterixdb by apache.

the class LoadRecordFieldsRule method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
    if (context.checkIfInDontApplySet(this, op1)) {
        return false;
    }
    if (op1.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
        AssignOperator a1 = (AssignOperator) op1;
        ILogicalExpression expr = getFirstExpr(a1);
        if (AnalysisUtil.isAccessToFieldRecord(expr)) {
            boolean res = findAndEliminateRedundantFieldAccess(a1, context);
            context.addToDontApplySet(this, op1);
            return res;
        }
    }
    exprVisitor.setTopOp(op1);
    exprVisitor.setContext(context);
    boolean res = op1.acceptExpressionTransform(exprVisitor);
    if (!res) {
        context.addToDontApplySet(this, op1);
    }
    if (res && op1.getOperatorTag() == LogicalOperatorTag.SELECT) {
        // checking if we can annotate a Selection as using just one field
        // access
        SelectOperator sigma = (SelectOperator) op1;
        LinkedList<LogicalVariable> vars = new LinkedList<LogicalVariable>();
        VariableUtilities.getUsedVariables(sigma, vars);
        if (vars.size() == 1) {
            // we can annotate Selection
            AssignOperator assign1 = (AssignOperator) op1.getInputs().get(0).getValue();
            AbstractLogicalExpression expr1 = (AbstractLogicalExpression) getFirstExpr(assign1);
            if (expr1.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
                AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expr1;
                // f should be a call to a field/data access kind of
                // function
                sigma.getAnnotations().put(OperatorAnnotation.FIELD_ACCESS, f.getArguments().get(0));
            }
        }
    }
    // TODO: avoid having to recompute type env. here
    if (res) {
        OperatorPropertiesUtil.typeOpRec(opRef, context);
    }
    return res;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) SelectOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) AbstractLogicalExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) LinkedList(java.util.LinkedList)

Aggregations

AbstractLogicalExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression)9 AbstractFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)8 ILogicalExpression (org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression)7 AbstractLogicalOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator)6 AssignOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator)6 ArrayList (java.util.ArrayList)5 LogicalVariable (org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable)5 ILogicalOperator (org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)3 VariableReferenceExpression (org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression)3 FunctionIdentifier (org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier)3 UnnestOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator)3 LinkedList (java.util.LinkedList)2 List (java.util.List)2 AOrderedList (org.apache.asterix.om.base.AOrderedList)2 AString (org.apache.asterix.om.base.AString)2 ARecordType (org.apache.asterix.om.types.ARecordType)2 IAType (org.apache.asterix.om.types.IAType)2 Mutable (org.apache.commons.lang3.mutable.Mutable)2 StatefulFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.StatefulFunctionCallExpression)2 AggregateOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator)2