Search in sources :

Example 61 with AbstractFunctionCallExpression

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

the class IntroduceLSMComponentFilterRule method findMacthedExprFieldName.

private boolean findMacthedExprFieldName(IOptimizableFuncExpr optFuncExpr, AbstractLogicalOperator op, Dataset dataset, ARecordType recType, List<Index> datasetIndexes, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator descendantOp = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
    while (descendantOp != null) {
        if (descendantOp.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
            AssignOperator assignOp = (AssignOperator) descendantOp;
            List<LogicalVariable> varList = assignOp.getVariables();
            for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
                LogicalVariable var = varList.get(varIndex);
                int funcVarIndex = optFuncExpr.findLogicalVar(var);
                if (funcVarIndex == -1) {
                    continue;
                }
                List<String> fieldName = getFieldNameFromSubAssignTree(optFuncExpr, descendantOp, varIndex, recType).second;
                if (fieldName == null) {
                    return false;
                }
                optFuncExpr.setFieldName(funcVarIndex, fieldName);
                return true;
            }
        } else if (descendantOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
            DataSourceScanOperator scanOp = (DataSourceScanOperator) descendantOp;
            List<LogicalVariable> varList = scanOp.getVariables();
            for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
                LogicalVariable var = varList.get(varIndex);
                int funcVarIndex = optFuncExpr.findLogicalVar(var);
                if (funcVarIndex == -1) {
                    continue;
                }
                // The variable value is one of the partitioning fields.
                List<String> fieldName = dataset.getPrimaryKeys().get(varIndex);
                if (fieldName == null) {
                    return false;
                }
                optFuncExpr.setFieldName(funcVarIndex, fieldName);
                return true;
            }
        } else if (descendantOp.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
            UnnestMapOperator unnestMapOp = (UnnestMapOperator) descendantOp;
            List<LogicalVariable> varList = unnestMapOp.getVariables();
            for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
                LogicalVariable var = varList.get(varIndex);
                int funcVarIndex = optFuncExpr.findLogicalVar(var);
                if (funcVarIndex == -1) {
                    continue;
                }
                String indexName;
                Index index = null;
                ILogicalExpression unnestExpr = unnestMapOp.getExpressionRef().getValue();
                if (unnestExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
                    AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) unnestExpr;
                    FunctionIdentifier fid = f.getFunctionIdentifier();
                    if (!fid.equals(BuiltinFunctions.INDEX_SEARCH)) {
                        throw new IllegalStateException();
                    }
                    AccessMethodJobGenParams jobGenParams = new AccessMethodJobGenParams();
                    jobGenParams.readFromFuncArgs(f.getArguments());
                    indexName = jobGenParams.indexName;
                    for (Index idx : datasetIndexes) {
                        if (idx.getIndexName().compareTo(indexName) == 0) {
                            index = idx;
                            break;
                        }
                    }
                }
                IAType metaItemType = ((MetadataProvider) context.getMetadataProvider()).findType(dataset.getMetaItemTypeDataverseName(), dataset.getMetaItemTypeName());
                ARecordType metaRecType = (ARecordType) metaItemType;
                int numSecondaryKeys = KeyFieldTypeUtil.getNumSecondaryKeys(index, recType, metaRecType);
                List<String> fieldName;
                if (varIndex >= numSecondaryKeys) {
                    fieldName = dataset.getPrimaryKeys().get(varIndex - numSecondaryKeys);
                } else {
                    fieldName = index.getKeyFieldNames().get(varIndex);
                }
                if (fieldName == null) {
                    return false;
                }
                optFuncExpr.setFieldName(funcVarIndex, fieldName);
                return true;
            }
        }
        if (descendantOp.getInputs().isEmpty()) {
            break;
        }
        descendantOp = (AbstractLogicalOperator) descendantOp.getInputs().get(0).getValue();
    }
    return false;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) UnnestMapOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) Index(org.apache.asterix.metadata.entities.Index) 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) DataSourceScanOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator) MetadataProvider(org.apache.asterix.metadata.declared.MetadataProvider) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) ARecordType(org.apache.asterix.om.types.ARecordType) IAType(org.apache.asterix.om.types.IAType)

Example 62 with AbstractFunctionCallExpression

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

the class IntroduceLSMComponentFilterRule method getDataset.

private Dataset getDataset(AbstractLogicalOperator op, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator descendantOp = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
    while (descendantOp != null) {
        if (descendantOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
            DataSourceScanOperator dataSourceScanOp = (DataSourceScanOperator) descendantOp;
            DataSource ds = (DataSource) dataSourceScanOp.getDataSource();
            if (ds.getDatasourceType() != DataSource.Type.INTERNAL_DATASET) {
                return null;
            }
            return ((DatasetDataSource) ds).getDataset();
        } else if (descendantOp.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
            UnnestMapOperator unnestMapOp = (UnnestMapOperator) descendantOp;
            ILogicalExpression unnestExpr = unnestMapOp.getExpressionRef().getValue();
            if (unnestExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
                AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) unnestExpr;
                FunctionIdentifier fid = f.getFunctionIdentifier();
                String dataverseName;
                String datasetName;
                if (BuiltinFunctions.EXTERNAL_LOOKUP.equals(fid)) {
                    dataverseName = AccessMethodUtils.getStringConstant(f.getArguments().get(0));
                    datasetName = AccessMethodUtils.getStringConstant(f.getArguments().get(1));
                } else if (fid.equals(BuiltinFunctions.INDEX_SEARCH)) {
                    AccessMethodJobGenParams jobGenParams = new AccessMethodJobGenParams();
                    jobGenParams.readFromFuncArgs(f.getArguments());
                    dataverseName = jobGenParams.dataverseName;
                    datasetName = jobGenParams.datasetName;
                } else {
                    throw new AlgebricksException("Unexpected function for Unnest Map: " + fid);
                }
                return ((MetadataProvider) context.getMetadataProvider()).findDataset(dataverseName, datasetName);
            }
        }
        if (descendantOp.getInputs().isEmpty()) {
            break;
        }
        descendantOp = (AbstractLogicalOperator) descendantOp.getInputs().get(0).getValue();
    }
    return null;
}
Also used : FunctionIdentifier(org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) DataSourceScanOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator) UnnestMapOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) AlgebricksException(org.apache.hyracks.algebricks.common.exceptions.AlgebricksException) DatasetDataSource(org.apache.asterix.metadata.declared.DatasetDataSource) DataSource(org.apache.asterix.metadata.declared.DataSource) DatasetDataSource(org.apache.asterix.metadata.declared.DatasetDataSource)

Example 63 with AbstractFunctionCallExpression

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

the class OptimizableOperatorSubTree method initializeDataSource.

private boolean initializeDataSource(Mutable<ILogicalOperator> subTreeOpRef) {
    AbstractLogicalOperator subTreeOp = (AbstractLogicalOperator) subTreeOpRef.getValue();
    if (subTreeOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
        setDataSourceType(DataSourceType.DATASOURCE_SCAN);
        setDataSourceRef(subTreeOpRef);
        return true;
    } else if (subTreeOp.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
        setDataSourceType(DataSourceType.COLLECTION_SCAN);
        setDataSourceRef(subTreeOpRef);
        return true;
    } else if (subTreeOp.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
        // There can be multiple unnest-map or datasource-scan operators
        // if index-nested-loop-join has been applied by IntroduceJoinAccessMethodRule.
        // So, we need to traverse the whole path from the subTreeOp.
        boolean dataSourceFound = false;
        while (true) {
            if (subTreeOp.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
                UnnestMapOperator unnestMapOp = (UnnestMapOperator) subTreeOp;
                ILogicalExpression unnestExpr = unnestMapOp.getExpressionRef().getValue();
                if (unnestExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
                    AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) unnestExpr;
                    if (f.getFunctionIdentifier().equals(BuiltinFunctions.INDEX_SEARCH)) {
                        AccessMethodJobGenParams jobGenParams = new AccessMethodJobGenParams();
                        jobGenParams.readFromFuncArgs(f.getArguments());
                        if (jobGenParams.isPrimaryIndex()) {
                            if (getDataSourceRef() == null) {
                                setDataSourceRef(subTreeOpRef);
                                setDataSourceType(DataSourceType.PRIMARY_INDEX_LOOKUP);
                            } else {
                                // One datasource already exists. This is an additional datasource.
                                initializeIxJoinOuterAddtionalDataSourcesIfEmpty();
                                getIxJoinOuterAdditionalDataSourceTypes().add(DataSourceType.PRIMARY_INDEX_LOOKUP);
                                getIxJoinOuterAdditionalDataSourceRefs().add(subTreeOpRef);
                            }
                            dataSourceFound = true;
                        }
                    } else if (f.getFunctionIdentifier().equals(BuiltinFunctions.EXTERNAL_LOOKUP)) {
                        // External lookup case
                        if (getDataSourceRef() == null) {
                            setDataSourceRef(subTreeOpRef);
                            setDataSourceType(DataSourceType.EXTERNAL_SCAN);
                        } else {
                            // One datasource already exists. This is an additional datasource.
                            initializeIxJoinOuterAddtionalDataSourcesIfEmpty();
                            getIxJoinOuterAdditionalDataSourceTypes().add(DataSourceType.EXTERNAL_SCAN);
                            getIxJoinOuterAdditionalDataSourceRefs().add(subTreeOpRef);
                        }
                        dataSourceFound = true;
                    }
                }
            } else if (subTreeOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
                initializeIxJoinOuterAddtionalDataSourcesIfEmpty();
                getIxJoinOuterAdditionalDataSourceTypes().add(DataSourceType.DATASOURCE_SCAN);
                getIxJoinOuterAdditionalDataSourceRefs().add(subTreeOpRef);
                dataSourceFound = true;
            } else if (subTreeOp.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
                initializeIxJoinOuterAddtionalDataSourcesIfEmpty();
                getIxJoinOuterAdditionalDataSourceTypes().add(DataSourceType.COLLECTION_SCAN);
                getIxJoinOuterAdditionalDataSourceRefs().add(subTreeOpRef);
            }
            // Traverse the subtree while there are operators in the path.
            if (subTreeOp.hasInputs()) {
                subTreeOpRef = subTreeOp.getInputs().get(0);
                subTreeOp = (AbstractLogicalOperator) subTreeOpRef.getValue();
            } else {
                break;
            }
        }
        if (dataSourceFound) {
            return true;
        }
    }
    return false;
}
Also used : ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) UnnestMapOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator) AbstractUnnestMapOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestMapOperator) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)

Example 64 with AbstractFunctionCallExpression

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

the class InvertedIndexAccessMethod method analyzeGetItemFuncExpr.

public boolean analyzeGetItemFuncExpr(AbstractFunctionCallExpression funcExpr, List<AbstractLogicalOperator> assignsAndUnnests, AccessMethodAnalysisContext analysisCtx) throws AlgebricksException {
    if (funcExpr.getFunctionIdentifier() != BuiltinFunctions.GET_ITEM) {
        return false;
    }
    ILogicalExpression arg1 = funcExpr.getArguments().get(0).getValue();
    ILogicalExpression arg2 = funcExpr.getArguments().get(1).getValue();
    // The second arg is the item index to be accessed. It must be a constant.
    if (arg2.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
        return false;
    }
    // If it is a variable we must track its origin in the assigns to get the original function expr.
    if (arg1.getExpressionTag() != LogicalExpressionTag.VARIABLE && arg1.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return false;
    }
    AbstractFunctionCallExpression matchedFuncExpr = null;
    // The get-item arg is function call, directly check if it's optimizable.
    if (arg1.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
        matchedFuncExpr = (AbstractFunctionCallExpression) arg1;
    }
    // The get-item arg is a variable. Search the assigns and unnests for its origination function.
    int matchedAssignOrUnnestIndex = -1;
    if (arg1.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
        VariableReferenceExpression varRefExpr = (VariableReferenceExpression) arg1;
        // Try to find variable ref expr in all assigns.
        for (int i = 0; i < assignsAndUnnests.size(); i++) {
            AbstractLogicalOperator op = assignsAndUnnests.get(i);
            if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
                AssignOperator assign = (AssignOperator) op;
                List<LogicalVariable> assignVars = assign.getVariables();
                List<Mutable<ILogicalExpression>> assignExprs = assign.getExpressions();
                for (int j = 0; j < assignVars.size(); j++) {
                    LogicalVariable var = assignVars.get(j);
                    if (var != varRefExpr.getVariableReference()) {
                        continue;
                    }
                    // We've matched the variable in the first assign. Now analyze the originating function.
                    ILogicalExpression matchedExpr = assignExprs.get(j).getValue();
                    if (matchedExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
                        return false;
                    }
                    matchedFuncExpr = (AbstractFunctionCallExpression) matchedExpr;
                    break;
                }
            } else {
                UnnestOperator unnest = (UnnestOperator) op;
                LogicalVariable var = unnest.getVariable();
                if (var == varRefExpr.getVariableReference()) {
                    ILogicalExpression matchedExpr = unnest.getExpressionRef().getValue();
                    if (matchedExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
                        return false;
                    }
                    AbstractFunctionCallExpression unnestFuncExpr = (AbstractFunctionCallExpression) matchedExpr;
                    if (unnestFuncExpr.getFunctionIdentifier() != BuiltinFunctions.SCAN_COLLECTION) {
                        return false;
                    }
                    matchedFuncExpr = (AbstractFunctionCallExpression) unnestFuncExpr.getArguments().get(0).getValue();
                }
            }
            // We've already found a match.
            if (matchedFuncExpr != null) {
                matchedAssignOrUnnestIndex = i;
                break;
            }
        }
    }
    // Check that the matched function is optimizable by this access method.
    if (!secondLevelFuncIdents.contains(matchedFuncExpr.getFunctionIdentifier())) {
        return false;
    }
    boolean selectMatchFound = analyzeSelectSimilarityCheckFuncExprArgs(matchedFuncExpr, assignsAndUnnests, matchedAssignOrUnnestIndex, analysisCtx);
    boolean joinMatchFound = analyzeJoinSimilarityCheckFuncExprArgs(matchedFuncExpr, assignsAndUnnests, matchedAssignOrUnnestIndex, analysisCtx);
    if (selectMatchFound || joinMatchFound) {
        return true;
    }
    return false;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) Mutable(org.apache.commons.lang3.mutable.Mutable) UnnestOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator)

Example 65 with AbstractFunctionCallExpression

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

the class InvertedIndexAccessMethod method addFunctionSpecificArgs.

private void addFunctionSpecificArgs(IOptimizableFuncExpr optFuncExpr, InvertedIndexJobGenParams jobGenParams) {
    if (optFuncExpr.getFuncExpr().getFunctionIdentifier() == BuiltinFunctions.STRING_CONTAINS) {
        jobGenParams.setSearchModifierType(SearchModifierType.CONJUNCTIVE);
        jobGenParams.setSimilarityThreshold(new AsterixConstantValue(AMissing.MISSING));
        return;
    }
    if (optFuncExpr.getFuncExpr().getFunctionIdentifier() == BuiltinFunctions.SIMILARITY_JACCARD_CHECK) {
        jobGenParams.setSearchModifierType(SearchModifierType.JACCARD);
        // Add the similarity threshold which, by convention, is the last constant value.
        jobGenParams.setSimilarityThreshold(((ConstantExpression) optFuncExpr.getConstantExpr(optFuncExpr.getNumConstantExpr() - 1)).getValue());
        return;
    }
    if (optFuncExpr.getFuncExpr().getFunctionIdentifier() == BuiltinFunctions.EDIT_DISTANCE_CHECK || optFuncExpr.getFuncExpr().getFunctionIdentifier() == BuiltinFunctions.EDIT_DISTANCE_CONTAINS) {
        if (optFuncExpr.containsPartialField()) {
            jobGenParams.setSearchModifierType(SearchModifierType.CONJUNCTIVE_EDIT_DISTANCE);
        } else {
            jobGenParams.setSearchModifierType(SearchModifierType.EDIT_DISTANCE);
        }
        // Add the similarity threshold which, by convention, is the last constant value.
        jobGenParams.setSimilarityThreshold(((ConstantExpression) optFuncExpr.getConstantExpr(optFuncExpr.getNumConstantExpr() - 1)).getValue());
        return;
    }
    if (optFuncExpr.getFuncExpr().getFunctionIdentifier() == BuiltinFunctions.FULLTEXT_CONTAINS || optFuncExpr.getFuncExpr().getFunctionIdentifier() == BuiltinFunctions.FULLTEXT_CONTAINS_WO_OPTION) {
        // Let the job Gen pass the full-text search information.
        jobGenParams.setIsFullTextSearch(true);
        // We check the last argument of the given full-text search to see whether conjunctive or disjunctive
        // search parameter is given. This is the last argument of the function call expression.
        AbstractFunctionCallExpression funcExpr = optFuncExpr.getFuncExpr();
        jobGenParams.setSearchModifierType(getFullTextOption(funcExpr));
        jobGenParams.setSimilarityThreshold(new AsterixConstantValue(ANull.NULL));
    }
}
Also used : AsterixConstantValue(org.apache.asterix.om.constants.AsterixConstantValue) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)

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