use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class AccessMethodUtils method createSearchKeyExpr.
/**
* Returns the search key expression which feeds a secondary-index search. If we are optimizing a selection query then this method returns
* the a ConstantExpression from the first constant value in the optimizable function expression.
* If we are optimizing a join, then this method returns the VariableReferenceExpression that should feed the secondary index probe.
*
* @throws AlgebricksException
*/
public static Pair<ILogicalExpression, Boolean> createSearchKeyExpr(IOptimizableFuncExpr optFuncExpr, OptimizableOperatorSubTree indexSubTree, OptimizableOperatorSubTree probeSubTree) throws AlgebricksException {
if (probeSubTree == null) {
// We are optimizing a selection query. Search key is a constant.
// Type Checking and type promotion is done here
IAType fieldType = optFuncExpr.getFieldType(0);
if (optFuncExpr.getNumConstantExpr() == 0) {
//TODO: Right now we miss on type promotion for nonpure functions
return new Pair<>(new VariableReferenceExpression(optFuncExpr.getLogicalVar(1)), false);
}
ILogicalExpression constantAtRuntimeExpression = null;
AsterixConstantValue constantValue = null;
ATypeTag constantValueTag = null;
constantAtRuntimeExpression = optFuncExpr.getConstantExpr(0);
if (constantAtRuntimeExpression.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
constantValue = (AsterixConstantValue) ((ConstantExpression) constantAtRuntimeExpression).getValue();
}
constantValueTag = optFuncExpr.getConstantType(0).getTypeTag();
// type casting applied?
boolean typeCastingApplied = false;
// type casting happened from real (FLOAT, DOUBLE) value -> INT value?
boolean realTypeConvertedToIntegerType = false;
AsterixConstantValue replacedConstantValue = null;
// if the constant type and target type does not match, we do a type conversion
if (constantValueTag != fieldType.getTypeTag() && constantValue != null) {
try {
replacedConstantValue = ATypeHierarchy.getAsterixConstantValueFromNumericTypeObject(constantValue.getObject(), fieldType.getTypeTag(), true);
} catch (HyracksDataException e) {
throw new AlgebricksException(e);
}
if (replacedConstantValue != null) {
typeCastingApplied = true;
}
// In this case, we need to change the search parameter. Refer to the caller section for the detail.
switch(constantValueTag) {
case DOUBLE:
case FLOAT:
switch(fieldType.getTypeTag()) {
case TINYINT:
case SMALLINT:
case INTEGER:
case BIGINT:
realTypeConvertedToIntegerType = true;
break;
default:
break;
}
default:
break;
}
}
if (typeCastingApplied) {
return new Pair<>(new ConstantExpression(replacedConstantValue), realTypeConvertedToIntegerType);
} else {
return new Pair<>(optFuncExpr.getConstantExpr(0), false);
}
} else {
// We are optimizing a join query. Determine which variable feeds the secondary index.
if (optFuncExpr.getOperatorSubTree(0) == null || optFuncExpr.getOperatorSubTree(0) == probeSubTree) {
return new Pair<>(new VariableReferenceExpression(optFuncExpr.getLogicalVar(0)), false);
} else {
return new Pair<>(new VariableReferenceExpression(optFuncExpr.getLogicalVar(1)), false);
}
}
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class AccessMethodUtils method analyzeFuncExprArgsForOneConstAndVarAndUpdateAnalysisCtx.
public static boolean analyzeFuncExprArgsForOneConstAndVarAndUpdateAnalysisCtx(AbstractFunctionCallExpression funcExpr, AccessMethodAnalysisContext analysisCtx, IOptimizationContext context, IVariableTypeEnvironment typeEnvironment) throws AlgebricksException {
ILogicalExpression constExpression = null;
IAType constantExpressionType = null;
LogicalVariable fieldVar = null;
ILogicalExpression arg1 = funcExpr.getArguments().get(0).getValue();
ILogicalExpression arg2 = funcExpr.getArguments().get(1).getValue();
// One of the args must be a runtime constant, and the other arg must be a variable.
if (arg1.getExpressionTag() == LogicalExpressionTag.VARIABLE && arg2.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
return false;
}
if (arg2.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
// The arguments of contains() function are asymmetrical, we can only use index if it is on the first argument
if (funcExpr.getFunctionIdentifier() == BuiltinFunctions.STRING_CONTAINS || funcExpr.getFunctionIdentifier() == BuiltinFunctions.FULLTEXT_CONTAINS || funcExpr.getFunctionIdentifier() == BuiltinFunctions.FULLTEXT_CONTAINS_WO_OPTION) {
return false;
}
IAType expressionType = constantRuntimeResultType(arg1, context, typeEnvironment);
if (expressionType == null) {
//Not constant at runtime
return false;
}
constantExpressionType = expressionType;
constExpression = arg1;
VariableReferenceExpression varExpr = (VariableReferenceExpression) arg2;
fieldVar = varExpr.getVariableReference();
} else if (arg1.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
IAType expressionType = constantRuntimeResultType(arg2, context, typeEnvironment);
if (expressionType == null) {
//Not constant at runtime
return false;
}
constantExpressionType = expressionType;
constExpression = arg2;
// yet in the full-text search.
if (funcExpr.getFunctionIdentifier() == BuiltinFunctions.FULLTEXT_CONTAINS && arg2.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
checkFTSearchConstantExpression(constExpression);
}
VariableReferenceExpression varExpr = (VariableReferenceExpression) arg1;
fieldVar = varExpr.getVariableReference();
} else {
return false;
}
// Updates the given Analysis Context by adding a new optimizable function expression.
constructNewOptFuncExprAndAddToAnalysisCtx(funcExpr, fieldVar, constExpression, constantExpressionType, analysisCtx);
return true;
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class AccessMethodUtils method writeVarList.
private static void writeVarList(List<LogicalVariable> varList, List<Mutable<ILogicalExpression>> funcArgs) {
Mutable<ILogicalExpression> numKeysRef = new MutableObject<>(new ConstantExpression(new AsterixConstantValue(new AInt32(varList.size()))));
funcArgs.add(numKeysRef);
for (LogicalVariable keyVar : varList) {
Mutable<ILogicalExpression> keyVarRef = new MutableObject<>(new VariableReferenceExpression(keyVar));
funcArgs.add(keyVarRef);
}
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class SetupCommitExtensionOpRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (op.getOperatorTag() != LogicalOperatorTag.DELEGATE_OPERATOR) {
return false;
}
DelegateOperator eOp = (DelegateOperator) op;
if (!(eOp.getDelegate() instanceof CommitOperator)) {
return false;
}
boolean isSink = ((CommitOperator) eOp.getDelegate()).isSink();
List<Mutable<ILogicalExpression>> primaryKeyExprs = null;
Dataset dataset = null;
AbstractLogicalOperator descendantOp = (AbstractLogicalOperator) eOp.getInputs().get(0).getValue();
while (descendantOp != null) {
if (descendantOp.getOperatorTag() == LogicalOperatorTag.INDEX_INSERT_DELETE_UPSERT) {
IndexInsertDeleteUpsertOperator operator = (IndexInsertDeleteUpsertOperator) descendantOp;
if (!operator.isBulkload() && operator.getPrevSecondaryKeyExprs() == null) {
primaryKeyExprs = operator.getPrimaryKeyExpressions();
dataset = ((DatasetDataSource) operator.getDataSourceIndex().getDataSource()).getDataset();
break;
}
} else if (descendantOp.getOperatorTag() == LogicalOperatorTag.INSERT_DELETE_UPSERT) {
InsertDeleteUpsertOperator insertDeleteUpsertOperator = (InsertDeleteUpsertOperator) descendantOp;
if (!insertDeleteUpsertOperator.isBulkload()) {
primaryKeyExprs = insertDeleteUpsertOperator.getPrimaryKeyExpressions();
dataset = ((DatasetDataSource) insertDeleteUpsertOperator.getDataSource()).getDataset();
break;
}
}
if (descendantOp.getInputs().isEmpty()) {
break;
}
descendantOp = (AbstractLogicalOperator) descendantOp.getInputs().get(0).getValue();
}
if (primaryKeyExprs == null) {
return false;
}
//copy primaryKeyExprs
List<LogicalVariable> primaryKeyLogicalVars = new ArrayList<>();
for (Mutable<ILogicalExpression> expr : primaryKeyExprs) {
VariableReferenceExpression varRefExpr = (VariableReferenceExpression) expr.getValue();
primaryKeyLogicalVars.add(new LogicalVariable(varRefExpr.getVariableReference().getId()));
}
//get JobId(TransactorId)
MetadataProvider mp = (MetadataProvider) context.getMetadataProvider();
JobId jobId = mp.getJobId();
//create the logical and physical operator
CommitOperator commitOperator = new CommitOperator(primaryKeyLogicalVars, isSink);
CommitPOperator commitPOperator = new CommitPOperator(jobId, dataset, primaryKeyLogicalVars, isSink);
commitOperator.setPhysicalOperator(commitPOperator);
//create ExtensionOperator and put the commitOperator in it.
DelegateOperator extensionOperator = new DelegateOperator(commitOperator);
extensionOperator.setPhysicalOperator(commitPOperator);
//update plan link
extensionOperator.getInputs().add(eOp.getInputs().get(0));
context.computeAndSetTypeEnvironmentForOperator(extensionOperator);
opRef.setValue(extensionOperator);
return true;
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class AbstractIntroduceAccessMethodRule method matchVarsFromOptFuncExprToDataSourceScan.
private void matchVarsFromOptFuncExprToDataSourceScan(IOptimizableFuncExpr optFuncExpr, int optFuncExprIndex, List<Index> datasetIndexes, List<LogicalVariable> dsVarList, OptimizableOperatorSubTree subTree, AccessMethodAnalysisContext analysisCtx, IOptimizationContext context, boolean fromAdditionalDataSource) throws AlgebricksException {
for (int varIndex = 0; varIndex < dsVarList.size(); varIndex++) {
LogicalVariable var = dsVarList.get(varIndex);
int funcVarIndex = optFuncExpr.findLogicalVar(var);
// No matching var in optFuncExpr.
if (funcVarIndex == -1) {
continue;
}
// The variable value is one of the partitioning fields.
List<String> fieldName = null;
IAType fieldType = null;
List<List<String>> subTreePKs = null;
if (!fromAdditionalDataSource) {
subTreePKs = subTree.getDataset().getPrimaryKeys();
// Check whether this variable is PK, not a record variable.
if (varIndex <= subTreePKs.size() - 1) {
fieldName = subTreePKs.get(varIndex);
fieldType = (IAType) context.getOutputTypeEnvironment(subTree.getDataSourceRef().getValue()).getVarType(var);
}
} else {
// Need to check additional dataset one by one
for (int i = 0; i < subTree.getIxJoinOuterAdditionalDatasets().size(); i++) {
if (subTree.getIxJoinOuterAdditionalDatasets().get(i) != null) {
subTreePKs = subTree.getIxJoinOuterAdditionalDatasets().get(i).getPrimaryKeys();
// Check whether this variable is PK, not a record variable.
if (subTreePKs.contains(var) && varIndex <= subTreePKs.size() - 1) {
fieldName = subTreePKs.get(varIndex);
fieldType = (IAType) context.getOutputTypeEnvironment(subTree.getIxJoinOuterAdditionalDataSourceRefs().get(i).getValue()).getVarType(var);
break;
}
}
}
}
// Set the fieldName in the corresponding matched function
// expression, and remember matching subtree.
optFuncExpr.setFieldName(funcVarIndex, fieldName);
optFuncExpr.setOptimizableSubTree(funcVarIndex, subTree);
optFuncExpr.setSourceVar(funcVarIndex, var);
optFuncExpr.setLogicalExpr(funcVarIndex, new VariableReferenceExpression(var));
setTypeTag(context, subTree, optFuncExpr, funcVarIndex);
if (subTree.hasDataSourceScan()) {
fillIndexExprs(datasetIndexes, fieldName, fieldType, optFuncExpr, optFuncExprIndex, funcVarIndex, subTree, analysisCtx);
}
}
}
Aggregations