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;
}