use of com.facebook.presto.sql.tree.ExpressionTreeRewriter in project presto by prestodb.
the class CreateFunctionTask method createSqlInvokedFunction.
private SqlInvokedFunction createSqlInvokedFunction(CreateFunction statement, Metadata metadata, Analysis analysis) {
QualifiedObjectName functionName = statement.isTemporary() ? QualifiedObjectName.valueOf(SESSION_NAMESPACE, statement.getFunctionName().getSuffix()) : qualifyObjectName(statement.getFunctionName());
List<Parameter> parameters = statement.getParameters().stream().map(parameter -> new Parameter(parameter.getName().toString(), parseTypeSignature(parameter.getType()))).collect(toImmutableList());
TypeSignature returnType = parseTypeSignature(statement.getReturnType());
String description = statement.getComment().orElse("");
RoutineCharacteristics routineCharacteristics = RoutineCharacteristics.builder().setLanguage(new RoutineCharacteristics.Language(statement.getCharacteristics().getLanguage().getLanguage())).setDeterminism(RoutineCharacteristics.Determinism.valueOf(statement.getCharacteristics().getDeterminism().name())).setNullCallClause(RoutineCharacteristics.NullCallClause.valueOf(statement.getCharacteristics().getNullCallClause().name())).build();
RoutineBody body = statement.getBody();
if (statement.getBody() instanceof Return) {
Expression bodyExpression = ((Return) statement.getBody()).getExpression();
Type bodyType = analysis.getType(bodyExpression);
// Coerce expressions in body if necessary
bodyExpression = ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<Void>() {
@Override
public Expression rewriteExpression(Expression expression, Void context, ExpressionTreeRewriter<Void> treeRewriter) {
Expression rewritten = treeRewriter.defaultRewrite(expression, null);
Type coercion = analysis.getCoercion(expression);
if (coercion != null) {
return new Cast(rewritten, coercion.getTypeSignature().toString(), false, analysis.isTypeOnlyCoercion(expression));
}
return rewritten;
}
}, bodyExpression, null);
if (!bodyType.equals(metadata.getType(returnType))) {
// Casting is safe here, since we have verified at analysis time that the actual type of the body is coercible to declared return type.
bodyExpression = new Cast(bodyExpression, statement.getReturnType());
}
body = new Return(bodyExpression);
}
return new SqlInvokedFunction(functionName, parameters, returnType, description, routineCharacteristics, formatSql(body, Optional.empty()), notVersioned());
}
use of com.facebook.presto.sql.tree.ExpressionTreeRewriter in project presto by prestodb.
the class SqlFunctionUtils method rewriteLambdaExpression.
private static Expression rewriteLambdaExpression(Expression sqlFunction, Map<String, VariableReferenceExpression> arguments, ExpressionAnalysis functionAnalysis, PlanVariableAllocator variableAllocator) {
Map<NodeRef<Identifier>, LambdaArgumentDeclaration> lambdaArgumentReferences = functionAnalysis.getLambdaArgumentReferences();
Map<NodeRef<Expression>, Type> expressionTypes = functionAnalysis.getExpressionTypes();
// Rewrite reference to LambdaArgumentDeclaration
Map<NodeRef<LambdaArgumentDeclaration>, VariableReferenceExpression> variables = expressionTypes.entrySet().stream().filter(entry -> entry.getKey().getNode() instanceof LambdaArgumentDeclaration).distinct().collect(toImmutableMap(entry -> NodeRef.of((LambdaArgumentDeclaration) entry.getKey().getNode()), entry -> variableAllocator.newVariable(((LambdaArgumentDeclaration) entry.getKey().getNode()).getName(), entry.getValue(), "lambda")));
Expression rewritten = ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<Map<NodeRef<Identifier>, LambdaArgumentDeclaration>>() {
@Override
public Expression rewriteLambdaExpression(LambdaExpression node, Map<NodeRef<Identifier>, LambdaArgumentDeclaration> context, ExpressionTreeRewriter<Map<NodeRef<Identifier>, LambdaArgumentDeclaration>> treeRewriter) {
return new LambdaExpression(node.getArguments().stream().map(argument -> new LambdaArgumentDeclaration(new Identifier(variables.get(NodeRef.of(argument)).getName()))).collect(toImmutableList()), treeRewriter.rewrite(node.getBody(), context));
}
@Override
public Expression rewriteIdentifier(Identifier node, Map<NodeRef<Identifier>, LambdaArgumentDeclaration> context, ExpressionTreeRewriter<Map<NodeRef<Identifier>, LambdaArgumentDeclaration>> treeRewriter) {
NodeRef<Identifier> ref = NodeRef.of(node);
if (context.containsKey(ref)) {
return createSymbolReference(variables.get(NodeRef.of(context.get(ref))));
}
return node;
}
}, sqlFunction, lambdaArgumentReferences);
// Rewrite function input referenced in lambda
rewritten = ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<Map<String, VariableReferenceExpression>>() {
@Override
public Expression rewriteIdentifier(Identifier node, Map<String, VariableReferenceExpression> context, ExpressionTreeRewriter<Map<String, VariableReferenceExpression>> treeRewriter) {
if (context.containsKey(node.getValue())) {
return createSymbolReference(context.get(node.getValue()));
}
return node;
}
}, rewritten, arguments);
// Desugar lambda capture
return LambdaCaptureDesugaringRewriter.rewrite(rewritten, variableAllocator);
}
Aggregations