use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class PushGroupByThroughProduct method push.
private void push(Mutable<ILogicalOperator> opRefGby, Mutable<ILogicalOperator> opRefJoin, int branch, List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorToPush, List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorNotToPush, IOptimizationContext context) throws AlgebricksException {
GroupByOperator gby = (GroupByOperator) opRefGby.getValue();
AbstractBinaryJoinOperator join = (AbstractBinaryJoinOperator) opRefJoin.getValue();
gby.getDecorList().clear();
gby.getDecorList().addAll(decorToPush);
for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : decorNotToPush) {
LogicalVariable v1 = p.first;
if (v1 != null) {
VariableReferenceExpression varRef = (VariableReferenceExpression) p.second.getValue();
LogicalVariable v2 = varRef.getVariableReference();
OperatorManipulationUtil.substituteVarRec(join, v2, v1, true, context);
}
}
Mutable<ILogicalOperator> branchRef = join.getInputs().get(branch);
ILogicalOperator opBranch = branchRef.getValue();
opRefJoin.setValue(opBranch);
branchRef.setValue(gby);
opRefGby.setValue(join);
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class InlineUnnestFunctionRule method findUsedVarOrigin.
private ILogicalExpression findUsedVarOrigin(LogicalVariable usedVar, AbstractLogicalOperator parentOp, AbstractLogicalOperator currentOp) throws AlgebricksException {
ILogicalExpression ret = null;
if (currentOp.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
List<LogicalVariable> producedVars = new ArrayList<LogicalVariable>();
VariableUtilities.getProducedVariables(currentOp, producedVars);
if (producedVars.contains(usedVar)) {
AssignOperator assignOp = (AssignOperator) currentOp;
int index = assignOp.getVariables().indexOf(usedVar);
ILogicalExpression returnedExpr = assignOp.getExpressions().get(index).getValue();
if (returnedExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) returnedExpr;
if (BuiltinFunctions.isBuiltinUnnestingFunction(funcExpr.getFunctionIdentifier())) {
// we only inline for unnest functions
removeUnecessaryAssign(parentOp, currentOp, assignOp, index);
ret = returnedExpr;
}
} else if (returnedExpr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
//recusively inline
VariableReferenceExpression varExpr = (VariableReferenceExpression) returnedExpr;
LogicalVariable var = varExpr.getVariableReference();
ILogicalExpression finalExpr = findUsedVarOrigin(var, currentOp, (AbstractLogicalOperator) currentOp.getInputs().get(0).getValue());
if (finalExpr != null) {
removeUnecessaryAssign(parentOp, currentOp, assignOp, index);
ret = finalExpr;
}
}
}
} else {
for (Mutable<ILogicalOperator> child : currentOp.getInputs()) {
ILogicalExpression expr = findUsedVarOrigin(usedVar, currentOp, (AbstractLogicalOperator) child.getValue());
if (expr != null) {
ret = expr;
}
}
}
return ret;
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class AccessMethodUtils method createExternalDataLookupUnnestMap.
public static UnnestMapOperator createExternalDataLookupUnnestMap(AbstractDataSourceOperator dataSourceOp, Dataset dataset, ARecordType recordType, ILogicalOperator inputOp, IOptimizationContext context, boolean retainInput, boolean retainNull) throws AlgebricksException {
List<LogicalVariable> primaryKeyVars = AccessMethodUtils.getPrimaryKeyVarsFromSecondaryUnnestMap(dataset, inputOp);
// add a sort on the RID fields before fetching external data.
OrderOperator order = new OrderOperator();
for (LogicalVariable pkVar : primaryKeyVars) {
Mutable<ILogicalExpression> vRef = new MutableObject<>(new VariableReferenceExpression(pkVar));
order.getOrderExpressions().add(new Pair<>(OrderOperator.ASC_ORDER, vRef));
}
// The secondary-index search feeds into the sort.
order.getInputs().add(new MutableObject<>(inputOp));
order.setExecutionMode(ExecutionMode.LOCAL);
context.computeAndSetTypeEnvironmentForOperator(order);
List<Mutable<ILogicalExpression>> externalLookupArgs = new ArrayList<>();
//Add dataverse to the arguments
AccessMethodUtils.addStringArg(dataset.getDataverseName(), externalLookupArgs);
//Add dataset to the arguments
AccessMethodUtils.addStringArg(dataset.getDatasetName(), externalLookupArgs);
//Add PK vars to the arguments
AccessMethodUtils.writeVarList(primaryKeyVars, externalLookupArgs);
// Variables and types coming out of the external access.
List<LogicalVariable> externalUnnestVars = new ArrayList<>();
List<Object> outputTypes = new ArrayList<>();
// Append output variables/types generated by the data scan (not forwarded from input).
externalUnnestVars.addAll(dataSourceOp.getVariables());
appendExternalRecTypes(dataset, recordType, outputTypes);
IFunctionInfo externalLookup = FunctionUtil.getFunctionInfo(BuiltinFunctions.EXTERNAL_LOOKUP);
AbstractFunctionCallExpression externalLookupFunc = new ScalarFunctionCallExpression(externalLookup, externalLookupArgs);
UnnestMapOperator unnestOp = new UnnestMapOperator(externalUnnestVars, new MutableObject<ILogicalExpression>(externalLookupFunc), outputTypes, retainInput);
// Fed by the order operator or the secondaryIndexUnnestOp.
unnestOp.getInputs().add(new MutableObject<ILogicalOperator>(order));
context.computeAndSetTypeEnvironmentForOperator(unnestOp);
unnestOp.setExecutionMode(ExecutionMode.PARTITIONED);
//set the physical operator
DataSourceId dataSourceId = new DataSourceId(dataset.getDataverseName(), dataset.getDatasetName());
unnestOp.setPhysicalOperator(new ExternalDataLookupPOperator(dataSourceId, dataset, recordType, primaryKeyVars, false, retainInput, retainNull));
return unnestOp;
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class AccessMethodUtils method resetLOJNullPlaceholderVariableInGroupByOp.
public static void resetLOJNullPlaceholderVariableInGroupByOp(AccessMethodAnalysisContext analysisCtx, LogicalVariable newNullPlaceholderVaraible, IOptimizationContext context) throws AlgebricksException {
//reset the null placeholder variable in groupby operator
ScalarFunctionCallExpression isNullFuncExpr = analysisCtx.getLOJIsNullFuncInGroupBy();
isNullFuncExpr.getArguments().clear();
isNullFuncExpr.getArguments().add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(newNullPlaceholderVaraible)));
//recompute type environment.
OperatorPropertiesUtil.typeOpRec(analysisCtx.getLOJGroupbyOpRef(), context);
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression in project asterixdb by apache.
the class AbstractIntroduceAccessMethodRule method getFieldNameFromSubTree.
/**
* Returns the field name corresponding to the assigned variable at
* varIndex. Returns null if the expr at varIndex does not yield to a field
* access function after following a set of allowed functions.
*
* @throws AlgebricksException
*/
protected List<String> getFieldNameFromSubTree(IOptimizableFuncExpr optFuncExpr, OptimizableOperatorSubTree subTree, int opIndex, int assignVarIndex, ARecordType recordType, int funcVarIndex, ILogicalExpression parentFuncExpr, LogicalVariable recordVar, ARecordType metaType, LogicalVariable metaVar) throws AlgebricksException {
// Get expression corresponding to opVar at varIndex.
AbstractLogicalExpression expr = null;
AbstractFunctionCallExpression childFuncExpr = null;
AbstractLogicalOperator op = subTree.getAssignsAndUnnests().get(opIndex);
if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
AssignOperator assignOp = (AssignOperator) op;
expr = (AbstractLogicalExpression) assignOp.getExpressions().get(assignVarIndex).getValue();
// Can't get a field name from a constant expression. So, return null.
if (expr.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
return Collections.emptyList();
}
childFuncExpr = (AbstractFunctionCallExpression) expr;
} else {
UnnestOperator unnestOp = (UnnestOperator) op;
expr = (AbstractLogicalExpression) unnestOp.getExpressionRef().getValue();
if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return Collections.emptyList();
}
childFuncExpr = (AbstractFunctionCallExpression) expr;
if (childFuncExpr.getFunctionIdentifier() != BuiltinFunctions.SCAN_COLLECTION) {
return Collections.emptyList();
}
expr = (AbstractLogicalExpression) childFuncExpr.getArguments().get(0).getValue();
}
if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return Collections.emptyList();
}
AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
FunctionIdentifier funcIdent = funcExpr.getFunctionIdentifier();
boolean isByName = false;
boolean isFieldAccess = false;
String fieldName = null;
List<String> nestedAccessFieldName = null;
int fieldIndex = -1;
if (funcIdent == BuiltinFunctions.FIELD_ACCESS_BY_NAME) {
fieldName = ConstantExpressionUtil.getStringArgument(funcExpr, 1);
if (fieldName == null) {
return Collections.emptyList();
}
isFieldAccess = true;
isByName = true;
} else if (funcIdent == BuiltinFunctions.FIELD_ACCESS_BY_INDEX) {
Integer idx = ConstantExpressionUtil.getIntArgument(funcExpr, 1);
if (idx == null) {
return Collections.emptyList();
}
fieldIndex = idx;
isFieldAccess = true;
} else if (funcIdent == BuiltinFunctions.FIELD_ACCESS_NESTED) {
ILogicalExpression nameArg = funcExpr.getArguments().get(1).getValue();
if (nameArg.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
return Collections.emptyList();
}
ConstantExpression constExpr = (ConstantExpression) nameArg;
AOrderedList orderedNestedFieldName = (AOrderedList) ((AsterixConstantValue) constExpr.getValue()).getObject();
nestedAccessFieldName = new ArrayList<>();
for (int i = 0; i < orderedNestedFieldName.size(); i++) {
nestedAccessFieldName.add(((AString) orderedNestedFieldName.getItem(i)).getStringValue());
}
isFieldAccess = true;
isByName = true;
}
if (isFieldAccess) {
LogicalVariable sourceVar = ((VariableReferenceExpression) funcExpr.getArguments().get(0).getValue()).getVariableReference();
optFuncExpr.setLogicalExpr(funcVarIndex, parentFuncExpr);
int[] assignAndExpressionIndexes = null;
//go forward through nested assigns until you find the relevant one
for (int i = opIndex + 1; i < subTree.getAssignsAndUnnests().size(); i++) {
AbstractLogicalOperator subOp = subTree.getAssignsAndUnnests().get(i);
List<LogicalVariable> varList;
if (subOp.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
//Nested was an assign
varList = ((AssignOperator) subOp).getVariables();
} else if (subOp.getOperatorTag() == LogicalOperatorTag.UNNEST) {
//Nested is not an assign
varList = ((UnnestOperator) subOp).getVariables();
} else {
break;
}
//Go through variables in assign to check for match
for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
LogicalVariable var = varList.get(varIndex);
ArrayList<LogicalVariable> parentVars = new ArrayList<>();
expr.getUsedVariables(parentVars);
if (parentVars.contains(var)) {
//Found the variable we are looking for.
//return assign and index of expression
int[] returnValues = { i, varIndex };
assignAndExpressionIndexes = returnValues;
}
}
}
if (assignAndExpressionIndexes != null && assignAndExpressionIndexes[0] > -1) {
//We found the nested assign
//Recursive call on nested assign
List<String> parentFieldNames = getFieldNameFromSubTree(optFuncExpr, subTree, assignAndExpressionIndexes[0], assignAndExpressionIndexes[1], recordType, funcVarIndex, parentFuncExpr, recordVar, metaType, metaVar);
if (parentFieldNames.isEmpty()) {
//We will not use index
return Collections.emptyList();
}
if (!isByName) {
fieldName = sourceVar.equals(metaVar) ? ((ARecordType) metaType.getSubFieldType(parentFieldNames)).getFieldNames()[fieldIndex] : ((ARecordType) recordType.getSubFieldType(parentFieldNames)).getFieldNames()[fieldIndex];
}
optFuncExpr.setSourceVar(funcVarIndex, ((AssignOperator) op).getVariables().get(assignVarIndex));
//add fieldName to the nested fieldName, return
if (nestedAccessFieldName != null) {
for (int i = 0; i < nestedAccessFieldName.size(); i++) {
parentFieldNames.add(nestedAccessFieldName.get(i));
}
} else {
parentFieldNames.add(fieldName);
}
return (parentFieldNames);
}
optFuncExpr.setSourceVar(funcVarIndex, ((AssignOperator) op).getVariables().get(assignVarIndex));
//no nested assign, we are at the lowest level.
if (isByName) {
if (nestedAccessFieldName != null) {
return nestedAccessFieldName;
}
return new ArrayList<>(Arrays.asList(fieldName));
}
return new ArrayList<>(Arrays.asList(sourceVar.equals(metaVar) ? metaType.getFieldNames()[fieldIndex] : recordType.getFieldNames()[fieldIndex]));
}
if (!funcIDSetThatRetainFieldName.contains(funcIdent)) {
return Collections.emptyList();
}
// We use a part of the field in edit distance computation
if (optFuncExpr.getFuncExpr().getFunctionIdentifier() == BuiltinFunctions.EDIT_DISTANCE_CHECK) {
optFuncExpr.setPartialField(true);
}
// We expect the function's argument to be a variable, otherwise we
// cannot apply an index.
ILogicalExpression argExpr = funcExpr.getArguments().get(0).getValue();
if (argExpr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
return Collections.emptyList();
}
LogicalVariable curVar = ((VariableReferenceExpression) argExpr).getVariableReference();
// the current operator
for (int assignOrUnnestIndex = opIndex + 1; assignOrUnnestIndex < subTree.getAssignsAndUnnests().size(); assignOrUnnestIndex++) {
AbstractLogicalOperator curOp = subTree.getAssignsAndUnnests().get(assignOrUnnestIndex);
if (curOp.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
AssignOperator assignOp = (AssignOperator) curOp;
List<LogicalVariable> varList = assignOp.getVariables();
for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
LogicalVariable var = varList.get(varIndex);
if (var.equals(curVar)) {
optFuncExpr.setSourceVar(funcVarIndex, var);
return getFieldNameFromSubTree(optFuncExpr, subTree, assignOrUnnestIndex, varIndex, recordType, funcVarIndex, childFuncExpr, recordVar, metaType, metaVar);
}
}
} else {
UnnestOperator unnestOp = (UnnestOperator) curOp;
LogicalVariable var = unnestOp.getVariable();
if (var.equals(curVar)) {
getFieldNameFromSubTree(optFuncExpr, subTree, assignOrUnnestIndex, 0, recordType, funcVarIndex, childFuncExpr, recordVar, metaType, metaVar);
}
}
}
return Collections.emptyList();
}
Aggregations