Search in sources :

Example 96 with IAType

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

the class IntroduceSecondaryIndexInsertDeleteRule method createFilterExpression.

private Mutable<ILogicalExpression> createFilterExpression(List<LogicalVariable> secondaryKeyVars, IVariableTypeEnvironment typeEnv, boolean forceFilter) throws AlgebricksException {
    List<Mutable<ILogicalExpression>> filterExpressions = new ArrayList<>();
    // condition.
    for (LogicalVariable secondaryKeyVar : secondaryKeyVars) {
        IAType secondaryKeyType = (IAType) typeEnv.getVarType(secondaryKeyVar);
        if (!NonTaggedFormatUtil.isOptional(secondaryKeyType) && !forceFilter) {
            continue;
        }
        ScalarFunctionCallExpression isUnknownFuncExpr = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.IS_UNKOWN), new MutableObject<ILogicalExpression>(new VariableReferenceExpression(secondaryKeyVar)));
        ScalarFunctionCallExpression notFuncExpr = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.NOT), new MutableObject<ILogicalExpression>(isUnknownFuncExpr));
        filterExpressions.add(new MutableObject<ILogicalExpression>(notFuncExpr));
    }
    // No nullable secondary keys.
    if (filterExpressions.isEmpty()) {
        return null;
    }
    Mutable<ILogicalExpression> filterExpression;
    if (filterExpressions.size() > 1) {
        // Create a conjunctive condition.
        filterExpression = new MutableObject<>(new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.AND), filterExpressions));
    } else {
        filterExpression = filterExpressions.get(0);
    }
    return filterExpression;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) 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) ArrayList(java.util.ArrayList) IAType(org.apache.asterix.om.types.IAType) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)

Example 97 with IAType

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

the class IntroduceStaticTypeCastForInsertRule method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    /**
         * pattern match: sink/insert/assign record type is propagated from
         * insert data source to the record-constructor expression
         */
    if (context.checkIfInDontApplySet(this, opRef.getValue())) {
        return false;
    }
    context.addToDontApplySet(this, opRef.getValue());
    AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
    List<LogicalVariable> producedVariables = new ArrayList<LogicalVariable>();
    LogicalVariable oldRecordVariable;
    if (op1.getOperatorTag() != LogicalOperatorTag.DELEGATE_OPERATOR && op1.getOperatorTag() != LogicalOperatorTag.SINK) {
        return false;
    }
    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) {
        return false;
    }
    InsertDeleteUpsertOperator insertDeleteOp = (InsertDeleteUpsertOperator) op2;
    if (insertDeleteOp.getOperation() == InsertDeleteUpsertOperator.Kind.DELETE) {
        return false;
    }
    /**
         * get required record type
         */
    InsertDeleteUpsertOperator insertDeleteOperator = (InsertDeleteUpsertOperator) op2;
    DataSource dataSource = (DataSource) insertDeleteOperator.getDataSource();
    IAType requiredRecordType = dataSource.getItemType();
    List<LogicalVariable> usedVariables = new ArrayList<LogicalVariable>();
    insertDeleteOperator.getPayloadExpression().getValue().getUsedVariables(usedVariables);
    // empty
    if (usedVariables.size() == 0) {
        return false;
    }
    oldRecordVariable = usedVariables.get(0);
    LogicalVariable inputRecordVar = usedVariables.get(0);
    IVariableTypeEnvironment env = insertDeleteOperator.computeOutputTypeEnvironment(context);
    IAType inputRecordType = (IAType) env.getVarType(inputRecordVar);
    AbstractLogicalOperator currentOperator = (AbstractLogicalOperator) op2.getInputs().get(0).getValue();
    /**
         * find the assign operator for the "input record" to the insert_delete
         * operator
         */
    do {
        context.addToDontApplySet(this, currentOperator);
        if (currentOperator.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
            AssignOperator assignOp = (AssignOperator) currentOperator;
            producedVariables.clear();
            VariableUtilities.getProducedVariables(currentOperator, producedVariables);
            int position = producedVariables.indexOf(oldRecordVariable);
            /**
                 * set the top-down propagated type
                 */
            if (position >= 0) {
                AssignOperator originalAssign = (AssignOperator) currentOperator;
                List<Mutable<ILogicalExpression>> expressionRefs = originalAssign.getExpressions();
                ILogicalExpression expr = expressionRefs.get(position).getValue();
                if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
                    AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
                    // fail but just return false
                    if (TypeCastUtils.getRequiredType(funcExpr) != null) {
                        context.computeAndSetTypeEnvironmentForOperator(assignOp);
                        return false;
                    }
                    IVariableTypeEnvironment assignEnv = assignOp.computeOutputTypeEnvironment(context);
                    StaticTypeCastUtil.rewriteFuncExpr(funcExpr, requiredRecordType, inputRecordType, assignEnv);
                }
                context.computeAndSetTypeEnvironmentForOperator(originalAssign);
            }
        }
        if (currentOperator.getInputs().size() > 0) {
            currentOperator = (AbstractLogicalOperator) currentOperator.getInputs().get(0).getValue();
        } else {
            break;
        }
    } while (currentOperator != null);
    return true;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) 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) DataSource(org.apache.asterix.metadata.declared.DataSource) Mutable(org.apache.commons.lang3.mutable.Mutable) 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) CommitOperator(org.apache.asterix.algebra.operators.CommitOperator) IVariableTypeEnvironment(org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment) IAType(org.apache.asterix.om.types.IAType)

Example 98 with IAType

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

the class IntroduceDynamicTypeCastRule method addWrapperFunction.

/**
     * Inject a function to wrap a variable when necessary
     *
     * @param requiredRecordType
     *            the required record type
     * @param recordVar
     *            the record variable
     * @param parent
     *            the current parent operator to be rewritten
     * @param context
     *            the optimization context
     * @param fd
     *            the function to be injected
     * @return true if cast is injected; false otherwise.
     * @throws AlgebricksException
     */
public static LogicalVariable addWrapperFunction(ARecordType requiredRecordType, LogicalVariable recordVar, ILogicalOperator parent, IOptimizationContext context, FunctionIdentifier fd) throws AlgebricksException {
    List<Mutable<ILogicalOperator>> opRefs = parent.getInputs();
    for (int index = 0; index < opRefs.size(); index++) {
        Mutable<ILogicalOperator> opRef = opRefs.get(index);
        ILogicalOperator op = opRef.getValue();
        /** get produced vars */
        List<LogicalVariable> producedVars = new ArrayList<LogicalVariable>();
        VariableUtilities.getProducedVariables(op, producedVars);
        IVariableTypeEnvironment env = op.computeOutputTypeEnvironment(context);
        for (int i = 0; i < producedVars.size(); i++) {
            LogicalVariable var = producedVars.get(i);
            if (var.equals(recordVar)) {
                /** insert an assign operator to call the function on-top-of the variable */
                IAType actualType = (IAType) env.getVarType(var);
                AbstractFunctionCallExpression cast = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(fd));
                cast.getArguments().add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(var)));
                /** enforce the required record type */
                TypeCastUtils.setRequiredAndInputTypes(cast, requiredRecordType, actualType);
                LogicalVariable newAssignVar = context.newVar();
                AssignOperator newAssignOperator = new AssignOperator(newAssignVar, new MutableObject<ILogicalExpression>(cast));
                newAssignOperator.getInputs().add(new MutableObject<ILogicalOperator>(op));
                opRef.setValue(newAssignOperator);
                context.computeAndSetTypeEnvironmentForOperator(newAssignOperator);
                newAssignOperator.computeOutputTypeEnvironment(context);
                VariableUtilities.substituteVariables(parent, recordVar, newAssignVar, context);
                return newAssignVar;
            }
        }
        /** recursive descend to the operator who produced the recordVar */
        LogicalVariable replacedVar = addWrapperFunction(requiredRecordType, recordVar, op, context, fd);
        if (replacedVar != null) {
            /** substitute the recordVar by the replacedVar for operators who uses recordVar */
            VariableUtilities.substituteVariables(parent, recordVar, replacedVar, context);
            return replacedVar;
        }
    }
    return null;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ArrayList(java.util.ArrayList) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) 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) 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 99 with IAType

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

the class PushFieldAccessRule method isAccessToIndexedField.

@SuppressWarnings("unchecked")
private boolean isAccessToIndexedField(AssignOperator assign, IOptimizationContext context) throws AlgebricksException {
    AbstractFunctionCallExpression accessFun = (AbstractFunctionCallExpression) assign.getExpressions().get(0).getValue();
    ILogicalExpression e0 = accessFun.getArguments().get(0).getValue();
    if (e0.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
        return false;
    }
    LogicalVariable var = ((VariableReferenceExpression) e0).getVariableReference();
    if (context.findPrimaryKey(var) == null) {
        // not referring to a dataset record
        return false;
    }
    AbstractLogicalOperator op = assign;
    while (op.getInputs().size() == 1 && op.getOperatorTag() != LogicalOperatorTag.DATASOURCESCAN) {
        op = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
    }
    if (op.getOperatorTag() != LogicalOperatorTag.DATASOURCESCAN) {
        return false;
    }
    DataSourceScanOperator scan = (DataSourceScanOperator) op;
    LogicalVariable recVar = scan.getVariables().get(scan.getVariables().size() - 1);
    if (recVar != var) {
        return false;
    }
    MetadataProvider mp = (MetadataProvider) context.getMetadataProvider();
    DataSourceId asid = ((IDataSource<DataSourceId>) scan.getDataSource()).getId();
    Dataset dataset = mp.findDataset(asid.getDataverseName(), asid.getDatasourceName());
    if (dataset == null) {
        throw new AlgebricksException("Dataset " + asid.getDatasourceName() + " not found.");
    }
    if (dataset.getDatasetType() != DatasetType.INTERNAL) {
        return false;
    }
    final Integer pos = ConstantExpressionUtil.getIntConstant(accessFun.getArguments().get(1).getValue());
    if (pos != null) {
        String tName = dataset.getItemTypeName();
        IAType t = mp.findType(dataset.getItemTypeDataverseName(), tName);
        if (t.getTypeTag() != ATypeTag.OBJECT) {
            return false;
        }
        ARecordType rt = (ARecordType) t;
        if (pos >= rt.getFieldNames().length) {
            return false;
        }
    }
    List<Index> datasetIndexes = mp.getDatasetIndexes(dataset.getDataverseName(), dataset.getDatasetName());
    boolean hasSecondaryIndex = false;
    for (Index index : datasetIndexes) {
        if (index.isSecondaryIndex()) {
            hasSecondaryIndex = true;
            break;
        }
    }
    return hasSecondaryIndex;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) Dataset(org.apache.asterix.metadata.entities.Dataset) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) AlgebricksException(org.apache.hyracks.algebricks.common.exceptions.AlgebricksException) Index(org.apache.asterix.metadata.entities.Index) AString(org.apache.asterix.om.base.AString) IDataSource(org.apache.hyracks.algebricks.core.algebra.metadata.IDataSource) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) DataSourceScanOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator) MetadataProvider(org.apache.asterix.metadata.declared.MetadataProvider) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) ARecordType(org.apache.asterix.om.types.ARecordType) DataSourceId(org.apache.asterix.metadata.declared.DataSourceId) IAType(org.apache.asterix.om.types.IAType)

Example 100 with IAType

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

the class IntroduceDynamicTypeCastRule method compatible.

/**
     * Check whether the required record type and the input type is compatible
     *
     * @param reqType
     * @param inputType
     * @return true if compatible; false otherwise
     * @throws AlgebricksException
     */
public static boolean compatible(ARecordType reqType, IAType inputType) throws AlgebricksException {
    if (inputType.getTypeTag() == ATypeTag.ANY) {
        return false;
    }
    if (inputType.getTypeTag() != ATypeTag.OBJECT) {
        throw new AlgebricksException("The input type " + inputType + " is not a valid record type!");
    }
    ARecordType inputRecType = (ARecordType) inputType;
    if (reqType.isOpen() != inputRecType.isOpen()) {
        return false;
    }
    IAType[] reqTypes = reqType.getFieldTypes();
    String[] reqFieldNames = reqType.getFieldNames();
    IAType[] inputTypes = inputRecType.getFieldTypes();
    String[] inputFieldNames = ((ARecordType) inputType).getFieldNames();
    if (reqTypes.length != inputTypes.length) {
        return false;
    }
    for (int i = 0; i < reqTypes.length; i++) {
        if (!reqFieldNames[i].equals(inputFieldNames[i])) {
            return false;
        }
        IAType reqTypeInside = reqTypes[i];
        if (NonTaggedFormatUtil.isOptional(reqTypes[i])) {
            reqTypeInside = ((AUnionType) reqTypes[i]).getActualType();
        }
        IAType inputTypeInside = inputTypes[i];
        if (NonTaggedFormatUtil.isOptional(inputTypes[i])) {
            if (!NonTaggedFormatUtil.isOptional(reqTypes[i])) {
                /** if the required type is not optional, the two types are incompatible */
                return false;
            }
            inputTypeInside = ((AUnionType) inputTypes[i]).getActualType();
        }
        if (inputTypeInside.getTypeTag() != ATypeTag.MISSING && !reqTypeInside.equals(inputTypeInside)) {
            return false;
        }
    }
    return true;
}
Also used : AlgebricksException(org.apache.hyracks.algebricks.common.exceptions.AlgebricksException) ARecordType(org.apache.asterix.om.types.ARecordType) 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