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