Search in sources :

Example 16 with AbstractFunctionCallExpression

use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression 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 17 with AbstractFunctionCallExpression

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

the class ResolveVariableRule method cleanupScanCollectionForDataset.

// Cleans up scan collections on top of a "dataset" function call since "dataset"
// is an unnest function.
private void cleanupScanCollectionForDataset(AbstractFunctionCallExpression funcExpr) {
    if (funcExpr.getFunctionIdentifier() != BuiltinFunctions.SCAN_COLLECTION) {
        return;
    }
    ILogicalExpression arg = funcExpr.getArguments().get(0).getValue();
    if (arg.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return;
    }
    AbstractFunctionCallExpression argFuncExpr = (AbstractFunctionCallExpression) arg;
    if (argFuncExpr.getFunctionIdentifier() != BuiltinFunctions.DATASET) {
        return;
    }
    funcExpr.setFunctionInfo(argFuncExpr.getFunctionInfo());
    funcExpr.getArguments().clear();
    funcExpr.getArguments().addAll(argFuncExpr.getArguments());
}
Also used : ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)

Example 18 with AbstractFunctionCallExpression

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

the class RemoveLeftOuterUnnestForLeftOuterJoinRule method checkSelect.

// Checks the expression for the nested select operator inside the group-by operator.
private Pair<Boolean, ILogicalExpression> checkSelect(SelectOperator select) {
    ILogicalExpression condition = select.getCondition().getValue();
    if (condition.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return new Pair<>(false, null);
    }
    AbstractFunctionCallExpression conditionFunc = (AbstractFunctionCallExpression) condition;
    if (!conditionFunc.getFunctionIdentifier().equals(BuiltinFunctions.NOT)) {
        return new Pair<>(false, null);
    }
    condition = conditionFunc.getArguments().get(0).getValue();
    if (condition.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return new Pair<>(false, null);
    }
    conditionFunc = (AbstractFunctionCallExpression) condition;
    if (!conditionFunc.getFunctionIdentifier().equals(BuiltinFunctions.IS_MISSING)) {
        return new Pair<>(false, null);
    }
    ILogicalExpression conditionArg = conditionFunc.getArguments().get(0).getValue();
    return new Pair<>(true, conditionArg);
}
Also used : ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) Pair(org.apache.hyracks.algebricks.common.utils.Pair)

Example 19 with AbstractFunctionCallExpression

use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression 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 20 with AbstractFunctionCallExpression

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

the class OpenRecordConstructorResultType method computeType.

@Override
public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
    AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression;
    /**
         * if type has been top-down propagated, use the enforced type
         */
    ARecordType type = (ARecordType) TypeCastUtils.getRequiredType(f);
    if (type != null) {
        return type;
    }
    Iterator<Mutable<ILogicalExpression>> argIter = f.getArguments().iterator();
    List<String> namesList = new ArrayList<>();
    List<IAType> typesList = new ArrayList<>();
    // The following set of names do not belong to the closed part,
    // but are additional possible field names. For example, a field "foo" with type
    // ANY cannot be in the closed part, but "foo" is a possible field name.
    Set<String> allPossibleAdditionalFieldNames = new HashSet<>();
    boolean canProvideAdditionFieldInfo = true;
    boolean isOpen = false;
    while (argIter.hasNext()) {
        ILogicalExpression e1 = argIter.next().getValue();
        ILogicalExpression e2 = argIter.next().getValue();
        IAType t2 = (IAType) env.getType(e2);
        String fieldName = ConstantExpressionUtil.getStringConstant(e1);
        if (fieldName != null && t2 != null && TypeHelper.isClosed(t2)) {
            namesList.add(fieldName);
            if (t2.getTypeTag() == ATypeTag.UNION) {
                AUnionType unionType = (AUnionType) t2;
                t2 = AUnionType.createUnknownableType(unionType.getActualType());
            }
            typesList.add(t2);
        } else {
            if (canProvideAdditionFieldInfo && fieldName != null) {
                allPossibleAdditionalFieldNames.add(fieldName);
            } else {
                canProvideAdditionFieldInfo = false;
            }
            isOpen = true;
        }
    }
    String[] fieldNames = namesList.toArray(new String[0]);
    IAType[] fieldTypes = typesList.toArray(new IAType[0]);
    return canProvideAdditionFieldInfo ? new ARecordType(null, fieldNames, fieldTypes, isOpen, allPossibleAdditionalFieldNames) : new ARecordType(null, fieldNames, fieldTypes, isOpen);
}
Also used : AUnionType(org.apache.asterix.om.types.AUnionType) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ArrayList(java.util.ArrayList) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) ARecordType(org.apache.asterix.om.types.ARecordType) IAType(org.apache.asterix.om.types.IAType) HashSet(java.util.HashSet)

Aggregations

AbstractFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)138 ILogicalExpression (org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression)111 Mutable (org.apache.commons.lang3.mutable.Mutable)59 LogicalVariable (org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable)54 ArrayList (java.util.ArrayList)50 VariableReferenceExpression (org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression)38 IAType (org.apache.asterix.om.types.IAType)37 AssignOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator)37 ILogicalOperator (org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)35 AbstractLogicalOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator)35 FunctionIdentifier (org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier)34 ScalarFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)33 ConstantExpression (org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression)25 ARecordType (org.apache.asterix.om.types.ARecordType)20 AsterixConstantValue (org.apache.asterix.om.constants.AsterixConstantValue)19 AlgebricksException (org.apache.hyracks.algebricks.common.exceptions.AlgebricksException)19 Pair (org.apache.hyracks.algebricks.common.utils.Pair)19 MutableObject (org.apache.commons.lang3.mutable.MutableObject)18 AString (org.apache.asterix.om.base.AString)17 MetadataProvider (org.apache.asterix.metadata.declared.MetadataProvider)13