use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression in project asterixdb by apache.
the class RemoveRedundantListifyRule method applies.
private boolean applies(Mutable<ILogicalOperator> opRef, Set<LogicalVariable> varUsedAbove, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
if (op1.getOperatorTag() != LogicalOperatorTag.UNNEST) {
return false;
}
UnnestOperator unnest1 = (UnnestOperator) op1;
ILogicalExpression expr = unnest1.getExpressionRef().getValue();
if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
if (((AbstractFunctionCallExpression) expr).getFunctionIdentifier() != BuiltinFunctions.SCAN_COLLECTION) {
return false;
}
AbstractFunctionCallExpression functionCall = (AbstractFunctionCallExpression) expr;
ILogicalExpression functionCallArgExpr = functionCall.getArguments().get(0).getValue();
if (functionCallArgExpr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
return false;
}
LogicalVariable unnestedVar = ((VariableReferenceExpression) functionCallArgExpr).getVariableReference();
if (varUsedAbove.contains(unnestedVar)) {
return false;
}
Mutable<ILogicalOperator> aggregateParentRef = opRef;
AbstractLogicalOperator r = op1;
boolean metAggregate = false;
while (r.getInputs().size() == 1) {
aggregateParentRef = r.getInputs().get(0);
r = (AbstractLogicalOperator) aggregateParentRef.getValue();
if (r.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
AssignOperator assign = (AssignOperator) r;
List<LogicalVariable> variables = assign.getVariables();
// The assign operator doesn't produce any variable that is used by the unnest.
if (variables.contains(unnestedVar)) {
return false;
}
} else {
if (r.getOperatorTag() == LogicalOperatorTag.AGGREGATE) {
metAggregate = true;
}
break;
}
}
if (!metAggregate) {
return false;
}
AggregateOperator agg = (AggregateOperator) r;
if (agg.getVariables().size() > 1) {
return false;
}
LogicalVariable aggVar = agg.getVariables().get(0);
ILogicalExpression aggFun = agg.getExpressions().get(0).getValue();
if (!aggVar.equals(unnestedVar) || ((AbstractLogicalExpression) aggFun).getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) aggFun;
if (!BuiltinFunctions.LISTIFY.equals(f.getFunctionIdentifier())) {
return false;
}
if (f.getArguments().size() != 1) {
return false;
}
ILogicalExpression arg0 = f.getArguments().get(0).getValue();
if (((AbstractLogicalExpression) arg0).getExpressionTag() != LogicalExpressionTag.VARIABLE) {
return false;
}
LogicalVariable paramVar = ((VariableReferenceExpression) arg0).getVariableReference();
List<LogicalVariable> assgnVars = new ArrayList<>(1);
assgnVars.add(unnest1.getVariable());
List<Mutable<ILogicalExpression>> assgnExprs = new ArrayList<>(1);
assgnExprs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(paramVar)));
AssignOperator assign = new AssignOperator(assgnVars, assgnExprs);
assign.getInputs().add(agg.getInputs().get(0));
context.computeAndSetTypeEnvironmentForOperator(assign);
LogicalVariable posVar = unnest1.getPositionalVariable();
if (posVar == null) {
// Removes the aggregate operator.
aggregateParentRef.setValue(assign);
} else {
List<LogicalVariable> raggVars = new ArrayList<>(1);
raggVars.add(posVar);
List<Mutable<ILogicalExpression>> rAggExprs = new ArrayList<>(1);
StatefulFunctionCallExpression tidFun = new StatefulFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.TID), UnpartitionedPropertyComputer.INSTANCE);
rAggExprs.add(new MutableObject<ILogicalExpression>(tidFun));
RunningAggregateOperator rAgg = new RunningAggregateOperator(raggVars, rAggExprs);
rAgg.getInputs().add(new MutableObject<ILogicalOperator>(assign));
aggregateParentRef.setValue(rAgg);
context.computeAndSetTypeEnvironmentForOperator(rAgg);
}
// Removes the unnest operator.
opRef.setValue(unnest1.getInputs().get(0).getValue());
return true;
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression in project asterixdb by apache.
the class RecordRemoveFieldsTypeComputer method computeType.
@Override
public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expression;
String funcName = funcExpr.getFunctionIdentifier().getName();
IAType type0 = (IAType) env.getType(funcExpr.getArguments().get(0).getValue());
List<List<String>> pathList = new ArrayList<>();
Set<String> fieldNameSet = new HashSet<>();
Deque<String> fieldPathStack = new ArrayDeque<>();
ARecordType inputRecordType = getRecordTypeFromType(funcName, type0);
if (inputRecordType == null) {
return BuiltinType.ANY;
}
AbstractLogicalExpression arg1 = (AbstractLogicalExpression) funcExpr.getArguments().get(1).getValue();
IAType inputListType = (IAType) env.getType(arg1);
AOrderedListType inputOrderedListType = TypeComputeUtils.extractOrderedListType(inputListType);
if (inputOrderedListType == null) {
throw new TypeMismatchException(funcName, 1, inputListType.getTypeTag(), ATypeTag.ARRAY);
}
ATypeTag tt = inputOrderedListType.getItemType().getTypeTag();
if (tt == ATypeTag.STRING) {
// If top-fieldlist
if (setFieldNameSet(arg1, fieldNameSet)) {
return buildOutputType(fieldPathStack, inputRecordType, fieldNameSet, pathList);
} else {
return DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
}
} else {
// tt == ATypeTag.ANY, meaning the list is nested
computeTypeFromNonConstantExpression(funcName, arg1, fieldNameSet, pathList);
IAType resultType = buildOutputType(fieldPathStack, inputRecordType, fieldNameSet, pathList);
return resultType;
}
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression in project asterixdb by apache.
the class IntroduceLSMComponentFilterRule method getFieldNameFromSubAssignTree.
private Pair<ARecordType, List<String>> getFieldNameFromSubAssignTree(IOptimizableFuncExpr optFuncExpr, AbstractLogicalOperator op, int varIndex, ARecordType recType) {
AbstractLogicalExpression expr = null;
if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
AssignOperator assignOp = (AssignOperator) op;
expr = (AbstractLogicalExpression) assignOp.getExpressions().get(varIndex).getValue();
}
if (expr == null || expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return null;
}
AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
FunctionIdentifier funcIdent = funcExpr.getFunctionIdentifier();
if (funcIdent == BuiltinFunctions.FIELD_ACCESS_BY_NAME || funcIdent == BuiltinFunctions.FIELD_ACCESS_BY_INDEX) {
//get the variable from here. Figure out which input it came from. Go to that input!!!
ArrayList<LogicalVariable> usedVars = new ArrayList<>();
expr.getUsedVariables(usedVars);
LogicalVariable usedVar = usedVars.get(0);
List<String> returnList = new ArrayList<>();
//Find the input that it came from
for (int varCheck = 0; varCheck < op.getInputs().size(); varCheck++) {
AbstractLogicalOperator nestedOp = (AbstractLogicalOperator) op.getInputs().get(varCheck).getValue();
if (nestedOp.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
if (varCheck == op.getInputs().size() - 1) {
}
} else {
int nestedAssignVar = ((AssignOperator) nestedOp).getVariables().indexOf(usedVar);
if (nestedAssignVar == -1) {
continue;
}
//get the nested info from the lower input
Pair<ARecordType, List<String>> lowerInfo = getFieldNameFromSubAssignTree(optFuncExpr, (AbstractLogicalOperator) op.getInputs().get(varCheck).getValue(), nestedAssignVar, recType);
if (lowerInfo != null) {
recType = lowerInfo.first;
returnList = lowerInfo.second;
}
}
}
if (funcIdent == BuiltinFunctions.FIELD_ACCESS_BY_NAME) {
String fieldName = ConstantExpressionUtil.getStringArgument(funcExpr, 1);
if (fieldName == null) {
return null;
}
returnList.add(fieldName);
return new Pair<>(recType, returnList);
} else if (funcIdent == BuiltinFunctions.FIELD_ACCESS_BY_INDEX) {
Integer fieldIndex = ConstantExpressionUtil.getIntArgument(funcExpr, 1);
if (fieldIndex == null) {
return null;
}
returnList.add(recType.getFieldNames()[fieldIndex]);
IAType subType = recType.getFieldTypes()[fieldIndex];
if (subType.getTypeTag() == ATypeTag.OBJECT) {
recType = (ARecordType) subType;
}
return new Pair<>(recType, returnList);
}
}
ILogicalExpression argExpr = funcExpr.getArguments().get(0).getValue();
if (argExpr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
return null;
}
return null;
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression in project asterixdb by apache.
the class PushFunctionsBelowJoin method gatherFunctionCalls.
private void gatherFunctionCalls(Mutable<ILogicalExpression> exprRef, List<Mutable<ILogicalExpression>> funcExprs) {
AbstractLogicalExpression expr = (AbstractLogicalExpression) exprRef.getValue();
if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return;
}
// Check whether the function is a function we want to push.
AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
if (toPushFuncIdents.contains(funcExpr.getFunctionIdentifier())) {
funcExprs.add(exprRef);
}
// Traverse arguments.
for (Mutable<ILogicalExpression> funcArg : funcExpr.getArguments()) {
gatherFunctionCalls(funcArg, funcExprs);
}
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression in project asterixdb by apache.
the class LoadRecordFieldsRule method rewritePost.
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
if (context.checkIfInDontApplySet(this, op1)) {
return false;
}
if (op1.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
AssignOperator a1 = (AssignOperator) op1;
ILogicalExpression expr = getFirstExpr(a1);
if (AnalysisUtil.isAccessToFieldRecord(expr)) {
boolean res = findAndEliminateRedundantFieldAccess(a1, context);
context.addToDontApplySet(this, op1);
return res;
}
}
exprVisitor.setTopOp(op1);
exprVisitor.setContext(context);
boolean res = op1.acceptExpressionTransform(exprVisitor);
if (!res) {
context.addToDontApplySet(this, op1);
}
if (res && op1.getOperatorTag() == LogicalOperatorTag.SELECT) {
// checking if we can annotate a Selection as using just one field
// access
SelectOperator sigma = (SelectOperator) op1;
LinkedList<LogicalVariable> vars = new LinkedList<LogicalVariable>();
VariableUtilities.getUsedVariables(sigma, vars);
if (vars.size() == 1) {
// we can annotate Selection
AssignOperator assign1 = (AssignOperator) op1.getInputs().get(0).getValue();
AbstractLogicalExpression expr1 = (AbstractLogicalExpression) getFirstExpr(assign1);
if (expr1.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expr1;
// f should be a call to a field/data access kind of
// function
sigma.getAnnotations().put(OperatorAnnotation.FIELD_ACCESS, f.getArguments().get(0));
}
}
}
// TODO: avoid having to recompute type env. here
if (res) {
OperatorPropertiesUtil.typeOpRec(opRef, context);
}
return res;
}
Aggregations