Search in sources :

Example 41 with IAType

use of org.apache.asterix.om.types.IAType in project asterixdb by apache.

the class TypeResolverUtilTest method testIsmophicRecordType.

@Test
public void testIsmophicRecordType() {
    // Constructs input types.
    ARecordType leftRecordType = new ARecordType(null, new String[] { "a", "b" }, new IAType[] { BuiltinType.ASTRING, BuiltinType.AINT32 }, false, null);
    ARecordType rightRecordType = new ARecordType(null, new String[] { "b", "a" }, new IAType[] { BuiltinType.AINT32, BuiltinType.ASTRING }, false, null);
    // Resolves input types to a generalized type.
    List<IAType> inputTypes = new ArrayList<>();
    inputTypes.add(leftRecordType);
    inputTypes.add(rightRecordType);
    ARecordType resolvedType = (ARecordType) TypeResolverUtil.resolve(inputTypes);
    // Compares the resolved type with the expected type.
    Assert.assertEquals(resolvedType, leftRecordType);
}
Also used : ArrayList(java.util.ArrayList) ARecordType(org.apache.asterix.om.types.ARecordType) IAType(org.apache.asterix.om.types.IAType) Test(org.junit.Test)

Example 42 with IAType

use of org.apache.asterix.om.types.IAType in project asterixdb by apache.

the class InjectTypeCastForSwitchCaseRule method rewriteSwitchCase.

// Injects casts that cast types for different "THEN" and "ELSE" branches.
private boolean rewriteSwitchCase(ILogicalOperator op, AbstractFunctionCallExpression func, IOptimizationContext context) throws AlgebricksException {
    IVariableTypeEnvironment env = context.getOutputTypeEnvironment(op.getInputs().get(0).getValue());
    IAType producedType = (IAType) env.getType(func);
    List<Mutable<ILogicalExpression>> argRefs = func.getArguments();
    int argSize = argRefs.size();
    boolean rewritten = false;
    for (int argIndex = 2; argIndex < argSize; argIndex += (argIndex + 2 == argSize) ? 1 : 2) {
        Mutable<ILogicalExpression> argRef = argRefs.get(argIndex);
        IAType type = (IAType) env.getType(argRefs.get(argIndex).getValue());
        if (TypeResolverUtil.needsCast(producedType, type)) {
            ILogicalExpression argExpr = argRef.getValue();
            // Injects a cast call to cast the data type to the produced type of the switch-case function call.
            ScalarFunctionCallExpression castFunc = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CAST_TYPE), new ArrayList<>(Collections.singletonList(new MutableObject<>(argExpr))));
            TypeCastUtils.setRequiredAndInputTypes(castFunc, producedType, type);
            argRef.setValue(castFunc);
            rewritten = true;
        }
    }
    return rewritten;
}
Also used : Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) IVariableTypeEnvironment(org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment) IAType(org.apache.asterix.om.types.IAType) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)

Example 43 with IAType

use of org.apache.asterix.om.types.IAType in project asterixdb by apache.

the class InjectTypeCastForUnionRule method injectCast.

// Injects a type cast function on one input (indicated by childIndex) of the union all operator if necessary.
private boolean injectCast(UnionAllOperator op, int childIndex, IOptimizationContext context) throws AlgebricksException {
    // Gets the type environments for the union all operator and its child operator with the right child index.
    IVariableTypeEnvironment env = context.getOutputTypeEnvironment(op);
    Mutable<ILogicalOperator> branchOpRef = op.getInputs().get(childIndex);
    IVariableTypeEnvironment childEnv = context.getOutputTypeEnvironment(branchOpRef.getValue());
    // The two lists are used for the assign operator that calls cast functions.
    List<LogicalVariable> varsToCast = new ArrayList<>();
    List<Mutable<ILogicalExpression>> castFunctionsForLeft = new ArrayList<>();
    // Iterate through all triples.
    List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> triples = op.getVariableMappings();
    for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> triple : triples) {
        LogicalVariable producedVar = triple.third;
        IAType producedType = (IAType) env.getVarType(producedVar);
        LogicalVariable varToCast = childIndex == 0 ? triple.first : triple.second;
        IAType inputType = (IAType) childEnv.getVarType(varToCast);
        if (!TypeResolverUtil.needsCast(producedType, inputType)) {
            // Continues to the next triple if no cast is neeeded.
            continue;
        }
        LogicalVariable castedVar = context.newVar();
        // Resets triple variables to new variables that bind to the results of type casting.
        triple.first = childIndex == 0 ? castedVar : triple.first;
        triple.second = childIndex > 0 ? castedVar : triple.second;
        ScalarFunctionCallExpression castFunc = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CAST_TYPE), new ArrayList<>(Collections.singletonList(new MutableObject<>(new VariableReferenceExpression(varToCast)))));
        TypeCastUtils.setRequiredAndInputTypes(castFunc, producedType, inputType);
        // Adds the variable and function expression into lists, for the assign operator.
        varsToCast.add(castedVar);
        castFunctionsForLeft.add(new MutableObject<>(castFunc));
    }
    if (castFunctionsForLeft.isEmpty()) {
        return false;
    }
    // Injects an assign operator to perform type casts.
    AssignOperator assignOp = new AssignOperator(varsToCast, castFunctionsForLeft);
    assignOp.getInputs().add(new MutableObject<>(branchOpRef.getValue()));
    branchOpRef.setValue(assignOp);
    context.computeAndSetTypeEnvironmentForOperator(assignOp);
    // Returns true to indicate that rewriting happens.
    return true;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ArrayList(java.util.ArrayList) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) Triple(org.apache.hyracks.algebricks.common.utils.Triple) Mutable(org.apache.commons.lang3.mutable.Mutable) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) IVariableTypeEnvironment(org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment) IAType(org.apache.asterix.om.types.IAType) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)

Example 44 with IAType

use of org.apache.asterix.om.types.IAType in project asterixdb by apache.

the class IntroduceDynamicTypeCastForExternalFunctionRule method rewriteFunctionArgs.

private boolean rewriteFunctionArgs(ILogicalOperator op, Mutable<ILogicalExpression> expRef, IOptimizationContext context) throws AlgebricksException {
    ILogicalExpression expr = expRef.getValue();
    if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL || !(expr instanceof ScalarFunctionCallExpression)) {
        return false;
    }
    ScalarFunctionCallExpression funcCallExpr = (ScalarFunctionCallExpression) expr;
    boolean changed = false;
    IAType inputRecordType;
    ARecordType requiredRecordType;
    for (int iter1 = 0; iter1 < funcCallExpr.getArguments().size(); iter1++) {
        inputRecordType = (IAType) op.computeOutputTypeEnvironment(context).getType(funcCallExpr.getArguments().get(iter1).getValue());
        if (!(((ExternalScalarFunctionInfo) funcCallExpr.getFunctionInfo()).getArgumenTypes().get(iter1) instanceof ARecordType)) {
            continue;
        }
        requiredRecordType = (ARecordType) ((ExternalScalarFunctionInfo) funcCallExpr.getFunctionInfo()).getArgumenTypes().get(iter1);
        /**
             * the input record type can be an union type
             * for the case when it comes from a subplan or left-outer join
             */
        boolean checkUnknown = false;
        while (NonTaggedFormatUtil.isOptional(inputRecordType)) {
            /** while-loop for the case there is a nested multi-level union */
            inputRecordType = ((AUnionType) inputRecordType).getActualType();
            checkUnknown = true;
        }
        boolean castFlag = !IntroduceDynamicTypeCastRule.compatible(requiredRecordType, inputRecordType);
        if (castFlag || checkUnknown) {
            AbstractFunctionCallExpression castFunc = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CAST_TYPE));
            castFunc.getArguments().add(funcCallExpr.getArguments().get(iter1));
            TypeCastUtils.setRequiredAndInputTypes(castFunc, requiredRecordType, inputRecordType);
            funcCallExpr.getArguments().set(iter1, new MutableObject<>(castFunc));
            changed = changed || true;
        }
    }
    return changed;
}
Also used : ExternalScalarFunctionInfo(org.apache.asterix.metadata.functions.ExternalScalarFunctionInfo) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ARecordType(org.apache.asterix.om.types.ARecordType) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression) IAType(org.apache.asterix.om.types.IAType)

Example 45 with IAType

use of org.apache.asterix.om.types.IAType in project asterixdb by apache.

the class IntroduceDynamicTypeCastRule method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    // Depending on the operator type, we need to extract the following pieces of information.
    AbstractLogicalOperator op;
    ARecordType requiredRecordType;
    LogicalVariable recordVar;
    // We identify INSERT and DISTRIBUTE_RESULT operators.
    AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
    switch(op1.getOperatorTag()) {
        case SINK:
        case DELEGATE_OPERATOR:
            {
                /**
                 * pattern match: commit insert assign
                 * resulting plan: commit-insert-project-assign
                 */
                if (op1.getOperatorTag() == LogicalOperatorTag.DELEGATE_OPERATOR) {
                    DelegateOperator eOp = (DelegateOperator) op1;
                    if (!(eOp.getDelegate() instanceof CommitOperator)) {
                        return false;
                    }
                }
                AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
                if (op2.getOperatorTag() == LogicalOperatorTag.INSERT_DELETE_UPSERT) {
                    InsertDeleteUpsertOperator insertDeleteOp = (InsertDeleteUpsertOperator) op2;
                    if (insertDeleteOp.getOperation() == InsertDeleteUpsertOperator.Kind.DELETE) {
                        return false;
                    }
                    // Remember this is the operator we need to modify
                    op = insertDeleteOp;
                    // Derive the required ARecordType based on the schema of the DataSource
                    InsertDeleteUpsertOperator insertDeleteOperator = (InsertDeleteUpsertOperator) op2;
                    DataSource dataSource = (DataSource) insertDeleteOperator.getDataSource();
                    requiredRecordType = (ARecordType) dataSource.getItemType();
                    // Derive the Variable which we will potentially wrap with cast/null functions
                    ILogicalExpression expr = insertDeleteOperator.getPayloadExpression().getValue();
                    List<LogicalVariable> payloadVars = new ArrayList<>();
                    expr.getUsedVariables(payloadVars);
                    recordVar = payloadVars.get(0);
                } else {
                    return false;
                }
                break;
            }
        case DISTRIBUTE_RESULT:
            {
                // First, see if there was an output-record-type specified
                requiredRecordType = (ARecordType) op1.getAnnotations().get("output-record-type");
                if (requiredRecordType == null) {
                    return false;
                }
                // Remember this is the operator we need to modify
                op = op1;
                recordVar = ((VariableReferenceExpression) ((DistributeResultOperator) op).getExpressions().get(0).getValue()).getVariableReference();
                break;
            }
        default:
            {
                return false;
            }
    }
    // Derive the statically-computed type of the record
    IVariableTypeEnvironment env = op.computeOutputTypeEnvironment(context);
    IAType inputRecordType = (IAType) env.getVarType(recordVar);
    /** the input record type can be an union type -- for the case when it comes from a subplan or left-outer join */
    boolean checkUnknown = false;
    while (NonTaggedFormatUtil.isOptional(inputRecordType)) {
        /** while-loop for the case there is a nested multi-level union */
        inputRecordType = ((AUnionType) inputRecordType).getActualType();
        checkUnknown = true;
    }
    /** see whether the input record type needs to be casted */
    boolean cast = !compatible(requiredRecordType, inputRecordType);
    if (checkUnknown) {
        recordVar = addWrapperFunction(requiredRecordType, recordVar, op, context, BuiltinFunctions.CHECK_UNKNOWN);
    }
    if (cast) {
        addWrapperFunction(requiredRecordType, recordVar, op, context, BuiltinFunctions.CAST_TYPE);
    }
    return cast || checkUnknown;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) DataSource(org.apache.asterix.metadata.declared.DataSource) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) InsertDeleteUpsertOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.InsertDeleteUpsertOperator) DelegateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.DelegateOperator) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) ArrayList(java.util.ArrayList) List(java.util.List) ARecordType(org.apache.asterix.om.types.ARecordType) CommitOperator(org.apache.asterix.algebra.operators.CommitOperator) IVariableTypeEnvironment(org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment) IAType(org.apache.asterix.om.types.IAType)

Aggregations

IAType (org.apache.asterix.om.types.IAType)190 ARecordType (org.apache.asterix.om.types.ARecordType)73 ArrayList (java.util.ArrayList)64 ILogicalExpression (org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression)42 ATypeTag (org.apache.asterix.om.types.ATypeTag)40 AbstractFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)37 List (java.util.List)32 AlgebricksException (org.apache.hyracks.algebricks.common.exceptions.AlgebricksException)32 AUnionType (org.apache.asterix.om.types.AUnionType)31 AString (org.apache.asterix.om.base.AString)28 LogicalVariable (org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable)27 Mutable (org.apache.commons.lang3.mutable.Mutable)25 Pair (org.apache.hyracks.algebricks.common.utils.Pair)24 HyracksDataException (org.apache.hyracks.api.exceptions.HyracksDataException)20 Dataset (org.apache.asterix.metadata.entities.Dataset)18 AsterixException (org.apache.asterix.common.exceptions.AsterixException)17 AOrderedListType (org.apache.asterix.om.types.AOrderedListType)16 VariableReferenceExpression (org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression)16 IVisitablePointable (org.apache.asterix.om.pointables.base.IVisitablePointable)15 IVariableTypeEnvironment (org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment)15