use of com.facebook.presto.sql.tree.CreateFunction in project presto by prestodb.
the class TestSqlParser method testCreateFunction.
@Test
public void testCreateFunction() {
assertStatement("CREATE FUNCTION tan (x double)\n" + "RETURNS double\n" + "COMMENT 'tangent trigonometric function'\n" + "LANGUAGE SQL\n" + "DETERMINISTIC\n" + "RETURNS NULL ON NULL INPUT\n" + "RETURN sin(x) / cos(x)", new CreateFunction(QualifiedName.of("tan"), false, false, ImmutableList.of(new SqlParameterDeclaration(identifier("x"), "double")), "double", Optional.of("tangent trigonometric function"), new RoutineCharacteristics(SQL, DETERMINISTIC, RETURNS_NULL_ON_NULL_INPUT), new Return(new ArithmeticBinaryExpression(DIVIDE, new FunctionCall(QualifiedName.of("sin"), ImmutableList.of(identifier("x"))), new FunctionCall(QualifiedName.of("cos"), ImmutableList.of(identifier("x")))))));
CreateFunction createFunctionRand = new CreateFunction(QualifiedName.of("dev", "testing", "rand"), true, false, ImmutableList.of(), "double", Optional.empty(), new RoutineCharacteristics(SQL, NOT_DETERMINISTIC, CALLED_ON_NULL_INPUT), new Return(new FunctionCall(QualifiedName.of("rand"), ImmutableList.of())));
assertStatement("CREATE OR REPLACE FUNCTION dev.testing.rand ()\n" + "RETURNS double\n" + "LANGUAGE SQL\n" + "NOT DETERMINISTIC\n" + "CALLED ON NULL INPUT\n" + "RETURN rand()", createFunctionRand);
assertStatement("CREATE OR REPLACE FUNCTION dev.testing.rand ()\n" + "RETURNS double\n" + "RETURN rand()", createFunctionRand);
CreateFunction createTemporaryFunctionFoo = new CreateFunction(QualifiedName.of("foo"), false, true, ImmutableList.of(), "boolean", Optional.empty(), new RoutineCharacteristics(SQL, NOT_DETERMINISTIC, CALLED_ON_NULL_INPUT), new Return(new BooleanLiteral("true")));
assertStatement("CREATE TEMPORARY FUNCTION foo() \n" + "RETURNS boolean \n" + "RETURN true", createTemporaryFunctionFoo);
assertInvalidStatement("CREATE FUNCTION dev.testing.rand () RETURNS double LANGUAGE SQL LANGUAGE SQL RETURN rand()", "Duplicate language clause: SQL");
assertInvalidStatement("CREATE FUNCTION dev.testing.rand () RETURNS double DETERMINISTIC DETERMINISTIC RETURN rand()", "Duplicate determinism characteristics: DETERMINISTIC");
assertInvalidStatement("CREATE FUNCTION dev.testing.rand () RETURNS double CALLED ON NULL INPUT CALLED ON NULL INPUT RETURN rand()", "Duplicate null-call clause: CALLEDONNULLINPUT");
}
use of com.facebook.presto.sql.tree.CreateFunction in project presto by prestodb.
the class TestCreateFunctionTask method testCreateTemporaryFunction.
@Test
public void testCreateTemporaryFunction() {
SqlParser parser = new SqlParser();
String sqlString = "CREATE TEMPORARY FUNCTION foo() RETURNS int RETURN 1";
CreateFunction statement = (CreateFunction) parser.createStatement(sqlString, ParsingOptions.builder().build());
TransactionManager transactionManager = createTestTransactionManager();
QueryStateMachine stateMachine = createQueryStateMachine(sqlString, TEST_SESSION, false, transactionManager, executorService, metadataManager);
WarningCollector warningCollector = stateMachine.getWarningCollector();
CreateFunctionTask createFunctionTask = new CreateFunctionTask(parser);
createFunctionTask.execute(statement, transactionManager, metadataManager, new AllowAllAccessControl(), TEST_SESSION, emptyList(), warningCollector);
assertEquals(createFunctionTask.getAddedSessionFunctions().size(), 1);
}
use of com.facebook.presto.sql.tree.CreateFunction in project presto by prestodb.
the class TestCreateFunctionTask method testCreateTemporaryFunctionWithSameNameFails.
@Test(expectedExceptions = PrestoException.class, expectedExceptionsMessageRegExp = "Session function .* has already been defined")
public void testCreateTemporaryFunctionWithSameNameFails() {
SqlParser parser = new SqlParser();
String sqlString = "CREATE TEMPORARY FUNCTION foo() RETURNS int RETURN 1";
CreateFunction statement = (CreateFunction) parser.createStatement(sqlString, ParsingOptions.builder().build());
TransactionManager transactionManager = createTestTransactionManager();
QueryStateMachine stateMachine = createQueryStateMachine(sqlString, TEST_SESSION, false, transactionManager, executorService, metadataManager);
WarningCollector warningCollector = stateMachine.getWarningCollector();
CreateFunctionTask createFunctionTask = new CreateFunctionTask(parser);
createFunctionTask.execute(statement, transactionManager, metadataManager, new AllowAllAccessControl(), TEST_SESSION, emptyList(), warningCollector);
createFunctionTask.execute(statement, transactionManager, metadataManager, new AllowAllAccessControl(), TEST_SESSION, emptyList(), warningCollector);
}
use of com.facebook.presto.sql.tree.CreateFunction 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());
}
Aggregations