private boolean findMatchedExprFieldName()

in asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java [511:658]


    private boolean findMatchedExprFieldName(IOptimizableFuncExpr optFuncExpr, AbstractLogicalOperator op,
            Dataset dataset, ARecordType filterSourceType, List<Index> datasetIndexes, IOptimizationContext context,
            Integer filterSourceIndicator) 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;
                    }
                    Pair<ARecordType, List<String>> fieldNamePairs =
                            getFieldNameFromSubAssignTree(optFuncExpr, descendantOp, varIndex, filterSourceType,
                                    filterSourceIndicator, dataset.getPrimaryKeys().size());
                    if (fieldNamePairs == null) {
                        return false;
                    }
                    List<String> fieldName = fieldNamePairs.second;
                    // Since we validated the filter source in getFieldNameFromSubAssignTree, we can safely set the
                    // fieldSource to be filterSourceIndicator
                    optFuncExpr.setFieldName(funcVarIndex, fieldName, filterSourceIndicator);
                    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;
                    }
                    List<Integer> keySourceIndicators = DatasetUtil.getKeySourceIndicators(dataset);
                    int keySource = getKeySource(keySourceIndicators, varIndex);
                    optFuncExpr.setFieldName(funcVarIndex, fieldName, keySource);
                    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 CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE,
                                    unnestMapOp.getSourceLocation(),
                                    "Illegal function found, expected an " + "index-search.");
                        }
                        AccessMethodJobGenParams jobGenParams = new AccessMethodJobGenParams();
                        jobGenParams.readFromFuncArgs(f.getArguments());
                        indexName = jobGenParams.indexName;
                        for (Index idx : datasetIndexes) {
                            if (idx.getIndexName().compareTo(indexName) == 0) {
                                index = idx;
                                break;
                            }
                        }
                    }
                    if (index == null) {
                        throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE,
                                unnestMapOp.getSourceLocation(),
                                "Could not find the corresponding index for an" + " index search.");
                    }

                    IAType metaItemType = ((MetadataProvider) context.getMetadataProvider()).findType(
                            dataset.getMetaItemTypeDatabaseName(), dataset.getMetaItemTypeDataverseName(),
                            dataset.getMetaItemTypeName());
                    IAType recordItemType = ((MetadataProvider) context.getMetadataProvider()).findType(
                            dataset.getItemTypeDatabaseName(), dataset.getItemTypeDataverseName(),
                            dataset.getItemTypeName());
                    ARecordType recordType = (ARecordType) recordItemType;
                    ARecordType metaRecType = (ARecordType) metaItemType;
                    int numSecondaryKeys = KeyFieldTypeUtil.getNumSecondaryKeys(index, recordType, metaRecType);
                    List<String> fieldName;
                    int keySource;
                    if (varIndex >= numSecondaryKeys) {
                        int idx = varIndex - numSecondaryKeys;
                        fieldName = dataset.getPrimaryKeys().get(idx);
                        keySource = getKeySource(DatasetUtil.getKeySourceIndicators(dataset), idx);
                    } else {
                        List<List<String>> keyFieldNames;
                        List<Integer> keySources;
                        switch (Index.IndexCategory.of(index.getIndexType())) {
                            case ARRAY:
                                Index.ArrayIndexDetails arrayIndexDetails =
                                        (Index.ArrayIndexDetails) index.getIndexDetails();
                                keyFieldNames = new ArrayList<>();
                                keySources = new ArrayList<>();
                                for (Index.ArrayIndexElement e : arrayIndexDetails.getElementList()) {
                                    for (List<String> project : e.getProjectList()) {
                                        keyFieldNames.add(
                                                ArrayIndexUtil.getFlattenedKeyFieldNames(e.getUnnestList(), project));
                                        keySources.add(e.getSourceIndicator());
                                    }
                                }
                                break;
                            case VALUE:
                                Index.ValueIndexDetails valueIndexDetails =
                                        (Index.ValueIndexDetails) index.getIndexDetails();
                                keyFieldNames = valueIndexDetails.getKeyFieldNames();
                                keySources = valueIndexDetails.getKeyFieldSourceIndicators();
                                break;
                            case TEXT:
                                Index.TextIndexDetails textIndexDetails =
                                        (Index.TextIndexDetails) index.getIndexDetails();
                                keyFieldNames = textIndexDetails.getKeyFieldNames();
                                keySources = textIndexDetails.getKeyFieldSourceIndicators();
                                break;
                            default:
                                throw new CompilationException(ErrorCode.COMPILATION_UNKNOWN_INDEX_TYPE,
                                        String.valueOf(index.getIndexType()));
                        }
                        fieldName = keyFieldNames.get(varIndex);
                        keySource = getKeySource(keySources, varIndex);
                    }
                    if (fieldName == null) {
                        return false;
                    }
                    optFuncExpr.setFieldName(funcVarIndex, fieldName, keySource);
                    return true;
                }
            }

            if (descendantOp.getInputs().isEmpty()) {
                break;
            }
            descendantOp = (AbstractLogicalOperator) descendantOp.getInputs().get(0).getValue();
        }
        return false;
    }