use of com.facebook.presto.spi.function.SqlInvokedFunction in project presto by prestodb.
the class TestSqlInvokedFunctionNamespaceManager method testCaching.
@Test
public void testCaching() {
InMemoryFunctionNamespaceManager functionNamespaceManager = createFunctionNamespaceManager();
functionNamespaceManager.createFunction(FUNCTION_POWER_TOWER_DOUBLE, false);
// fetchFunctionsDirect does not produce the same function reference
SqlInvokedFunction function1 = getOnlyElement(functionNamespaceManager.fetchFunctionsDirect(POWER_TOWER));
SqlInvokedFunction function2 = getOnlyElement(functionNamespaceManager.fetchFunctionsDirect(POWER_TOWER));
assertEquals(function1, function2);
assertNotSame(function1, function2);
// fetchFunctionMetadataDirect does not produce the same metadata reference
FunctionMetadata metadata1 = functionNamespaceManager.fetchFunctionMetadataDirect(function1.getRequiredFunctionHandle());
FunctionMetadata metadata2 = functionNamespaceManager.fetchFunctionMetadataDirect(function2.getRequiredFunctionHandle());
assertEquals(metadata1, metadata2);
assertNotSame(metadata1, metadata2);
// getFunctionMetadata produces the same metadata reference
metadata1 = functionNamespaceManager.getFunctionMetadata(function1.getRequiredFunctionHandle());
metadata2 = functionNamespaceManager.getFunctionMetadata(function2.getRequiredFunctionHandle());
assertSame(metadata1, metadata2);
// getFunctions produces the same function collection reference
functionNamespaceManager.createFunction(FUNCTION_POWER_TOWER_INT, false);
FunctionNamespaceTransactionHandle transaction1 = functionNamespaceManager.beginTransaction();
FunctionNamespaceTransactionHandle transaction2 = functionNamespaceManager.beginTransaction();
Collection<SqlInvokedFunction> functions1 = functionNamespaceManager.getFunctions(Optional.of(transaction1), POWER_TOWER);
Collection<SqlInvokedFunction> functions2 = functionNamespaceManager.getFunctions(Optional.of(transaction2), POWER_TOWER);
assertEquals(functions1.size(), 2);
assertSame(functions1, functions2);
}
use of com.facebook.presto.spi.function.SqlInvokedFunction in project presto by prestodb.
the class InMemoryFunctionNamespaceManager method createFunction.
@Override
public synchronized void createFunction(SqlInvokedFunction function, boolean replace) {
checkFunctionLanguageSupported(function);
SqlFunctionId functionId = function.getFunctionId();
if (!replace && latestFunctions.containsKey(function.getFunctionId())) {
throw new PrestoException(GENERIC_USER_ERROR, format("Function '%s' already exists", functionId.getId()));
}
SqlInvokedFunction replacedFunction = latestFunctions.get(functionId);
long version = 1;
if (replacedFunction != null) {
version = parseLong(replacedFunction.getRequiredVersion()) + 1;
}
latestFunctions.put(functionId, function.withVersion(String.valueOf(version)));
}
use of com.facebook.presto.spi.function.SqlInvokedFunction in project presto by prestodb.
the class SqlInvokedFunctionRowMapper method map.
@Override
public SqlInvokedFunction map(ResultSet rs, StatementContext ctx) throws SQLException {
String catalog = rs.getString("catalog_name");
String schema = rs.getString("schema_name");
String functionName = rs.getString("function_name");
List<Parameter> parameters = PARAMETERS_CODEC.fromJson(rs.getString("parameters"));
String returnType = rs.getString("return_type");
String description = rs.getString("description");
RoutineCharacteristics routineCharacteristics = ROUTINE_CHARACTERISTICS_CODEC.fromJson(rs.getString("routine_characteristics"));
String body = rs.getString("body");
String version = String.valueOf(rs.getLong("version"));
return new SqlInvokedFunction(QualifiedObjectName.valueOf(catalog, schema, functionName), parameters, parseTypeSignature(returnType), description, routineCharacteristics, body, withVersion(version));
}
use of com.facebook.presto.spi.function.SqlInvokedFunction in project presto by prestodb.
the class SqlInvokedScalarFromAnnotationsParser method createSqlInvokedFunctions.
private static List<SqlInvokedFunction> createSqlInvokedFunctions(Method method, Optional<SqlInvokedScalarFunction> header, Optional<String> description) {
SqlInvokedScalarFunction functionHeader = header.orElse(method.getAnnotation(SqlInvokedScalarFunction.class));
String functionDescription = description.orElse(method.isAnnotationPresent(Description.class) ? method.getAnnotation(Description.class).value() : "");
TypeSignature returnType = parseTypeSignature(method.getAnnotation(SqlType.class).value());
// Parameter
checkCondition(!method.isAnnotationPresent(SqlParameter.class) || !method.isAnnotationPresent(SqlParameters.class), FUNCTION_IMPLEMENTATION_ERROR, "Function-defining method [%s] is annotated with both @SqlParameter and @SqlParameters", method);
List<Parameter> parameters;
if (method.isAnnotationPresent(SqlParameter.class)) {
parameters = ImmutableList.of(getParameterFromAnnotation(method.getAnnotation(SqlParameter.class)));
} else if (method.isAnnotationPresent(SqlParameters.class)) {
parameters = stream(method.getAnnotation(SqlParameters.class).value()).map(SqlInvokedScalarFromAnnotationsParser::getParameterFromAnnotation).collect(toImmutableList());
} else {
parameters = ImmutableList.of();
}
// Routine characteristics
RoutineCharacteristics routineCharacteristics = RoutineCharacteristics.builder().setLanguage(RoutineCharacteristics.Language.SQL).setDeterminism(functionHeader.deterministic() ? DETERMINISTIC : NOT_DETERMINISTIC).setNullCallClause(functionHeader.calledOnNullInput() ? CALLED_ON_NULL_INPUT : RETURNS_NULL_ON_NULL_INPUT).build();
String body;
try {
body = (String) method.invoke(null);
} catch (ReflectiveOperationException e) {
throw new PrestoException(FUNCTION_IMPLEMENTATION_ERROR, format("Failed to get function body for method [%s]", method), e);
}
return Stream.concat(Stream.of(functionHeader.value()), stream(functionHeader.alias())).map(name -> new SqlInvokedFunction(QualifiedObjectName.valueOf(DEFAULT_NAMESPACE, name), parameters, returnType, functionDescription, routineCharacteristics, body, notVersioned())).collect(toImmutableList());
}
use of com.facebook.presto.spi.function.SqlInvokedFunction in project presto by prestodb.
the class CreateFunctionTask method execute.
@Override
public ListenableFuture<?> execute(CreateFunction statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters, WarningCollector warningCollector) {
Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, warningCollector);
Analysis analysis = analyzer.analyze(statement);
if (analysis.getFunctionHandles().values().stream().anyMatch(SqlFunctionHandle.class::isInstance)) {
throw new PrestoException(NOT_SUPPORTED, "Invoking a dynamically registered function in SQL function body is not supported");
}
SqlInvokedFunction function = createSqlInvokedFunction(statement, metadata, analysis);
if (statement.isTemporary()) {
addSessionFunction(session, new SqlFunctionId(function.getSignature().getName(), function.getSignature().getArgumentTypes()), function);
} else {
metadata.getFunctionAndTypeManager().createFunction(function, statement.isReplace());
}
return immediateFuture(null);
}
Aggregations