Search in sources :

Example 71 with AbstractFunctionCallExpression

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

the class PushSelectIntoJoinRule method addCondToJoin.

private static void addCondToJoin(SelectOperator select, AbstractBinaryJoinOperator join, IOptimizationContext context) {
    ILogicalExpression cond = join.getCondition().getValue();
    if (OperatorPropertiesUtil.isAlwaysTrueCond(cond)) {
        // the join was a product
        join.getCondition().setValue(select.getCondition().getValue());
    } else {
        boolean bAddedToConj = false;
        if (cond.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
            AbstractFunctionCallExpression fcond = (AbstractFunctionCallExpression) cond;
            if (fcond.getFunctionIdentifier().equals(AlgebricksBuiltinFunctions.AND)) {
                AbstractFunctionCallExpression newCond = new ScalarFunctionCallExpression(context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.AND));
                newCond.getArguments().add(select.getCondition());
                newCond.getArguments().addAll(fcond.getArguments());
                join.getCondition().setValue(newCond);
                bAddedToConj = true;
            }
        }
        if (!bAddedToConj) {
            AbstractFunctionCallExpression newCond = new ScalarFunctionCallExpression(context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.AND), select.getCondition(), new MutableObject<ILogicalExpression>(join.getCondition().getValue()));
            join.getCondition().setValue(newCond);
        }
    }
}
Also used : ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)

Example 72 with AbstractFunctionCallExpression

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

Example 73 with AbstractFunctionCallExpression

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

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

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

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