use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression 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.AbstractFunctionCallExpression in project asterixdb by apache.
the class ResolveVariableRule method cleanupScanCollectionForDataset.
// Cleans up scan collections on top of a "dataset" function call since "dataset"
// is an unnest function.
private void cleanupScanCollectionForDataset(AbstractFunctionCallExpression funcExpr) {
if (funcExpr.getFunctionIdentifier() != BuiltinFunctions.SCAN_COLLECTION) {
return;
}
ILogicalExpression arg = funcExpr.getArguments().get(0).getValue();
if (arg.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return;
}
AbstractFunctionCallExpression argFuncExpr = (AbstractFunctionCallExpression) arg;
if (argFuncExpr.getFunctionIdentifier() != BuiltinFunctions.DATASET) {
return;
}
funcExpr.setFunctionInfo(argFuncExpr.getFunctionInfo());
funcExpr.getArguments().clear();
funcExpr.getArguments().addAll(argFuncExpr.getArguments());
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression in project asterixdb by apache.
the class RemoveLeftOuterUnnestForLeftOuterJoinRule method checkSelect.
// Checks the expression for the nested select operator inside the group-by operator.
private Pair<Boolean, ILogicalExpression> checkSelect(SelectOperator select) {
ILogicalExpression condition = select.getCondition().getValue();
if (condition.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return new Pair<>(false, null);
}
AbstractFunctionCallExpression conditionFunc = (AbstractFunctionCallExpression) condition;
if (!conditionFunc.getFunctionIdentifier().equals(BuiltinFunctions.NOT)) {
return new Pair<>(false, null);
}
condition = conditionFunc.getArguments().get(0).getValue();
if (condition.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return new Pair<>(false, null);
}
conditionFunc = (AbstractFunctionCallExpression) condition;
if (!conditionFunc.getFunctionIdentifier().equals(BuiltinFunctions.IS_MISSING)) {
return new Pair<>(false, null);
}
ILogicalExpression conditionArg = conditionFunc.getArguments().get(0).getValue();
return new Pair<>(true, conditionArg);
}
use of org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression 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.AbstractFunctionCallExpression in project asterixdb by apache.
the class OpenRecordConstructorResultType method computeType.
@Override
public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression;
/**
* if type has been top-down propagated, use the enforced type
*/
ARecordType type = (ARecordType) TypeCastUtils.getRequiredType(f);
if (type != null) {
return type;
}
Iterator<Mutable<ILogicalExpression>> argIter = f.getArguments().iterator();
List<String> namesList = new ArrayList<>();
List<IAType> typesList = new ArrayList<>();
// The following set of names do not belong to the closed part,
// but are additional possible field names. For example, a field "foo" with type
// ANY cannot be in the closed part, but "foo" is a possible field name.
Set<String> allPossibleAdditionalFieldNames = new HashSet<>();
boolean canProvideAdditionFieldInfo = true;
boolean isOpen = false;
while (argIter.hasNext()) {
ILogicalExpression e1 = argIter.next().getValue();
ILogicalExpression e2 = argIter.next().getValue();
IAType t2 = (IAType) env.getType(e2);
String fieldName = ConstantExpressionUtil.getStringConstant(e1);
if (fieldName != null && t2 != null && TypeHelper.isClosed(t2)) {
namesList.add(fieldName);
if (t2.getTypeTag() == ATypeTag.UNION) {
AUnionType unionType = (AUnionType) t2;
t2 = AUnionType.createUnknownableType(unionType.getActualType());
}
typesList.add(t2);
} else {
if (canProvideAdditionFieldInfo && fieldName != null) {
allPossibleAdditionalFieldNames.add(fieldName);
} else {
canProvideAdditionFieldInfo = false;
}
isOpen = true;
}
}
String[] fieldNames = namesList.toArray(new String[0]);
IAType[] fieldTypes = typesList.toArray(new IAType[0]);
return canProvideAdditionFieldInfo ? new ARecordType(null, fieldNames, fieldTypes, isOpen, allPossibleAdditionalFieldNames) : new ARecordType(null, fieldNames, fieldTypes, isOpen);
}
Aggregations