throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
if (op.getOperatorTag() != LogicalOperatorTag.UNNEST) {
return false;
}
UnnestOperator unnest1 = (UnnestOperator) op;
AbstractLogicalOperator op2 = (AbstractLogicalOperator) unnest1.getInputs().get(0).getValue();
if (op2.getOperatorTag() != LogicalOperatorTag.UNNEST) {
return false;
}
UnnestOperator unnest2 = (UnnestOperator) op2;
if (!usedVariables.contains(unnest2.getVariable())) {
// Check to see if the unnest2 expression has a scalar implementation.
ILogicalExpression logicalExpression2 = (ILogicalExpression) unnest2.getExpressionRef().getValue();
if (logicalExpression2.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
return false;
}
AbstractFunctionCallExpression functionCall2 = (AbstractFunctionCallExpression) logicalExpression2;
Function functionInfo2 = (Function) functionCall2.getFunctionInfo();
if (!functionInfo2.hasScalarEvaluatorFactory()) {
return false;
}
// Find unnest2 variable in unnest1
Mutable<ILogicalExpression> unnest1Arg = ExpressionToolbox.findVariableExpression(
unnest1.getExpressionRef(), unnest2.getVariable());
if (unnest1Arg == null) {
return false;
}
// Replace unnest2 expression in unnest1
ScalarFunctionCallExpression child = new ScalarFunctionCallExpression(functionInfo2,
functionCall2.getArguments());
unnest1Arg.setValue(child);
// Move input for unnest2 into unnest1
unnest1.getInputs().clear();
unnest1.getInputs().addAll(unnest2.getInputs());
return true;
}
return false;
}