diff --git a/presto-expressions/src/main/java/com/facebook/presto/expressions/translator/TranslatorAnnotationParser.java b/presto-expressions/src/main/java/com/facebook/presto/expressions/translator/TranslatorAnnotationParser.java index f5f1aa0c60df1..05a0ce064de97 100644 --- a/presto-expressions/src/main/java/com/facebook/presto/expressions/translator/TranslatorAnnotationParser.java +++ b/presto-expressions/src/main/java/com/facebook/presto/expressions/translator/TranslatorAnnotationParser.java @@ -13,12 +13,13 @@ */ package com.facebook.presto.expressions.translator; +import com.facebook.presto.spi.CatalogSchemaName; import com.facebook.presto.spi.function.FunctionMetadata; import com.facebook.presto.spi.function.OperatorType; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.ScalarFunction; import com.facebook.presto.spi.function.ScalarOperator; import com.facebook.presto.spi.function.SqlType; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.TypeSignature; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -204,7 +205,7 @@ public Set getMethods() private static class ScalarTranslationHeader { - private final FullyQualifiedName name; + private final QualifiedFunctionName name; private final Optional operatorType; private final boolean deterministic; private final boolean calledOnNullInput; @@ -237,7 +238,7 @@ public static List fromAnnotatedElement(AnnotatedElemen private ScalarTranslationHeader(String name, boolean deterministic, boolean calledOnNullInput) { // TODO This is a hack. Engine should provide an API for connectors to overwrite functions. Connector should not hard code the builtin function namespace. - this.name = requireNonNull(FullyQualifiedName.of("presto", "default", name)); + this.name = requireNonNull(QualifiedFunctionName.of(new CatalogSchemaName("presto", "default"), name)); this.operatorType = Optional.empty(); this.deterministic = deterministic; this.calledOnNullInput = calledOnNullInput; @@ -268,7 +269,7 @@ private static String camelToSnake(String name) return LOWER_CAMEL.to(LOWER_UNDERSCORE, name); } - FullyQualifiedName getName() + QualifiedFunctionName getName() { return name; } diff --git a/presto-main/src/main/java/com/facebook/presto/execution/CreateFunctionTask.java b/presto-main/src/main/java/com/facebook/presto/execution/CreateFunctionTask.java new file mode 100644 index 0000000000000..b12ab47e55026 --- /dev/null +++ b/presto-main/src/main/java/com/facebook/presto/execution/CreateFunctionTask.java @@ -0,0 +1,104 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.facebook.presto.execution; + +import com.facebook.presto.metadata.Metadata; +import com.facebook.presto.security.AccessControl; +import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.function.QualifiedFunctionName; +import com.facebook.presto.spi.function.RoutineCharacteristics; +import com.facebook.presto.spi.function.SqlInvokedFunction; +import com.facebook.presto.spi.function.SqlParameter; +import com.facebook.presto.spi.type.TypeSignature; +import com.facebook.presto.sql.analyzer.Analyzer; +import com.facebook.presto.sql.parser.SqlParser; +import com.facebook.presto.sql.tree.CreateFunction; +import com.facebook.presto.sql.tree.Expression; +import com.facebook.presto.transaction.TransactionManager; +import com.google.common.util.concurrent.ListenableFuture; + +import javax.inject.Inject; + +import java.util.List; +import java.util.Optional; + +import static com.facebook.presto.spi.StandardErrorCode.GENERIC_USER_ERROR; +import static com.facebook.presto.spi.type.TypeSignature.parseTypeSignature; +import static com.facebook.presto.sql.SqlFormatter.formatSql; +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.util.concurrent.Futures.immediateFuture; +import static java.lang.String.format; +import static java.util.Locale.ENGLISH; +import static java.util.Objects.requireNonNull; + +public class CreateFunctionTask + implements DataDefinitionTask +{ + private final SqlParser sqlParser; + + @Inject + public CreateFunctionTask(SqlParser sqlParser) + { + this.sqlParser = requireNonNull(sqlParser, "sqlParser is null"); + } + + @Override + public String getName() + { + return "CREATE FUNCTION"; + } + + @Override + public String explain(CreateFunction statement, List parameters) + { + return "CREATE FUNCTION " + statement.getFunctionName(); + } + + @Override + public ListenableFuture execute(CreateFunction statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine stateMachine, List parameters) + { + Analyzer analyzer = new Analyzer(stateMachine.getSession(), metadata, sqlParser, accessControl, Optional.empty(), parameters, stateMachine.getWarningCollector()); + analyzer.analyze(statement); + metadata.getFunctionManager().createFunction(createSqlInvokedFunction(statement), statement.isReplace()); + return immediateFuture(null); + } + + private SqlInvokedFunction createSqlInvokedFunction(CreateFunction statement) + { + if (statement.getFunctionName().getParts().size() != 3) { + throw new PrestoException(GENERIC_USER_ERROR, format("Invalid function name: %s, require exactly 3 parts", statement.getFunctionName())); + } + + QualifiedFunctionName functionName = QualifiedFunctionName.of(statement.getFunctionName().toString()); + List parameters = statement.getParameters().stream() + .map(parameter -> new SqlParameter(parameter.getName().toString().toLowerCase(ENGLISH), parseTypeSignature(parameter.getType()))) + .collect(toImmutableList()); + TypeSignature returnType = parseTypeSignature(statement.getReturnType()); + String description = statement.getComment().orElse(""); + RoutineCharacteristics routineCharacteristics = new RoutineCharacteristics( + RoutineCharacteristics.Language.valueOf(statement.getCharacteristics().getLanguage().name()), + RoutineCharacteristics.Determinism.valueOf(statement.getCharacteristics().getDeterminism().name()), + RoutineCharacteristics.NullCallClause.valueOf(statement.getCharacteristics().getNullCallClause().name())); + String body = formatSql(statement.getBody(), Optional.empty()); + + return new SqlInvokedFunction( + functionName, + parameters, + returnType, + description, + routineCharacteristics, + body, + Optional.empty()); + } +} diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInFunctionHandle.java b/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInFunctionHandle.java index 4e5319d37b504..c0db340eb834f 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInFunctionHandle.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInFunctionHandle.java @@ -13,9 +13,9 @@ */ package com.facebook.presto.metadata; +import com.facebook.presto.spi.CatalogSchemaName; import com.facebook.presto.spi.function.FunctionHandle; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -42,9 +42,9 @@ public Signature getSignature() } @Override - public FullyQualifiedName.Prefix getFunctionNamespace() + public CatalogSchemaName getFunctionNamespace() { - return signature.getName().getPrefix(); + return signature.getName().getFunctionNamespace(); } @Override diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInFunctionNamespaceManager.java b/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInFunctionNamespaceManager.java index 30ba09f9dcba7..7d6ccc509e5bd 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInFunctionNamespaceManager.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInFunctionNamespaceManager.java @@ -150,6 +150,7 @@ import com.facebook.presto.operator.window.RowNumberFunction; import com.facebook.presto.operator.window.SqlWindowFunction; import com.facebook.presto.operator.window.WindowFunctionSupplier; +import com.facebook.presto.spi.CatalogSchemaName; import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockEncodingSerde; @@ -158,10 +159,11 @@ import com.facebook.presto.spi.function.FunctionNamespaceManager; import com.facebook.presto.spi.function.FunctionNamespaceTransactionHandle; import com.facebook.presto.spi.function.OperatorType; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.ScalarFunctionImplementation; import com.facebook.presto.spi.function.Signature; import com.facebook.presto.spi.function.SqlFunction; -import com.facebook.presto.spi.relation.FullyQualifiedName; +import com.facebook.presto.spi.function.SqlInvokedFunction; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; import com.facebook.presto.spi.type.TypeSignature; @@ -292,6 +294,7 @@ import static com.facebook.presto.operator.scalar.ZipWithFunction.ZIP_WITH_FUNCTION; import static com.facebook.presto.operator.window.AggregateWindowFunction.supplier; import static com.facebook.presto.spi.StandardErrorCode.FUNCTION_IMPLEMENTATION_MISSING; +import static com.facebook.presto.spi.StandardErrorCode.GENERIC_USER_ERROR; import static com.facebook.presto.spi.function.FunctionImplementationType.BUILTIN; import static com.facebook.presto.spi.function.FunctionKind.AGGREGATE; import static com.facebook.presto.spi.function.FunctionKind.SCALAR; @@ -353,7 +356,7 @@ public class BuiltInFunctionNamespaceManager implements FunctionNamespaceManager { - public static final FullyQualifiedName.Prefix DEFAULT_NAMESPACE = FullyQualifiedName.of("presto.default.foo").getPrefix(); + public static final CatalogSchemaName DEFAULT_NAMESPACE = new CatalogSchemaName("presto", "default"); public static final String NAME = "_builtin"; private final TypeManager typeManager; @@ -681,9 +684,9 @@ public synchronized void registerBuiltInFunctions(List listFunctions() } @Override - public Collection getFunctions(Optional transactionHandle, FullyQualifiedName functionName) + public Collection getFunctions(Optional transactionHandle, QualifiedFunctionName functionName) { return functions.get(functionName); } @@ -902,7 +905,7 @@ private static class EmptyTransactionHandle private static class FunctionMap { - private final Multimap functions; + private final Multimap functions; public FunctionMap() { @@ -911,13 +914,13 @@ public FunctionMap() public FunctionMap(FunctionMap map, Iterable functions) { - this.functions = ImmutableListMultimap.builder() + this.functions = ImmutableListMultimap.builder() .putAll(map.functions) .putAll(Multimaps.index(functions, function -> function.getSignature().getName())) .build(); // Make sure all functions with the same name are aggregations or none of them are - for (Map.Entry> entry : this.functions.asMap().entrySet()) { + for (Map.Entry> entry : this.functions.asMap().entrySet()) { Collection values = entry.getValue(); long aggregations = values.stream() .map(function -> function.getSignature().getKind()) @@ -932,7 +935,7 @@ public List list() return ImmutableList.copyOf(functions.values()); } - public Collection get(FullyQualifiedName name) + public Collection get(QualifiedFunctionName name) { return functions.get(name); } @@ -945,7 +948,7 @@ private static class MagicLiteralFunction MagicLiteralFunction(BlockEncodingSerde blockEncodingSerde) { - super(new Signature(FullyQualifiedName.of(DEFAULT_NAMESPACE, MAGIC_LITERAL_FUNCTION_PREFIX), SCALAR, TypeSignature.parseTypeSignature("R"), TypeSignature.parseTypeSignature("T"))); + super(new Signature(QualifiedFunctionName.of(DEFAULT_NAMESPACE, MAGIC_LITERAL_FUNCTION_PREFIX), SCALAR, TypeSignature.parseTypeSignature("R"), TypeSignature.parseTypeSignature("T"))); this.blockEncodingSerde = requireNonNull(blockEncodingSerde, "blockEncodingSerde is null"); } diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/CastType.java b/presto-main/src/main/java/com/facebook/presto/metadata/CastType.java index ac43f79525a3e..6e53d79797ede 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/CastType.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/CastType.java @@ -14,7 +14,7 @@ package com.facebook.presto.metadata; import com.facebook.presto.spi.function.OperatorType; -import com.facebook.presto.spi.relation.FullyQualifiedName; +import com.facebook.presto.spi.function.QualifiedFunctionName; import static com.facebook.presto.metadata.BuiltInFunctionNamespaceManager.DEFAULT_NAMESPACE; import static com.facebook.presto.operator.scalar.JsonStringToArrayCast.JSON_STRING_TO_ARRAY_NAME; @@ -27,21 +27,21 @@ public enum CastType { CAST(OperatorType.CAST.getFunctionName(), true), SATURATED_FLOOR_CAST(OperatorType.SATURATED_FLOOR_CAST.getFunctionName(), true), - TRY_CAST(FullyQualifiedName.of(DEFAULT_NAMESPACE, TRY_CAST_NAME), false), - JSON_TO_ARRAY_CAST(FullyQualifiedName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_ARRAY_NAME), false), - JSON_TO_MAP_CAST(FullyQualifiedName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_MAP_NAME), false), - JSON_TO_ROW_CAST(FullyQualifiedName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_ROW_NAME), false); + TRY_CAST(QualifiedFunctionName.of(DEFAULT_NAMESPACE, TRY_CAST_NAME), false), + JSON_TO_ARRAY_CAST(QualifiedFunctionName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_ARRAY_NAME), false), + JSON_TO_MAP_CAST(QualifiedFunctionName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_MAP_NAME), false), + JSON_TO_ROW_CAST(QualifiedFunctionName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_ROW_NAME), false); - private final FullyQualifiedName castName; + private final QualifiedFunctionName castName; private final boolean isOperatorType; - CastType(FullyQualifiedName castName, boolean isOperatorType) + CastType(QualifiedFunctionName castName, boolean isOperatorType) { this.castName = castName; this.isOperatorType = isOperatorType; } - public FullyQualifiedName getCastName() + public QualifiedFunctionName getCastName() { return castName; } diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/FunctionManager.java b/presto-main/src/main/java/com/facebook/presto/metadata/FunctionManager.java index 138b57d012580..f895099f3a6cb 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/FunctionManager.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/FunctionManager.java @@ -13,12 +13,13 @@ */ package com.facebook.presto.metadata; -import com.facebook.presto.Session; import com.facebook.presto.operator.aggregation.InternalAggregationFunction; import com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation; import com.facebook.presto.operator.window.WindowFunctionSupplier; +import com.facebook.presto.spi.CatalogSchemaName; import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.block.BlockEncodingSerde; +import com.facebook.presto.spi.function.CatalogSchemaPrefix; import com.facebook.presto.spi.function.FunctionHandle; import com.facebook.presto.spi.function.FunctionKind; import com.facebook.presto.spi.function.FunctionMetadata; @@ -27,10 +28,11 @@ import com.facebook.presto.spi.function.FunctionNamespaceManagerFactory; import com.facebook.presto.spi.function.FunctionNamespaceTransactionHandle; import com.facebook.presto.spi.function.OperatorType; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.ScalarFunctionImplementation; import com.facebook.presto.spi.function.Signature; import com.facebook.presto.spi.function.SqlFunction; -import com.facebook.presto.spi.relation.FullyQualifiedName; +import com.facebook.presto.spi.function.SqlInvokedFunction; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; import com.facebook.presto.spi.type.TypeSignature; @@ -63,6 +65,7 @@ import static com.facebook.presto.spi.StandardErrorCode.AMBIGUOUS_FUNCTION_CALL; import static com.facebook.presto.spi.StandardErrorCode.FUNCTION_IMPLEMENTATION_MISSING; import static com.facebook.presto.spi.StandardErrorCode.FUNCTION_NOT_FOUND; +import static com.facebook.presto.spi.StandardErrorCode.GENERIC_USER_ERROR; import static com.facebook.presto.spi.function.FunctionKind.SCALAR; import static com.facebook.presto.spi.type.TypeSignature.parseTypeSignature; import static com.facebook.presto.sql.analyzer.TypeSignatureProvider.fromTypeSignatures; @@ -92,7 +95,7 @@ public class FunctionManager private final FunctionInvokerProvider functionInvokerProvider; private final Map functionNamespaceManagerFactories = new ConcurrentHashMap<>(); private final HandleResolver handleResolver; - private final Map> functionNamespaces = new ConcurrentHashMap<>(); + private final Map> functionNamespaces = new ConcurrentHashMap<>(); @Inject public FunctionManager( @@ -105,7 +108,7 @@ public FunctionManager( this.typeManager = requireNonNull(typeManager, "typeManager is null"); this.transactionManager = requireNonNull(transactionManager, "transactionManager is null"); this.builtInFunctionNamespaceManager = new BuiltInFunctionNamespaceManager(typeManager, blockEncodingSerde, featuresConfig, this); - this.functionNamespaces.put(DEFAULT_NAMESPACE, builtInFunctionNamespaceManager); + this.functionNamespaces.put(DEFAULT_NAMESPACE.asCatalogSchemaPrefix(), builtInFunctionNamespaceManager); this.functionInvokerProvider = new FunctionInvokerProvider(this); this.handleResolver = handleResolver; if (typeManager instanceof TypeRegistry) { @@ -122,7 +125,7 @@ public FunctionManager(TypeManager typeManager, BlockEncodingSerde blockEncoding this(typeManager, createTestTransactionManager(), blockEncodingSerde, featuresConfig, new HandleResolver()); } - public void loadFunctionNamespaces(String functionNamespaceManagerName, List functionNamespacePrefixes, Map properties) + public void loadFunctionNamespaces(String functionNamespaceManagerName, List catalogSchemaPrefixes, Map properties) { requireNonNull(functionNamespaceManagerName, "connectorName is null"); FunctionNamespaceManagerFactory factory = functionNamespaceManagerFactories.get(functionNamespaceManagerName); @@ -130,10 +133,9 @@ public void loadFunctionNamespaces(String functionNamespaceManagerName, List functionNamespaceManager = factory.create(properties); transactionManager.registerFunctionNamespaceManager(functionNamespaceManagerName, functionNamespaceManager); - for (String functionNamespacePrefix : functionNamespacePrefixes) { - FunctionNamespaceManager otherFunctionNamespaceManager = functionNamespaces.putIfAbsent(FullyQualifiedName.Prefix.of(functionNamespacePrefix), functionNamespaceManager); - if (otherFunctionNamespaceManager != null) { - throw new IllegalArgumentException(format("Function namespace manager '%s' already registered to handle function namespace '%s'", otherFunctionNamespaceManager.getName(), functionNamespacePrefix)); + for (String catalogSchemaPrefix : catalogSchemaPrefixes) { + if (functionNamespaces.putIfAbsent(CatalogSchemaPrefix.of(catalogSchemaPrefix), functionNamespaceManager) != null) { + throw new IllegalArgumentException(format("Function namespace manager '%s' already registered to handle function namespace '%s'", factory.getName(), catalogSchemaPrefix)); } } } @@ -163,6 +165,15 @@ public List listFunctions() .collect(toImmutableList()); } + public void createFunction(SqlInvokedFunction function, boolean replace) + { + Optional> functionNamespaceManager = getServingFunctionNamespaceManager(function.getSignature().getName().getFunctionNamespace()); + if (!functionNamespaceManager.isPresent()) { + throw new PrestoException(GENERIC_USER_ERROR, format("Cannot create function in function namespace: %s", function.getFunctionId().getFunctionName().getFunctionNamespace())); + } + functionNamespaceManager.get().createFunction(function, replace); + } + /** * Resolves a function using implicit type coercions. We enforce explicit naming for dynamic function namespaces. * All unqualified function names will only be resolved against the built-in static function namespace. While it is @@ -173,17 +184,25 @@ public List listFunctions() */ public FunctionHandle resolveFunction(Optional transactionId, QualifiedName name, List parameterTypes) { - FullyQualifiedName functionName; + QualifiedFunctionName functionName; if (!name.getPrefix().isPresent()) { - functionName = FullyQualifiedName.of(DEFAULT_NAMESPACE, name.getSuffix()); + functionName = QualifiedFunctionName.of(DEFAULT_NAMESPACE, name.getSuffix()); } else { - functionName = FullyQualifiedName.of(name.getOriginalParts()); + if (name.getOriginalParts().size() != 3) { + throw new PrestoException(FUNCTION_NOT_FOUND, format("Non-builtin functions must be reference by three parts: catalog.schema.function_name, found: %s", name.toString())); + } + functionName = QualifiedFunctionName.of(new CatalogSchemaName(name.getOriginalParts().get(0), name.getOriginalParts().get(1)), name.getOriginalParts().get(2)); } - Optional> functionNamespaceManager = getServingFunctionNamespaceManager(functionName); + return resolveFunction(transactionId, functionName, parameterTypes); + } + + public FunctionHandle resolveFunction(Optional transactionId, QualifiedFunctionName functionName, List parameterTypes) + { + Optional> functionNamespaceManager = getServingFunctionNamespaceManager(functionName.getFunctionNamespace()); if (!functionNamespaceManager.isPresent()) { - throw new PrestoException(FUNCTION_NOT_FOUND, format("Cannot find function namespace for function %s", name)); + throw new PrestoException(FUNCTION_NOT_FOUND, constructFunctionNotFoundErrorMessage(functionName, parameterTypes, ImmutableList.of())); } Optional transactionHandle = transactionId @@ -204,9 +223,9 @@ public FunctionHandle resolveFunction(Optional transactionId, Qua return functionNamespaceManager.get().getFunctionHandle(transactionHandle, match.get()); } - if (name.getSuffix().startsWith(MAGIC_LITERAL_FUNCTION_PREFIX)) { - // extract type from function name - String typeName = name.getSuffix().substring(MAGIC_LITERAL_FUNCTION_PREFIX.length()); + if (functionName.getFunctionName().startsWith(MAGIC_LITERAL_FUNCTION_PREFIX)) { + // extract type from function functionName + String typeName = functionName.getFunctionName().substring(MAGIC_LITERAL_FUNCTION_PREFIX.length()); // lookup the type Type type = typeManager.getType(parseTypeSignature(typeName)); @@ -217,18 +236,22 @@ public FunctionHandle resolveFunction(Optional transactionId, Qua return new BuiltInFunctionHandle(getMagicLiteralFunctionSignature(type)); } - throw new PrestoException(FUNCTION_NOT_FOUND, constructFunctionNotFoundErrorMessage(name.toString(), parameterTypes, candidates)); + throw new PrestoException(FUNCTION_NOT_FOUND, constructFunctionNotFoundErrorMessage(functionName, parameterTypes, candidates)); } @Override public FunctionMetadata getFunctionMetadata(FunctionHandle functionHandle) { - return functionNamespaces.get(functionHandle.getFunctionNamespace()).getFunctionMetadata(functionHandle); + Optional> functionNamespaceManager = getServingFunctionNamespaceManager(functionHandle.getFunctionNamespace()); + checkArgument(functionNamespaceManager.isPresent(), "Cannot find function namespace for '%s'", functionHandle.getFunctionNamespace()); + return functionNamespaceManager.get().getFunctionMetadata(functionHandle); } public ScalarFunctionImplementation getScalarFunctionImplementation(FunctionHandle functionHandle) { - return functionNamespaces.get(functionHandle.getFunctionNamespace()).getScalarFunctionImplementation(functionHandle); + Optional> functionNamespaceManager = getServingFunctionNamespaceManager(functionHandle.getFunctionNamespace()); + checkArgument(functionNamespaceManager.isPresent(), "Cannot find function namespace for '%s'", functionHandle.getFunctionNamespace()); + return functionNamespaceManager.get().getScalarFunctionImplementation(functionHandle); } public WindowFunctionSupplier getWindowFunctionImplementation(FunctionHandle functionHandle) @@ -249,7 +272,7 @@ public BuiltInScalarFunctionImplementation getBuiltInScalarFunctionImplementatio @VisibleForTesting public List listOperators() { - Set operatorNames = Arrays.asList(OperatorType.values()).stream() + Set operatorNames = Arrays.asList(OperatorType.values()).stream() .map(OperatorType::getFunctionName) .collect(toImmutableSet()); @@ -261,7 +284,7 @@ public List listOperators() public FunctionHandle resolveOperator(OperatorType operatorType, List argumentTypes) { try { - return resolveFunction(Optional.empty(), QualifiedName.of(operatorType.getFunctionName().getParts()), argumentTypes); + return resolveFunction(Optional.empty(), operatorType.getFunctionName(), argumentTypes); } catch (PrestoException e) { if (e.getErrorCode().getCode() == FUNCTION_NOT_FOUND.toErrorCode().getCode()) { @@ -278,14 +301,14 @@ public FunctionHandle resolveOperator(OperatorType operatorType, List parameterTypes) { - FullyQualifiedName functionName = FullyQualifiedName.of(DEFAULT_NAMESPACE, name); + QualifiedFunctionName functionName = QualifiedFunctionName.of(DEFAULT_NAMESPACE, name); Collection candidates = builtInFunctionNamespaceManager.getFunctions(Optional.empty(), functionName); return lookupFunction(builtInFunctionNamespaceManager, Optional.empty(), functionName, parameterTypes, candidates); } @@ -309,7 +332,7 @@ public FunctionHandle lookupCast(CastType castType, TypeSignature fromType, Type private FunctionHandle lookupFunction( FunctionNamespaceManager functionNamespaceManager, Optional transactionHandle, - FullyQualifiedName functionName, + QualifiedFunctionName functionName, List parameterTypes, Collection candidates) { @@ -331,30 +354,31 @@ private FunctionHandle lookupFunction( return functionNamespaceManager.getFunctionHandle(transactionHandle, match.get()); } - throw new PrestoException(FUNCTION_NOT_FOUND, constructFunctionNotFoundErrorMessage(functionName.toString(), parameterTypes, candidates)); + throw new PrestoException(FUNCTION_NOT_FOUND, constructFunctionNotFoundErrorMessage(functionName, parameterTypes, candidates)); } - private Optional> getServingFunctionNamespaceManager(FullyQualifiedName functionName) + private Optional> getServingFunctionNamespaceManager(CatalogSchemaName functionNamespace) { - FullyQualifiedName.Prefix functionPrefix = functionName.getPrefix(); - if (functionPrefix.equals(DEFAULT_NAMESPACE)) { + if (functionNamespace.equals(DEFAULT_NAMESPACE)) { return Optional.of(builtInFunctionNamespaceManager); } - FullyQualifiedName.Prefix bestMatchNamespace = null; + CatalogSchemaPrefix bestMatch = null; FunctionNamespaceManager servingFunctionNamespaceManager = null; - for (Map.Entry> functionNamespace : functionNamespaces.entrySet()) { - if (functionNamespace.getKey().contains(functionPrefix) && (bestMatchNamespace == null || bestMatchNamespace.contains(functionNamespace.getKey()))) { - bestMatchNamespace = functionNamespace.getKey(); - servingFunctionNamespaceManager = functionNamespace.getValue(); + for (Map.Entry> entry : functionNamespaces.entrySet()) { + CatalogSchemaPrefix prefix = entry.getKey(); + if (prefix.includes(functionNamespace) && (bestMatch == null || bestMatch.includes(prefix))) { + bestMatch = prefix; + servingFunctionNamespaceManager = entry.getValue(); } } return Optional.ofNullable(servingFunctionNamespaceManager); } - private String constructFunctionNotFoundErrorMessage(String name, List parameterTypes, Collection candidates) + private String constructFunctionNotFoundErrorMessage(QualifiedFunctionName functionName, List parameterTypes, Collection candidates) { + String name = toConciseFunctionName(functionName); List expectedParameters = new ArrayList<>(); for (SqlFunction function : candidates) { expectedParameters.add(format("%s(%s) %s", @@ -371,6 +395,14 @@ private String constructFunctionNotFoundErrorMessage(String name, List matchFunctionExact(List candidates, List actualParameters) { return matchFunction(candidates, actualParameters, false); diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/SignatureBuilder.java b/presto-main/src/main/java/com/facebook/presto/metadata/SignatureBuilder.java index 356f88e20c6c8..7445b0971b983 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/SignatureBuilder.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/SignatureBuilder.java @@ -16,9 +16,9 @@ import com.facebook.presto.spi.function.FunctionKind; import com.facebook.presto.spi.function.LongVariableConstraint; import com.facebook.presto.spi.function.OperatorType; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; import com.facebook.presto.spi.function.TypeVariableConstraint; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.TypeSignature; import com.google.common.collect.ImmutableList; @@ -32,7 +32,7 @@ public final class SignatureBuilder { - private FullyQualifiedName name; + private QualifiedFunctionName name; private FunctionKind kind; private List typeVariableConstraints = emptyList(); private List longVariableConstraints = emptyList(); @@ -49,11 +49,11 @@ public static SignatureBuilder builder() public SignatureBuilder name(String name) { - this.name = FullyQualifiedName.of(DEFAULT_NAMESPACE, requireNonNull(name, "name is null")); + this.name = QualifiedFunctionName.of(DEFAULT_NAMESPACE, requireNonNull(name, "name is null")); return this; } - public SignatureBuilder name(FullyQualifiedName name) + public SignatureBuilder name(QualifiedFunctionName name) { this.name = requireNonNull(name, "name is null"); return this; diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/SqlAggregationFunction.java b/presto-main/src/main/java/com/facebook/presto/metadata/SqlAggregationFunction.java index cbe3a29b34f98..17c193344b72d 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/SqlAggregationFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/SqlAggregationFunction.java @@ -17,9 +17,9 @@ import com.facebook.presto.operator.aggregation.InternalAggregationFunction; import com.facebook.presto.spi.function.FunctionKind; import com.facebook.presto.spi.function.LongVariableConstraint; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; import com.facebook.presto.spi.function.TypeVariableConstraint; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.TypeManager; import com.facebook.presto.spi.type.TypeSignature; import com.google.common.collect.ImmutableList; @@ -93,7 +93,7 @@ private static Signature createSignature( requireNonNull(argumentTypes, "argumentTypes is null"); checkArgument(kind == AGGREGATE, "kind must be an aggregate"); return new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, name), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, name), kind, ImmutableList.copyOf(typeVariableConstraints), ImmutableList.copyOf(longVariableConstraints), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/aggregation/AggregationImplementation.java b/presto-main/src/main/java/com/facebook/presto/operator/aggregation/AggregationImplementation.java index df1fb9b76f998..fc81c17bedaf0 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/aggregation/AggregationImplementation.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/aggregation/AggregationImplementation.java @@ -26,11 +26,11 @@ import com.facebook.presto.spi.function.FunctionKind; import com.facebook.presto.spi.function.LongVariableConstraint; import com.facebook.presto.spi.function.OutputFunction; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; import com.facebook.presto.spi.function.SqlType; import com.facebook.presto.spi.function.TypeParameter; import com.facebook.presto.spi.function.TypeVariableConstraint; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.TypeManager; import com.facebook.presto.spi.type.TypeSignature; import com.google.common.collect.ImmutableList; @@ -306,7 +306,7 @@ private Parser( private AggregationImplementation get() { Signature signature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, header.getName()), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, header.getName()), FunctionKind.AGGREGATE, typeVariableConstraints, longVariableConstraints, diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/AbstractGreatestLeast.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/AbstractGreatestLeast.java index b97dc36761d5b..0ac39aafe9740 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/AbstractGreatestLeast.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/AbstractGreatestLeast.java @@ -28,8 +28,8 @@ import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.function.FunctionKind; import com.facebook.presto.spi.function.OperatorType; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; @@ -73,7 +73,7 @@ public abstract class AbstractGreatestLeast private final OperatorType operatorType; - protected AbstractGreatestLeast(FullyQualifiedName name, OperatorType operatorType) + protected AbstractGreatestLeast(QualifiedFunctionName name, OperatorType operatorType) { super(new Signature( name, diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ApplyFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ApplyFunction.java index 55e480fcc4d83..c681f9c68f83e 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ApplyFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ApplyFunction.java @@ -17,8 +17,8 @@ import com.facebook.presto.metadata.FunctionManager; import com.facebook.presto.metadata.SqlScalarFunction; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; import com.facebook.presto.sql.gen.lambda.UnaryFunctionInterface; @@ -48,7 +48,7 @@ public final class ApplyFunction private ApplyFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "apply"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "apply"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T"), typeVariable("U")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayConcatFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayConcatFunction.java index 79439e6468991..9179b02329a7e 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayConcatFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayConcatFunction.java @@ -22,8 +22,8 @@ import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; import com.facebook.presto.sql.gen.VarArgsToArrayAdapterGenerator; @@ -56,7 +56,7 @@ public final class ArrayConcatFunction private ArrayConcatFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, FUNCTION_NAME), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, FUNCTION_NAME), FunctionKind.SCALAR, ImmutableList.of(typeVariable("E")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayConstructor.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayConstructor.java index 416f895c0c3b7..99c449b84b2cb 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayConstructor.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayConstructor.java @@ -29,8 +29,8 @@ import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.block.BlockBuilderStatus; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; import com.facebook.presto.sql.gen.CallSiteBinder; @@ -75,7 +75,7 @@ public final class ArrayConstructor public ArrayConstructor() { - super(new Signature(FullyQualifiedName.of(DEFAULT_NAMESPACE, "array_constructor"), + super(new Signature(QualifiedFunctionName.of(DEFAULT_NAMESPACE, "array_constructor"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("E")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFlattenFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFlattenFunction.java index 19224e1b9b58d..cab59b576e049 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFlattenFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFlattenFunction.java @@ -19,8 +19,8 @@ import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; @@ -46,7 +46,7 @@ public class ArrayFlattenFunction private ArrayFlattenFunction() { - super(new Signature(FullyQualifiedName.of(DEFAULT_NAMESPACE, FUNCTION_NAME), + super(new Signature(QualifiedFunctionName.of(DEFAULT_NAMESPACE, FUNCTION_NAME), FunctionKind.SCALAR, ImmutableList.of(typeVariable("E")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayJoin.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayJoin.java index 04801b57f8c52..a1e88d1910866 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayJoin.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayJoin.java @@ -24,8 +24,8 @@ import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; @@ -96,7 +96,7 @@ public static class ArrayJoinWithNullReplacement public ArrayJoinWithNullReplacement() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, FUNCTION_NAME), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, FUNCTION_NAME), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T")), ImmutableList.of(), @@ -133,7 +133,7 @@ public BuiltInScalarFunctionImplementation specialize(BoundVariables boundVariab public ArrayJoin() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, FUNCTION_NAME), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, FUNCTION_NAME), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayReduceFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayReduceFunction.java index eb3059bfe1e0d..d6fec733041bc 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayReduceFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayReduceFunction.java @@ -18,8 +18,8 @@ import com.facebook.presto.metadata.SqlScalarFunction; import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; import com.facebook.presto.sql.gen.lambda.BinaryFunctionInterface; @@ -49,7 +49,7 @@ public final class ArrayReduceFunction private ArrayReduceFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "reduce"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "reduce"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T"), typeVariable("S"), typeVariable("R")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayToArrayCast.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayToArrayCast.java index 6d7b3260f4310..0a8a80a3aa7b2 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayToArrayCast.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayToArrayCast.java @@ -117,7 +117,7 @@ private static Class generateArrayCast(TypeManager typeManager, FunctionMetad Type fromElementType = typeManager.getType(elementCastFunctionMetadata.getArgumentTypes().get(0)); Type toElementType = typeManager.getType(elementCastFunctionMetadata.getReturnType()); CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(definition, binder); - ArrayMapBytecodeExpression newArray = ArrayGeneratorUtils.map(scope, cachedInstanceBinder, fromElementType, toElementType, value, elementCastFunctionMetadata.getName().getSuffix(), elementCast); + ArrayMapBytecodeExpression newArray = ArrayGeneratorUtils.map(scope, cachedInstanceBinder, fromElementType, toElementType, value, elementCastFunctionMetadata.getName().getFunctionName(), elementCast); // return the block body.append(newArray.ret()); diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayToElementConcatFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayToElementConcatFunction.java index b513ab2768ec1..6f7526cb9ff62 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayToElementConcatFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayToElementConcatFunction.java @@ -18,8 +18,8 @@ import com.facebook.presto.metadata.SqlScalarFunction; import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; import com.google.common.collect.ImmutableList; @@ -48,7 +48,7 @@ public class ArrayToElementConcatFunction public ArrayToElementConcatFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "concat"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "concat"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("E")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayTransformFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayTransformFunction.java index 9d5292f5a75e8..9bcb66d462191 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayTransformFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayTransformFunction.java @@ -29,8 +29,8 @@ import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.ArrayType; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; @@ -76,7 +76,7 @@ public final class ArrayTransformFunction private ArrayTransformFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "transform"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "transform"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T"), typeVariable("U")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ConcatFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ConcatFunction.java index 5fd6e6e90906e..8409aa393a032 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ConcatFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ConcatFunction.java @@ -27,8 +27,8 @@ import com.facebook.presto.metadata.SqlScalarFunction; import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.TypeManager; import com.facebook.presto.spi.type.TypeSignature; import com.google.common.collect.ImmutableList; @@ -78,7 +78,7 @@ public final class ConcatFunction private ConcatFunction(TypeSignature type, String description) { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "concat"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "concat"), FunctionKind.SCALAR, ImmutableList.of(), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ElementToArrayConcatFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ElementToArrayConcatFunction.java index 468b70e959b78..63a2ca140253b 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ElementToArrayConcatFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ElementToArrayConcatFunction.java @@ -18,8 +18,8 @@ import com.facebook.presto.metadata.SqlScalarFunction; import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; import com.google.common.collect.ImmutableList; @@ -48,7 +48,7 @@ public class ElementToArrayConcatFunction public ElementToArrayConcatFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "concat"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "concat"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("E")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/Greatest.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/Greatest.java index 824b433e17377..3831dec1a9770 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/Greatest.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/Greatest.java @@ -14,7 +14,7 @@ package com.facebook.presto.operator.scalar; import com.facebook.presto.spi.function.OperatorType; -import com.facebook.presto.spi.relation.FullyQualifiedName; +import com.facebook.presto.spi.function.QualifiedFunctionName; import static com.facebook.presto.metadata.BuiltInFunctionNamespaceManager.DEFAULT_NAMESPACE; @@ -25,7 +25,7 @@ public final class Greatest public Greatest() { - super(FullyQualifiedName.of(DEFAULT_NAMESPACE, "greatest"), OperatorType.GREATER_THAN); + super(QualifiedFunctionName.of(DEFAULT_NAMESPACE, "greatest"), OperatorType.GREATER_THAN); } @Override diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/InvokeFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/InvokeFunction.java index 14fe2e91be7d9..0eb8f3817720f 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/InvokeFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/InvokeFunction.java @@ -18,8 +18,8 @@ import com.facebook.presto.metadata.FunctionManager; import com.facebook.presto.metadata.SqlScalarFunction; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; import com.facebook.presto.sql.gen.lambda.LambdaFunctionInterface; @@ -47,7 +47,7 @@ public final class InvokeFunction private InvokeFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "invoke"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "invoke"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToArrayCast.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToArrayCast.java index a5f9684fcc1ff..504f10c2c7443 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToArrayCast.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToArrayCast.java @@ -16,8 +16,8 @@ import com.facebook.presto.metadata.BoundVariables; import com.facebook.presto.metadata.FunctionManager; import com.facebook.presto.metadata.SqlScalarFunction; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.TypeManager; import com.google.common.collect.ImmutableList; @@ -37,7 +37,7 @@ public final class JsonStringToArrayCast private JsonStringToArrayCast() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_ARRAY_NAME), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_ARRAY_NAME), SCALAR, ImmutableList.of(typeVariable("T")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToMapCast.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToMapCast.java index 3c7319844e4db..bf1e710f868ec 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToMapCast.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToMapCast.java @@ -16,8 +16,8 @@ import com.facebook.presto.metadata.BoundVariables; import com.facebook.presto.metadata.FunctionManager; import com.facebook.presto.metadata.SqlScalarFunction; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.TypeManager; import com.google.common.collect.ImmutableList; @@ -38,7 +38,7 @@ public final class JsonStringToMapCast private JsonStringToMapCast() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_MAP_NAME), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_MAP_NAME), SCALAR, ImmutableList.of(comparableTypeParameter("K"), typeVariable("V")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToRowCast.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToRowCast.java index 6120d481d7ae7..e958f5003c27e 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToRowCast.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonStringToRowCast.java @@ -16,8 +16,8 @@ import com.facebook.presto.metadata.BoundVariables; import com.facebook.presto.metadata.FunctionManager; import com.facebook.presto.metadata.SqlScalarFunction; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.TypeManager; import com.google.common.collect.ImmutableList; @@ -37,7 +37,7 @@ public final class JsonStringToRowCast private JsonStringToRowCast() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_ROW_NAME), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, JSON_STRING_TO_ROW_NAME), SCALAR, ImmutableList.of(withVariadicBound("T", "row")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/Least.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/Least.java index 5e4d1ed9124a9..46b3fc48c32a7 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/Least.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/Least.java @@ -14,7 +14,7 @@ package com.facebook.presto.operator.scalar; import com.facebook.presto.spi.function.OperatorType; -import com.facebook.presto.spi.relation.FullyQualifiedName; +import com.facebook.presto.spi.function.QualifiedFunctionName; import static com.facebook.presto.metadata.BuiltInFunctionNamespaceManager.DEFAULT_NAMESPACE; @@ -25,7 +25,7 @@ public final class Least public Least() { - super(FullyQualifiedName.of(DEFAULT_NAMESPACE, "least"), OperatorType.LESS_THAN); + super(QualifiedFunctionName.of(DEFAULT_NAMESPACE, "least"), OperatorType.LESS_THAN); } @Override diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapConcatFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapConcatFunction.java index 8d51db9a951c9..6a911588d1834 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapConcatFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapConcatFunction.java @@ -23,8 +23,8 @@ import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.MapType; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.Type; @@ -61,7 +61,7 @@ public final class MapConcatFunction private MapConcatFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, FUNCTION_NAME), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, FUNCTION_NAME), FunctionKind.SCALAR, ImmutableList.of(typeVariable("K"), typeVariable("V")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapConstructor.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapConstructor.java index 1c8fd821f7855..f390481fc954a 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapConstructor.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapConstructor.java @@ -26,8 +26,8 @@ import com.facebook.presto.spi.block.MapBlockBuilder; import com.facebook.presto.spi.function.FunctionKind; import com.facebook.presto.spi.function.OperatorType; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.MapType; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; @@ -76,7 +76,7 @@ public final class MapConstructor public MapConstructor() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "map"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "map"), FunctionKind.SCALAR, ImmutableList.of(comparableTypeParameter("K"), typeVariable("V")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapElementAtFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapElementAtFunction.java index d7a06c7f7f328..acf7438ed63e5 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapElementAtFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapElementAtFunction.java @@ -21,8 +21,8 @@ import com.facebook.presto.spi.block.SingleMapBlock; import com.facebook.presto.spi.function.FunctionKind; import com.facebook.presto.spi.function.OperatorType; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; import com.google.common.collect.ImmutableList; @@ -54,7 +54,7 @@ public class MapElementAtFunction protected MapElementAtFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "element_at"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "element_at"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("K"), typeVariable("V")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapFilterFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapFilterFunction.java index 65d08c52a4327..981a1c25334a5 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapFilterFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapFilterFunction.java @@ -30,8 +30,8 @@ import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.MapType; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.Type; @@ -82,7 +82,7 @@ public final class MapFilterFunction private MapFilterFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "map_filter"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "map_filter"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("K"), typeVariable("V")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapTransformKeyFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapTransformKeyFunction.java index 09f3e418be435..9727e8f0114b0 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapTransformKeyFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapTransformKeyFunction.java @@ -34,8 +34,8 @@ import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.MapType; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.Type; @@ -92,7 +92,7 @@ public final class MapTransformKeyFunction private MapTransformKeyFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "transform_keys"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "transform_keys"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("K1"), typeVariable("K2"), typeVariable("V")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapTransformValueFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapTransformValueFunction.java index b94cbf139cc99..ac3c8fcd39407 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapTransformValueFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapTransformValueFunction.java @@ -33,8 +33,8 @@ import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.MapType; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.Type; @@ -90,7 +90,7 @@ public final class MapTransformValueFunction private MapTransformValueFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "transform_values"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "transform_values"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("K"), typeVariable("V1"), typeVariable("V2")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapZipWithFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapZipWithFunction.java index e8d88b3c4e75e..73299327da607 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapZipWithFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapZipWithFunction.java @@ -21,8 +21,8 @@ import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.block.SingleMapBlock; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.MapType; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.Type; @@ -56,7 +56,7 @@ public final class MapZipWithFunction private MapZipWithFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "map_zip_with"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "map_zip_with"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("K"), typeVariable("V1"), typeVariable("V2"), typeVariable("V3")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/RowIndeterminateOperator.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/RowIndeterminateOperator.java index ce5549ca63d4b..89f7e2f4484b6 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/RowIndeterminateOperator.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/RowIndeterminateOperator.java @@ -137,7 +137,7 @@ private static Class generateIndeterminate(Type type, FunctionManager functio BytecodeExpression element = constantType(binder, fieldTypes.get(i)).getValue(value, constantInt(i)); ifNullField.ifFalse(new IfStatement("if the field is not null but indeterminate...") - .condition(invokeFunction(scope, cachedInstanceBinder, functionManager.getFunctionMetadata(functionHandle).getName().getSuffix(), function, element)) + .condition(invokeFunction(scope, cachedInstanceBinder, functionManager.getFunctionMetadata(functionHandle).getName().getFunctionName(), function, element)) .ifTrue(new BytecodeBlock() .push(true) .gotoLabel(end))); diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/TryCastFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/TryCastFunction.java index 60cf95e728d60..81464d91481ee 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/TryCastFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/TryCastFunction.java @@ -19,8 +19,8 @@ import com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation.ArgumentProperty; import com.facebook.presto.spi.function.FunctionHandle; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; import com.google.common.collect.ImmutableList; @@ -47,7 +47,7 @@ public class TryCastFunction public TryCastFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, TRY_CAST_NAME), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, TRY_CAST_NAME), FunctionKind.SCALAR, ImmutableList.of(typeVariable("F"), typeVariable("T")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ZipFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ZipFunction.java index 32ceaca2471b5..8621ce30e9e9c 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ZipFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ZipFunction.java @@ -21,8 +21,8 @@ import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.RowType; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; @@ -69,7 +69,7 @@ private ZipFunction(int arity) private ZipFunction(List typeParameters) { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "zip"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "zip"), FunctionKind.SCALAR, typeParameters.stream().map(Signature::typeVariable).collect(toImmutableList()), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ZipWithFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ZipWithFunction.java index 34b0baed98777..55ae92ed6b42a 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ZipWithFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ZipWithFunction.java @@ -20,8 +20,8 @@ import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.ArrayType; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; @@ -54,7 +54,7 @@ public final class ZipWithFunction private ZipWithFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "zip_with"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "zip_with"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T"), typeVariable("U"), typeVariable("R")), ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/annotations/ScalarImplementationHeader.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/annotations/ScalarImplementationHeader.java index 8aee7464eabc9..dc7a3da110d5a 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/annotations/ScalarImplementationHeader.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/annotations/ScalarImplementationHeader.java @@ -15,9 +15,9 @@ import com.facebook.presto.operator.scalar.ScalarHeader; import com.facebook.presto.spi.function.OperatorType; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.ScalarFunction; import com.facebook.presto.spi.function.ScalarOperator; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.google.common.collect.ImmutableList; import java.lang.reflect.AnnotatedElement; @@ -34,13 +34,13 @@ public class ScalarImplementationHeader { - private final FullyQualifiedName name; + private final QualifiedFunctionName name; private final Optional operatorType; private final ScalarHeader header; private ScalarImplementationHeader(String name, ScalarHeader header) { - this.name = FullyQualifiedName.of(DEFAULT_NAMESPACE, requireNonNull(name)); + this.name = QualifiedFunctionName.of(DEFAULT_NAMESPACE, requireNonNull(name)); this.operatorType = Optional.empty(); this.header = requireNonNull(header); } @@ -95,7 +95,7 @@ public static List fromAnnotatedElement(AnnotatedEle return result; } - public FullyQualifiedName getName() + public QualifiedFunctionName getName() { return name; } diff --git a/presto-main/src/main/java/com/facebook/presto/operator/window/ReflectionWindowFunctionSupplier.java b/presto-main/src/main/java/com/facebook/presto/operator/window/ReflectionWindowFunctionSupplier.java index abc2239219e40..dd558f0bf2f77 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/window/ReflectionWindowFunctionSupplier.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/window/ReflectionWindowFunctionSupplier.java @@ -14,9 +14,9 @@ package com.facebook.presto.operator.window; import com.facebook.presto.spi.function.Description; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; import com.facebook.presto.spi.function.WindowFunction; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.Type; import com.google.common.collect.Lists; @@ -35,7 +35,7 @@ public class ReflectionWindowFunctionSupplier public ReflectionWindowFunctionSupplier(String name, Type returnType, List argumentTypes, Class type) { - this(new Signature(FullyQualifiedName.of(DEFAULT_NAMESPACE, name), WINDOW, returnType.getTypeSignature(), Lists.transform(argumentTypes, Type::getTypeSignature)), type); + this(new Signature(QualifiedFunctionName.of(DEFAULT_NAMESPACE, name), WINDOW, returnType.getTypeSignature(), Lists.transform(argumentTypes, Type::getTypeSignature)), type); } public ReflectionWindowFunctionSupplier(Signature signature, Class type) diff --git a/presto-main/src/main/java/com/facebook/presto/operator/window/WindowAnnotationsParser.java b/presto-main/src/main/java/com/facebook/presto/operator/window/WindowAnnotationsParser.java index 63fbf8ee31c0a..03b299246ea8a 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/window/WindowAnnotationsParser.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/window/WindowAnnotationsParser.java @@ -13,11 +13,11 @@ */ package com.facebook.presto.operator.window; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; import com.facebook.presto.spi.function.TypeVariableConstraint; import com.facebook.presto.spi.function.WindowFunction; import com.facebook.presto.spi.function.WindowFunctionSignature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.TypeSignature; import com.google.common.collect.ImmutableList; @@ -56,7 +56,7 @@ private static SqlWindowFunction parse(Class clazz, Wi .collect(toImmutableList()); Signature signature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, window.name()), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, window.name()), WINDOW, typeVariables, ImmutableList.of(), diff --git a/presto-main/src/main/java/com/facebook/presto/server/CoordinatorModule.java b/presto-main/src/main/java/com/facebook/presto/server/CoordinatorModule.java index 097ec7b7de047..ee41e4a1fd9b4 100644 --- a/presto-main/src/main/java/com/facebook/presto/server/CoordinatorModule.java +++ b/presto-main/src/main/java/com/facebook/presto/server/CoordinatorModule.java @@ -30,6 +30,7 @@ import com.facebook.presto.execution.CallTask; import com.facebook.presto.execution.ClusterSizeMonitor; import com.facebook.presto.execution.CommitTask; +import com.facebook.presto.execution.CreateFunctionTask; import com.facebook.presto.execution.CreateRoleTask; import com.facebook.presto.execution.CreateSchemaTask; import com.facebook.presto.execution.CreateTableTask; @@ -98,6 +99,7 @@ import com.facebook.presto.sql.tree.AddColumn; import com.facebook.presto.sql.tree.Call; import com.facebook.presto.sql.tree.Commit; +import com.facebook.presto.sql.tree.CreateFunction; import com.facebook.presto.sql.tree.CreateRole; import com.facebook.presto.sql.tree.CreateSchema; import com.facebook.presto.sql.tree.CreateTable; @@ -304,6 +306,7 @@ protected void setup(Binder binder) bindDataDefinitionTask(binder, executionBinder, DropTable.class, DropTableTask.class); bindDataDefinitionTask(binder, executionBinder, CreateView.class, CreateViewTask.class); bindDataDefinitionTask(binder, executionBinder, DropView.class, DropViewTask.class); + bindDataDefinitionTask(binder, executionBinder, CreateFunction.class, CreateFunctionTask.class); bindDataDefinitionTask(binder, executionBinder, Use.class, UseTask.class); bindDataDefinitionTask(binder, executionBinder, SetSession.class, SetSessionTask.class); bindDataDefinitionTask(binder, executionBinder, ResetSession.class, ResetSessionTask.class); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/SemanticErrorCode.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/SemanticErrorCode.java index 6cac18ea5aa5b..5ce3780c9a77a 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/SemanticErrorCode.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/SemanticErrorCode.java @@ -49,6 +49,7 @@ public enum SemanticErrorCode INVALID_LITERAL, FUNCTION_NOT_FOUND, + DUPLICATE_PARAMETER_NAME, ORDER_BY_MUST_BE_IN_SELECT, ORDER_BY_MUST_BE_IN_AGGREGATE, diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java index 656506f05f27b..0ad25a58005a0 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java @@ -49,6 +49,7 @@ import com.facebook.presto.sql.tree.Analyze; import com.facebook.presto.sql.tree.Call; import com.facebook.presto.sql.tree.Commit; +import com.facebook.presto.sql.tree.CreateFunction; import com.facebook.presto.sql.tree.CreateSchema; import com.facebook.presto.sql.tree.CreateTable; import com.facebook.presto.sql.tree.CreateTableAsSelect; @@ -113,6 +114,7 @@ import com.facebook.presto.sql.tree.SimpleGroupBy; import com.facebook.presto.sql.tree.SingleColumn; import com.facebook.presto.sql.tree.SortItem; +import com.facebook.presto.sql.tree.SqlParameterDeclaration; import com.facebook.presto.sql.tree.StartTransaction; import com.facebook.presto.sql.tree.Statement; import com.facebook.presto.sql.tree.Table; @@ -125,6 +127,7 @@ import com.facebook.presto.sql.tree.With; import com.facebook.presto.sql.tree.WithQuery; import com.facebook.presto.sql.util.AstUtils; +import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; @@ -139,6 +142,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import static com.facebook.presto.SystemSessionProperties.getMaxGroupingSets; @@ -149,6 +153,7 @@ import static com.facebook.presto.spi.function.FunctionKind.WINDOW; import static com.facebook.presto.spi.type.BigintType.BIGINT; import static com.facebook.presto.spi.type.BooleanType.BOOLEAN; +import static com.facebook.presto.spi.type.TypeSignature.parseTypeSignature; import static com.facebook.presto.spi.type.VarcharType.VARCHAR; import static com.facebook.presto.sql.NodeUtils.getSortItemsFromOrderBy; import static com.facebook.presto.sql.NodeUtils.mapFromProperties; @@ -165,6 +170,7 @@ import static com.facebook.presto.sql.analyzer.SemanticErrorCode.COLUMN_NAME_NOT_SPECIFIED; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.COLUMN_TYPE_UNKNOWN; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.DUPLICATE_COLUMN_NAME; +import static com.facebook.presto.sql.analyzer.SemanticErrorCode.DUPLICATE_PARAMETER_NAME; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.DUPLICATE_PROPERTY; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.DUPLICATE_RELATION; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.INVALID_ORDINAL; @@ -212,7 +218,10 @@ import static java.lang.String.format; import static java.util.Collections.emptyList; import static java.util.Locale.ENGLISH; +import static java.util.Map.Entry; import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.counting; +import static java.util.stream.Collectors.groupingBy; class StatementAnalyzer { @@ -538,6 +547,45 @@ protected Scope visitCreateView(CreateView node, Optional scope) return createAndAssignScope(node, scope); } + @Override + protected Scope visitCreateFunction(CreateFunction node, Optional scope) + { + analysis.setUpdateType("CREATE FUNCTION"); + + // Check parameter + List duplicateParameters = node.getParameters().stream() + .map(SqlParameterDeclaration::getName) + .map(Identifier::getValue) + .collect(groupingBy(Function.identity(), counting())) + .entrySet() + .stream() + .filter(entry -> entry.getValue() > 1) + .map(Entry::getKey) + .collect(toImmutableList()); + if (!duplicateParameters.isEmpty()) { + throw new SemanticException(DUPLICATE_PARAMETER_NAME, node, "Duplicate function parameter name: %s", Joiner.on(", ").join(duplicateParameters)); + } + + // Check return type + Type returnType = metadata.getType(parseTypeSignature(node.getReturnType())); + List fields = node.getParameters().stream() + .map(parameter -> Field.newUnqualified(parameter.getName().getValue(), metadata.getType(parseTypeSignature(parameter.getType())))) + .collect(toImmutableList()); + Scope functionScope = Scope.builder() + .withRelationType(RelationId.anonymous(), new RelationType(fields)) + .build(); + Type bodyType = analyzeExpression(node.getBody(), functionScope).getExpressionTypes().get(NodeRef.of(node.getBody())); + if (!bodyType.equals(returnType)) { + throw new SemanticException(TYPE_MISMATCH, node, "Function implementation type '%s' does not match declared return type '%s'", bodyType, returnType); + } + + Analyzer.verifyNoAggregateWindowOrGroupingFunctions(analysis.getFunctionHandles(), metadata.getFunctionManager(), node.getBody(), "CREATE FUNCTION body"); + + // TODO: Check body contains no SQL invoked functions + + return createAndAssignScope(node, scope); + } + @Override protected Scope visitSetSession(SetSession node, Optional scope) { diff --git a/presto-main/src/main/java/com/facebook/presto/sql/gen/FunctionCallCodeGenerator.java b/presto-main/src/main/java/com/facebook/presto/sql/gen/FunctionCallCodeGenerator.java index f39fc51f3f35f..2d12903176509 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/gen/FunctionCallCodeGenerator.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/gen/FunctionCallCodeGenerator.java @@ -49,7 +49,7 @@ public BytecodeNode generateCall(FunctionHandle functionHandle, BytecodeGenerato } return context.generateCall( - functionManager.getFunctionMetadata(functionHandle).getName().getSuffix(), + functionManager.getFunctionMetadata(functionHandle).getName().getFunctionName(), function, argumentsBytecode, outputBlockVariable.map(variable -> new OutputBlockVariableAndType(variable, returnType))); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/LiteralEncoder.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/LiteralEncoder.java index a3f837254b598..a7c4ce1eea20f 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/LiteralEncoder.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/LiteralEncoder.java @@ -17,8 +17,8 @@ import com.facebook.presto.operator.scalar.VarbinaryFunctions; import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockEncodingSerde; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.relation.RowExpression; import com.facebook.presto.spi.type.ArrayType; import com.facebook.presto.spi.type.CharType; @@ -294,7 +294,7 @@ public static Signature getMagicLiteralFunctionSignature(Type type) { TypeSignature argumentType = typeForMagicLiteral(type).getTypeSignature(); - return new Signature(FullyQualifiedName.of(DEFAULT_NAMESPACE, MAGIC_LITERAL_FUNCTION_PREFIX + type.getTypeSignature()), + return new Signature(QualifiedFunctionName.of(DEFAULT_NAMESPACE, MAGIC_LITERAL_FUNCTION_PREFIX + type.getTypeSignature()), SCALAR, type.getTypeSignature(), argumentType); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/LocalExecutionPlanner.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/LocalExecutionPlanner.java index a07c14761e2ea..403d6bfbf768b 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/LocalExecutionPlanner.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/LocalExecutionPlanner.java @@ -121,6 +121,7 @@ import com.facebook.presto.spi.function.FunctionHandle; import com.facebook.presto.spi.function.FunctionMetadata; import com.facebook.presto.spi.function.OperatorType; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.SqlFunctionProperties; import com.facebook.presto.spi.plan.AggregationNode; import com.facebook.presto.spi.plan.AggregationNode.Aggregation; @@ -138,7 +139,6 @@ import com.facebook.presto.spi.plan.ValuesNode; import com.facebook.presto.spi.relation.CallExpression; import com.facebook.presto.spi.relation.ConstantExpression; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.relation.InputReferenceExpression; import com.facebook.presto.spi.relation.LambdaDefinitionExpression; import com.facebook.presto.spi.relation.RowExpression; @@ -1740,7 +1740,7 @@ private Optional removeExpressionFromFilter(RowExpression filter, private SpatialPredicate spatialTest(CallExpression functionCall, boolean probeFirst, Optional comparisonOperator) { - FullyQualifiedName functionName = metadata.getFunctionManager().getFunctionMetadata(functionCall.getFunctionHandle()).getName(); + QualifiedFunctionName functionName = metadata.getFunctionManager().getFunctionMetadata(functionCall.getFunctionHandle()).getName(); if (functionName.equals(ST_CONTAINS)) { if (probeFirst) { return (buildGeometry, probeGeometry, radius) -> probeGeometry.contains(buildGeometry); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/NullabilityAnalyzer.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/NullabilityAnalyzer.java index 899b9c8adfd55..1438a4de6f2d3 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/NullabilityAnalyzer.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/NullabilityAnalyzer.java @@ -199,7 +199,7 @@ else if (!functionReturnsNullForNotNullInput(function)) { private boolean functionReturnsNullForNotNullInput(FunctionMetadata function) { - return (function.getName().getSuffix().equalsIgnoreCase("like")); + return (function.getName().getFunctionName().equalsIgnoreCase("like")); } @Override diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/RowExpressionEqualityInference.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/RowExpressionEqualityInference.java index aa4ab8937ee80..7f04c6f189edb 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/RowExpressionEqualityInference.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/RowExpressionEqualityInference.java @@ -493,7 +493,7 @@ private static CallExpression buildEqualsExpression(FunctionManager functionMana private static CallExpression binaryOperation(FunctionManager functionManager, OperatorType type, RowExpression left, RowExpression right) { return call( - type.getFunctionName().getSuffix(), + type.getFunctionName().getFunctionName(), functionManager.resolveOperator(type, fromTypes(left.getType(), right.getType())), BOOLEAN, left, diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/RowExpressionInterpreter.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/RowExpressionInterpreter.java index bf2c2c3c86dc2..8b68e559212da 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/RowExpressionInterpreter.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/RowExpressionInterpreter.java @@ -776,7 +776,7 @@ private SpecialCallResult tryHandleCast(CallExpression callExpression, List createAggregationOverNull(AggregationNod aggregation.getOrderBy().map(orderBy -> inlineOrderByVariables(sourcesVariableMapping, orderBy)), aggregation.isDistinct(), aggregation.getMask().map(x -> new VariableReferenceExpression(sourcesVariableMapping.get(x).getName(), x.getType()))); - FullyQualifiedName functionName = functionManager.getFunctionMetadata(overNullAggregation.getFunctionHandle()).getName(); - VariableReferenceExpression overNull = variableAllocator.newVariable(functionName.getSuffix(), aggregationVariable.getType()); + QualifiedFunctionName functionName = functionManager.getFunctionMetadata(overNullAggregation.getFunctionHandle()).getName(); + VariableReferenceExpression overNull = variableAllocator.newVariable(functionName.getFunctionName(), aggregationVariable.getType()); aggregationsOverNullBuilder.put(overNull, overNullAggregation); aggregationsVariableMappingBuilder.put(aggregationVariable, overNull); } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/PushPartialAggregationThroughExchange.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/PushPartialAggregationThroughExchange.java index 02a252d9f07d6..bb28753283ffd 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/PushPartialAggregationThroughExchange.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/PushPartialAggregationThroughExchange.java @@ -201,7 +201,7 @@ private PlanNode split(AggregationNode node, Context context) Map finalAggregation = new HashMap<>(); for (Map.Entry entry : node.getAggregations().entrySet()) { AggregationNode.Aggregation originalAggregation = entry.getValue(); - String functionName = functionManager.getFunctionMetadata(originalAggregation.getFunctionHandle()).getName().getSuffix(); + String functionName = functionManager.getFunctionMetadata(originalAggregation.getFunctionHandle()).getName().getFunctionName(); FunctionHandle functionHandle = originalAggregation.getFunctionHandle(); InternalAggregationFunction function = functionManager.getAggregateFunctionImplementation(functionHandle); VariableReferenceExpression intermediateVariable = context.getVariableAllocator().newVariable(functionName, function.getIntermediateType()); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/RewriteSpatialPartitioningAggregation.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/RewriteSpatialPartitioningAggregation.java index 79f26ab9e0cf2..866ffbf3826ea 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/RewriteSpatialPartitioningAggregation.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/RewriteSpatialPartitioningAggregation.java @@ -16,12 +16,12 @@ import com.facebook.presto.matching.Captures; import com.facebook.presto.matching.Pattern; import com.facebook.presto.metadata.Metadata; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.plan.AggregationNode; import com.facebook.presto.spi.plan.AggregationNode.Aggregation; import com.facebook.presto.spi.plan.Assignments; import com.facebook.presto.spi.plan.ProjectNode; import com.facebook.presto.spi.relation.CallExpression; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.relation.RowExpression; import com.facebook.presto.spi.relation.VariableReferenceExpression; import com.facebook.presto.spi.type.Type; @@ -68,7 +68,7 @@ public class RewriteSpatialPartitioningAggregation implements Rule { private static final TypeSignature GEOMETRY_TYPE_SIGNATURE = parseTypeSignature("Geometry"); - private static final FullyQualifiedName NAME = FullyQualifiedName.of(DEFAULT_NAMESPACE, "spatial_partitioning"); + private static final QualifiedFunctionName NAME = QualifiedFunctionName.of(DEFAULT_NAMESPACE, "spatial_partitioning"); private final Pattern pattern = aggregation().matching(this::hasSpatialPartitioningAggregation); private final Metadata metadata; @@ -99,7 +99,7 @@ public Result apply(AggregationNode node, Captures captures, Context context) ImmutableMap.Builder envelopeAssignments = ImmutableMap.builder(); for (Map.Entry entry : node.getAggregations().entrySet()) { Aggregation aggregation = entry.getValue(); - FullyQualifiedName name = metadata.getFunctionManager().getFunctionMetadata(aggregation.getFunctionHandle()).getName(); + QualifiedFunctionName name = metadata.getFunctionManager().getFunctionMetadata(aggregation.getFunctionHandle()).getName(); Type geometryType = metadata.getType(GEOMETRY_TYPE_SIGNATURE); if (name.equals(NAME) && aggregation.getArguments().size() == 1) { RowExpression geometry = getOnlyElement(aggregation.getArguments()); @@ -113,8 +113,8 @@ public Result apply(AggregationNode node, Captures captures, Context context) aggregations.put(entry.getKey(), new Aggregation( new CallExpression( - name.getSuffix(), - metadata.getFunctionManager().lookupFunction(NAME.getSuffix(), fromTypes(geometryType, INTEGER)), + name.getFunctionName(), + metadata.getFunctionManager().lookupFunction(NAME.getFunctionName(), fromTypes(geometryType, INTEGER)), entry.getKey().getType(), ImmutableList.of( castToRowExpression(asSymbolReference(envelopeVariable)), diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/ExpressionEquivalence.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/ExpressionEquivalence.java index d326243774a8e..a3408698a3af3 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/ExpressionEquivalence.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/ExpressionEquivalence.java @@ -18,9 +18,9 @@ import com.facebook.presto.metadata.FunctionManager; import com.facebook.presto.metadata.Metadata; import com.facebook.presto.spi.function.FunctionHandle; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.relation.CallExpression; import com.facebook.presto.spi.relation.ConstantExpression; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.relation.InputReferenceExpression; import com.facebook.presto.spi.relation.LambdaDefinitionExpression; import com.facebook.presto.spi.relation.RowExpression; @@ -143,7 +143,7 @@ public RowExpression visitCall(CallExpression call, Void context) .map(expression -> expression.accept(this, context)) .collect(toImmutableList())); - FullyQualifiedName callName = functionManager.getFunctionMetadata(call.getFunctionHandle()).getName(); + QualifiedFunctionName callName = functionManager.getFunctionMetadata(call.getFunctionHandle()).getName(); if (callName.equals(EQUAL.getFunctionName()) || callName.equals(NOT_EQUAL.getFunctionName()) || callName.equals(IS_DISTINCT_FROM.getFunctionName())) { // sort arguments diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/HashGenerationOptimizer.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/HashGenerationOptimizer.java index ca28f54b443c2..d1fb458c47b85 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/HashGenerationOptimizer.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/HashGenerationOptimizer.java @@ -91,7 +91,7 @@ public class HashGenerationOptimizer implements PlanOptimizer { public static final long INITIAL_HASH_VALUE = 0; - private static final String HASH_CODE = OperatorType.HASH_CODE.getFunctionName().getSuffix(); + private static final String HASH_CODE = OperatorType.HASH_CODE.getFunctionName().getFunctionName(); private final FunctionManager functionManager; diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/MetadataQueryOptimizer.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/MetadataQueryOptimizer.java index 53694e25205ee..74d34a3743dea 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/MetadataQueryOptimizer.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/MetadataQueryOptimizer.java @@ -21,6 +21,7 @@ import com.facebook.presto.spi.ColumnHandle; import com.facebook.presto.spi.Constraint; import com.facebook.presto.spi.DiscretePredicates; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.plan.AggregationNode; import com.facebook.presto.spi.plan.AggregationNode.Aggregation; import com.facebook.presto.spi.plan.FilterNode; @@ -33,7 +34,6 @@ import com.facebook.presto.spi.plan.ValuesNode; import com.facebook.presto.spi.predicate.NullableValue; import com.facebook.presto.spi.predicate.TupleDomain; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.relation.RowExpression; import com.facebook.presto.spi.relation.VariableReferenceExpression; import com.facebook.presto.sql.planner.ExpressionDeterminismEvaluator; @@ -66,10 +66,10 @@ public class MetadataQueryOptimizer implements PlanOptimizer { - private static final Set ALLOWED_FUNCTIONS = ImmutableSet.of( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "max"), - FullyQualifiedName.of(DEFAULT_NAMESPACE, "min"), - FullyQualifiedName.of(DEFAULT_NAMESPACE, "approx_distinct")); + private static final Set ALLOWED_FUNCTIONS = ImmutableSet.of( + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "max"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "min"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "approx_distinct")); private final Metadata metadata; private final LiteralEncoder literalEncoder; @@ -112,7 +112,7 @@ public PlanNode visitAggregation(AggregationNode node, RewriteContext cont { // supported functions are only MIN/MAX/APPROX_DISTINCT or distinct aggregates for (Aggregation aggregation : node.getAggregations().values()) { - FullyQualifiedName functionName = metadata.getFunctionManager().getFunctionMetadata(aggregation.getFunctionHandle()).getName(); + QualifiedFunctionName functionName = metadata.getFunctionManager().getFunctionMetadata(aggregation.getFunctionHandle()).getName(); if (!ALLOWED_FUNCTIONS.contains(functionName) && !aggregation.isDistinct()) { return context.defaultRewrite(node); } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/OptimizeMixedDistinctAggregations.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/OptimizeMixedDistinctAggregations.java index 210bf4b918deb..69e59df27b5a4 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/OptimizeMixedDistinctAggregations.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/OptimizeMixedDistinctAggregations.java @@ -16,6 +16,7 @@ import com.facebook.presto.Session; import com.facebook.presto.execution.warnings.WarningCollector; import com.facebook.presto.metadata.Metadata; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.plan.AggregationNode; import com.facebook.presto.spi.plan.AggregationNode.Aggregation; import com.facebook.presto.spi.plan.Assignments; @@ -23,7 +24,6 @@ import com.facebook.presto.spi.plan.PlanNodeIdAllocator; import com.facebook.presto.spi.plan.ProjectNode; import com.facebook.presto.spi.relation.CallExpression; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.relation.RowExpression; import com.facebook.presto.spi.relation.VariableReferenceExpression; import com.facebook.presto.spi.type.BigintType; @@ -193,10 +193,10 @@ public PlanNode visitAggregation(AggregationNode node, RewriteContext latestFunctions = new ConcurrentHashMap<>(); + + private final Map latestFunctions = new ConcurrentHashMap<>(); public InMemoryFunctionNamespaceManager(SqlInvokedFunctionNamespaceManagerConfig config) { @@ -54,31 +54,29 @@ public String getName() } @Override - public synchronized void createFunction(SqlInvokedRegularFunction function, boolean replace) + public synchronized void createFunction(SqlInvokedFunction function, boolean replace) { - SqlFunctionId functionId = new SqlFunctionId(function.getSignature().getName(), function.getSignature().getArgumentTypes()); - if (!replace && latestFunctions.containsKey(functionId)) { - throw new PrestoException(GENERIC_USER_ERROR, format("Function '%s' already exists", functionId.getName())); + SqlFunctionId functionId = function.getFunctionId(); + if (!replace && latestFunctions.containsKey(function.getFunctionId())) { + throw new PrestoException(GENERIC_USER_ERROR, format("Function '%s' already exists", functionId.getId())); } - SqlInvokedRegularFunction replacedFunction = latestFunctions.get(functionId); + SqlInvokedFunction replacedFunction = latestFunctions.get(functionId); long version = 1; if (replacedFunction != null) { - checkArgument(replacedFunction.getVersion().isPresent(), "missing version in replaced function"); - version = replacedFunction.getVersion().get() + 1; + version = replacedFunction.getRequiredVersion() + 1; } - function = SqlInvokedRegularFunction.versioned(function, version); - latestFunctions.put(functionId, function); + latestFunctions.put(functionId, function.withVersion(version)); } @Override - public Collection listFunctions() + public Collection listFunctions() { return latestFunctions.values(); } @Override - public Collection fetchFunctionsDirect(FullyQualifiedName name) + public Collection fetchFunctionsDirect(QualifiedFunctionName name) { return latestFunctions.values().stream() .filter(function -> function.getSignature().getName().equals(name)) @@ -87,30 +85,30 @@ public Collection fetchFunctionsDirect(FullyQualified } @Override - public FunctionMetadata fetchFunctionMetadataDirect(SqlInvokedRegularFunctionHandle functionHandle) + public FunctionMetadata fetchFunctionMetadataDirect(SqlFunctionHandle functionHandle) { - return fetchFunctionsDirect(functionHandle.getName()).stream() + return fetchFunctionsDirect(functionHandle.getFunctionId().getFunctionName()).stream() .filter(function -> function.getRequiredFunctionHandle().equals(functionHandle)) .map(AbstractSqlInvokedFunctionNamespaceManager::sqlInvokedFunctionToMetadata) .collect(onlyElement()); } @Override - protected ScalarFunctionImplementation fetchFunctionImplementationDirect(SqlInvokedRegularFunctionHandle functionHandle) + protected ScalarFunctionImplementation fetchFunctionImplementationDirect(SqlFunctionHandle functionHandle) { - return fetchFunctionsDirect(functionHandle.getName()).stream() + return fetchFunctionsDirect(functionHandle.getFunctionId().getFunctionName()).stream() .filter(function -> function.getRequiredFunctionHandle().equals(functionHandle)) .map(AbstractSqlInvokedFunctionNamespaceManager::sqlInvokedFunctionToImplementation) .collect(onlyElement()); } - private static SqlInvokedRegularFunction copyFunction(SqlInvokedRegularFunction function) + private static SqlInvokedFunction copyFunction(SqlInvokedFunction function) { - return new SqlInvokedRegularFunction( + return new SqlInvokedFunction( function.getSignature().getName(), function.getParameters(), function.getSignature().getReturnType(), - function.getComment(), + function.getDescription(), function.getRoutineCharacteristics(), function.getBody(), function.getVersion()); diff --git a/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java b/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java index 8bd20b81aa7dd..9d947e47190ab 100644 --- a/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java +++ b/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java @@ -37,6 +37,7 @@ import com.facebook.presto.cost.TaskCountEstimator; import com.facebook.presto.eventlistener.EventListenerManager; import com.facebook.presto.execution.CommitTask; +import com.facebook.presto.execution.CreateFunctionTask; import com.facebook.presto.execution.CreateTableTask; import com.facebook.presto.execution.CreateViewTask; import com.facebook.presto.execution.DataDefinitionTask; @@ -148,6 +149,7 @@ import com.facebook.presto.sql.relational.RowExpressionDeterminismEvaluator; import com.facebook.presto.sql.relational.RowExpressionDomainTranslator; import com.facebook.presto.sql.tree.Commit; +import com.facebook.presto.sql.tree.CreateFunction; import com.facebook.presto.sql.tree.CreateTable; import com.facebook.presto.sql.tree.CreateView; import com.facebook.presto.sql.tree.Deallocate; @@ -418,6 +420,7 @@ private LocalQueryRunner(Session defaultSession, FeaturesConfig featuresConfig, dataDefinitionTask = ImmutableMap., DataDefinitionTask>builder() .put(CreateTable.class, new CreateTableTask()) .put(CreateView.class, new CreateViewTask(jsonCodec(ViewDefinition.class), sqlParser, new FeaturesConfig())) + .put(CreateFunction.class, new CreateFunctionTask(sqlParser)) .put(DropTable.class, new DropTableTask()) .put(DropView.class, new DropViewTask()) .put(RenameColumn.class, new RenameColumnTask()) diff --git a/presto-main/src/main/java/com/facebook/presto/transaction/InMemoryTransactionManager.java b/presto-main/src/main/java/com/facebook/presto/transaction/InMemoryTransactionManager.java index 1e6ce8f8f4367..dab73460d3a66 100644 --- a/presto-main/src/main/java/com/facebook/presto/transaction/InMemoryTransactionManager.java +++ b/presto-main/src/main/java/com/facebook/presto/transaction/InMemoryTransactionManager.java @@ -53,6 +53,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; +import java.util.stream.Stream; import static com.facebook.airlift.concurrent.MoreFutures.addExceptionCallback; import static com.facebook.presto.spi.StandardErrorCode.AUTOCOMMIT_WRITE_CONFLICT; @@ -241,7 +242,7 @@ public synchronized void registerFunctionNamespaceManager(String functionNamespa @Override public FunctionNamespaceTransactionHandle getFunctionNamespaceTransaction(TransactionId transactionId, String functionNamespaceManagerName) { - return getTransactionMetadata(transactionId).getFunctionNamespaceTransaction(functionNamespaceManagerName); + return getTransactionMetadata(transactionId).getFunctionNamespaceTransaction(functionNamespaceManagerName).getTransactionHandle(); } private void checkConnectorWrite(TransactionId transactionId, ConnectorId connectorId) @@ -342,7 +343,7 @@ private static class TransactionMetadata private final Map> functionNamespaceManagers; @GuardedBy("this") - private final Map functionNamespaceTransactions = new ConcurrentHashMap<>(); + private final Map functionNamespaceTransactions = new ConcurrentHashMap<>(); public TransactionMetadata( TransactionId transactionId, @@ -460,11 +461,17 @@ private synchronized CatalogMetadata getTransactionCatalogMetadata(ConnectorId c return catalogMetadata; } - private synchronized FunctionNamespaceTransactionHandle getFunctionNamespaceTransaction(String functionNamespaceManagerName) + private synchronized FunctionNamespaceTransactionMetadata getFunctionNamespaceTransaction(String functionNamespaceManagerName) { checkOpenTransaction(); - return functionNamespaceTransactions.computeIfAbsent(functionNamespaceManagerName, name -> functionNamespaceManagers.get(name).beginTransaction()); + return functionNamespaceTransactions.computeIfAbsent( + functionNamespaceManagerName, name -> { + verify(name != null, "Unknown function namespace manager: %s", name); + FunctionNamespaceManager functionNamespaceManager = functionNamespaceManagers.get(name); + FunctionNamespaceTransactionHandle transactionHandle = functionNamespaceManager.beginTransaction(); + return new FunctionNamespaceTransactionMetadata(functionNamespaceManager, transactionHandle); + }); } public synchronized ConnectorTransactionMetadata createConnectorTransactionMetadata(ConnectorId connectorId, Catalog catalog) @@ -512,16 +519,23 @@ public synchronized ListenableFuture asyncCommit() return immediateFailedFuture(new PrestoException(TRANSACTION_ALREADY_ABORTED, "Current transaction has already been aborted")); } + ListenableFuture functionNamespaceFuture = Futures.allAsList(functionNamespaceTransactions.values().stream() + .map(transactionMetadata -> finishingExecutor.submit(transactionMetadata::commit)) + .collect(toImmutableList())); + ConnectorId writeConnectorId = this.writtenConnectorId.get(); if (writeConnectorId == null) { - ListenableFuture future = Futures.allAsList(connectorIdToMetadata.values().stream() - .map(transactionMetadata -> finishingExecutor.submit(transactionMetadata::commit)) - .collect(toList())); - addExceptionCallback(future, throwable -> { - abortInternal(); - log.error(throwable, "Read-only connector should not throw exception on commit"); - }); - return nonCancellationPropagating(future); + Supplier> commitReadOnlyConnectors = () -> { + ListenableFuture> future = Futures.allAsList(connectorIdToMetadata.values().stream() + .map(transactionMetadata -> finishingExecutor.submit(transactionMetadata::commit)) + .collect(toList())); + addExceptionCallback(future, throwable -> log.error(throwable, "Read-only connector should not throw exception on commit")); + return future; + }; + + ListenableFuture readOnlyCommitFuture = Futures.transformAsync(functionNamespaceFuture, ignored -> commitReadOnlyConnectors.get(), directExecutor()); + addExceptionCallback(readOnlyCommitFuture, this::abortInternal); + return nonCancellationPropagating(readOnlyCommitFuture); } Supplier> commitReadOnlyConnectors = () -> { @@ -535,9 +549,11 @@ public synchronized ListenableFuture asyncCommit() }; ConnectorTransactionMetadata writeConnector = connectorIdToMetadata.get(writeConnectorId); - ListenableFuture commitFuture = finishingExecutor.submit(writeConnector::commit); + Supplier commitFunctionNamespaceTransactions = () -> functionNamespaceFuture; + ListenableFuture commitFuture = Futures.transformAsync(finishingExecutor.submit(writeConnector::commit), ignored -> commitFunctionNamespaceTransactions.get(), directExecutor()); ListenableFuture readOnlyCommitFuture = Futures.transformAsync(commitFuture, ignored -> commitReadOnlyConnectors.get(), directExecutor()); addExceptionCallback(readOnlyCommitFuture, this::abortInternal); + return nonCancellationPropagating(readOnlyCommitFuture); } @@ -557,8 +573,11 @@ public synchronized ListenableFuture asyncAbort() private synchronized ListenableFuture abortInternal() { // the callbacks in statement performed on another thread so are safe - return nonCancellationPropagating(Futures.allAsList(connectorIdToMetadata.values().stream() - .map(connection -> finishingExecutor.submit(() -> safeAbort(connection))) + return nonCancellationPropagating(Futures.allAsList(Stream.concat( + functionNamespaceTransactions.values().stream() + .map(transactionMetadata -> finishingExecutor.submit(() -> safeAbort(transactionMetadata))), + connectorIdToMetadata.values().stream() + .map(connection -> finishingExecutor.submit(() -> safeAbort(connection)))) .collect(toList()))); } @@ -572,6 +591,16 @@ private static void safeAbort(ConnectorTransactionMetadata connection) } } + private static void safeAbort(FunctionNamespaceTransactionMetadata transactionMetadata) + { + try { + transactionMetadata.abort(); + } + catch (Exception e) { + log.error(e, "Function namespace transaction threw exception on abort"); + } + } + public TransactionInfo getTransactionInfo() { Duration idleTime = Optional.ofNullable(idleStartTime.get()) @@ -639,5 +668,42 @@ public void abort() } } } + + private static class FunctionNamespaceTransactionMetadata + { + private final FunctionNamespaceManager functionNamespaceManager; + private final FunctionNamespaceTransactionHandle transactionHandle; + private final AtomicBoolean finished = new AtomicBoolean(); + + public FunctionNamespaceTransactionMetadata(FunctionNamespaceManager functionNamespaceManager, FunctionNamespaceTransactionHandle transactionHandle) + { + this.functionNamespaceManager = requireNonNull(functionNamespaceManager, "functionNamespaceManager is null"); + this.transactionHandle = requireNonNull(transactionHandle, "transactionHandle is null"); + } + + public FunctionNamespaceManager getFunctionNamespaceManager() + { + return functionNamespaceManager; + } + + public FunctionNamespaceTransactionHandle getTransactionHandle() + { + return transactionHandle; + } + + public void commit() + { + if (finished.compareAndSet(false, true)) { + functionNamespaceManager.commit(transactionHandle); + } + } + + public void abort() + { + if (finished.compareAndSet(false, true)) { + functionNamespaceManager.abort(transactionHandle); + } + } + } } } diff --git a/presto-main/src/main/java/com/facebook/presto/util/SpatialJoinUtils.java b/presto-main/src/main/java/com/facebook/presto/util/SpatialJoinUtils.java index 30055fcbfe35e..c83992fdb1167 100644 --- a/presto-main/src/main/java/com/facebook/presto/util/SpatialJoinUtils.java +++ b/presto-main/src/main/java/com/facebook/presto/util/SpatialJoinUtils.java @@ -16,8 +16,8 @@ import com.facebook.presto.expressions.LogicalRowExpressions; import com.facebook.presto.metadata.FunctionManager; import com.facebook.presto.spi.function.FunctionMetadata; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.relation.CallExpression; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.relation.RowExpression; import com.facebook.presto.sql.relational.FunctionResolution; import com.facebook.presto.sql.tree.ComparisonExpression; @@ -37,18 +37,18 @@ public class SpatialJoinUtils { - public static final FullyQualifiedName ST_CONTAINS = FullyQualifiedName.of(DEFAULT_NAMESPACE, "st_contains"); - public static final FullyQualifiedName ST_CROSSES = FullyQualifiedName.of(DEFAULT_NAMESPACE, "st_crosses"); - public static final FullyQualifiedName ST_EQUALS = FullyQualifiedName.of(DEFAULT_NAMESPACE, "st_equals"); - public static final FullyQualifiedName ST_INTERSECTS = FullyQualifiedName.of(DEFAULT_NAMESPACE, "st_intersects"); - public static final FullyQualifiedName ST_OVERLAPS = FullyQualifiedName.of(DEFAULT_NAMESPACE, "st_overlaps"); - public static final FullyQualifiedName ST_TOUCHES = FullyQualifiedName.of(DEFAULT_NAMESPACE, "st_touches"); - public static final FullyQualifiedName ST_WITHIN = FullyQualifiedName.of(DEFAULT_NAMESPACE, "st_within"); - public static final FullyQualifiedName ST_DISTANCE = FullyQualifiedName.of(DEFAULT_NAMESPACE, "st_distance"); + public static final QualifiedFunctionName ST_CONTAINS = QualifiedFunctionName.of(DEFAULT_NAMESPACE, "st_contains"); + public static final QualifiedFunctionName ST_CROSSES = QualifiedFunctionName.of(DEFAULT_NAMESPACE, "st_crosses"); + public static final QualifiedFunctionName ST_EQUALS = QualifiedFunctionName.of(DEFAULT_NAMESPACE, "st_equals"); + public static final QualifiedFunctionName ST_INTERSECTS = QualifiedFunctionName.of(DEFAULT_NAMESPACE, "st_intersects"); + public static final QualifiedFunctionName ST_OVERLAPS = QualifiedFunctionName.of(DEFAULT_NAMESPACE, "st_overlaps"); + public static final QualifiedFunctionName ST_TOUCHES = QualifiedFunctionName.of(DEFAULT_NAMESPACE, "st_touches"); + public static final QualifiedFunctionName ST_WITHIN = QualifiedFunctionName.of(DEFAULT_NAMESPACE, "st_within"); + public static final QualifiedFunctionName ST_DISTANCE = QualifiedFunctionName.of(DEFAULT_NAMESPACE, "st_distance"); private static final Set ALLOWED_SPATIAL_JOIN_FUNCTIONS = Stream.of( ST_CONTAINS, ST_CROSSES, ST_EQUALS, ST_INTERSECTS, ST_OVERLAPS, ST_TOUCHES, ST_WITHIN) - .map(FullyQualifiedName::getSuffix) + .map(QualifiedFunctionName::getFunctionName) .map(String::toLowerCase) .collect(Collectors.toSet()); @@ -88,7 +88,7 @@ private static boolean isSupportedSpatialFunction(FunctionCall functionCall) private static boolean isSupportedSpatialFunction(CallExpression call, FunctionManager functionManager) { - String functionName = functionManager.getFunctionMetadata(call.getFunctionHandle()).getName().getSuffix().toLowerCase(ENGLISH); + String functionName = functionManager.getFunctionMetadata(call.getFunctionHandle()).getName().getFunctionName().toLowerCase(ENGLISH); return ALLOWED_SPATIAL_JOIN_FUNCTIONS.contains(functionName); } @@ -154,7 +154,7 @@ private static boolean isSupportedSpatialComparison(CallExpression expression, F private static boolean isSTDistance(Expression expression) { if (expression instanceof FunctionCall) { - return ((FunctionCall) expression).getName().getSuffix().equalsIgnoreCase(ST_DISTANCE.getSuffix()); + return ((FunctionCall) expression).getName().getSuffix().equalsIgnoreCase(ST_DISTANCE.getFunctionName()); } return false; diff --git a/presto-main/src/main/java/com/facebook/presto/util/StatementUtils.java b/presto-main/src/main/java/com/facebook/presto/util/StatementUtils.java index cc22a189eceaf..627bddda22694 100644 --- a/presto-main/src/main/java/com/facebook/presto/util/StatementUtils.java +++ b/presto-main/src/main/java/com/facebook/presto/util/StatementUtils.java @@ -18,6 +18,7 @@ import com.facebook.presto.sql.tree.Analyze; import com.facebook.presto.sql.tree.Call; import com.facebook.presto.sql.tree.Commit; +import com.facebook.presto.sql.tree.CreateFunction; import com.facebook.presto.sql.tree.CreateRole; import com.facebook.presto.sql.tree.CreateSchema; import com.facebook.presto.sql.tree.CreateTable; @@ -109,6 +110,7 @@ private StatementUtils() {} builder.put(DropTable.class, QueryType.DATA_DEFINITION); builder.put(CreateView.class, QueryType.DATA_DEFINITION); builder.put(DropView.class, QueryType.DATA_DEFINITION); + builder.put(CreateFunction.class, QueryType.DATA_DEFINITION); builder.put(Use.class, QueryType.DATA_DEFINITION); builder.put(SetSession.class, QueryType.DATA_DEFINITION); builder.put(ResetSession.class, QueryType.DATA_DEFINITION); diff --git a/presto-main/src/test/java/com/facebook/presto/metadata/TestFunctionManager.java b/presto-main/src/test/java/com/facebook/presto/metadata/TestFunctionManager.java index e448b7e121b7c..acd0bd62fd7be 100644 --- a/presto-main/src/test/java/com/facebook/presto/metadata/TestFunctionManager.java +++ b/presto-main/src/test/java/com/facebook/presto/metadata/TestFunctionManager.java @@ -16,6 +16,7 @@ import com.facebook.presto.block.BlockEncodingManager; import com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation; import com.facebook.presto.operator.scalar.CustomFunctions; +import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.block.BlockEncodingSerde; import com.facebook.presto.spi.function.FunctionHandle; import com.facebook.presto.spi.function.OperatorType; @@ -109,7 +110,7 @@ public void testMagicLiteralFunction() TypeRegistry typeManager = new TypeRegistry(); FunctionManager functionManager = createFunctionManager(typeManager); - BuiltInFunctionHandle functionHandle = (BuiltInFunctionHandle) functionManager.resolveFunction(TEST_SESSION.getTransactionId(), QualifiedName.of(signature.getName().getParts()), fromTypeSignatures(signature.getArgumentTypes())); + BuiltInFunctionHandle functionHandle = (BuiltInFunctionHandle) functionManager.resolveFunction(TEST_SESSION.getTransactionId(), signature.getName(), fromTypeSignatures(signature.getArgumentTypes())); assertEquals(functionManager.getFunctionMetadata(functionHandle).getArgumentTypes(), ImmutableList.of(parseTypeSignature(StandardTypes.BIGINT))); assertEquals(signature.getReturnType().getBase(), StandardTypes.TIMESTAMP_WITH_TIME_ZONE); } @@ -172,6 +173,22 @@ public void testOperatorTypes() assertFalse(functionManager.getFunctionMetadata(functionResolution.notFunction()).getOperatorType().isPresent()); } + @Test(expectedExceptions = PrestoException.class, expectedExceptionsMessageRegExp = ".*Non-builtin functions must be reference by three parts: catalog\\.schema\\.function_name, found: a\\.b") + public void testSqlFunctionReferenceTooShort() + { + TypeRegistry typeManager = new TypeRegistry(); + FunctionManager functionManager = new FunctionManager(typeManager, new BlockEncodingManager(typeManager), new FeaturesConfig()); + functionManager.resolveFunction(TEST_SESSION.getTransactionId(), QualifiedName.of("a", "b"), ImmutableList.of()); + } + + @Test(expectedExceptions = PrestoException.class, expectedExceptionsMessageRegExp = ".*Non-builtin functions must be reference by three parts: catalog\\.schema\\.function_name, found: a\\.b\\.c\\.d") + public void testSqlFunctionReferenceTooLong() + { + TypeRegistry typeManager = new TypeRegistry(); + FunctionManager functionManager = new FunctionManager(typeManager, new BlockEncodingManager(typeManager), new FeaturesConfig()); + functionManager.resolveFunction(TEST_SESSION.getTransactionId(), QualifiedName.of("a", "b", "c", "d"), ImmutableList.of()); + } + @Test public void testResolveFunctionByExactMatch() { diff --git a/presto-main/src/test/java/com/facebook/presto/metadata/TestFunctionNamespaceManager.java b/presto-main/src/test/java/com/facebook/presto/metadata/TestFunctionNamespaceManager.java index 8607ef8c2c040..00a379e516279 100644 --- a/presto-main/src/test/java/com/facebook/presto/metadata/TestFunctionNamespaceManager.java +++ b/presto-main/src/test/java/com/facebook/presto/metadata/TestFunctionNamespaceManager.java @@ -17,8 +17,8 @@ import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.function.FunctionMetadata; import com.facebook.presto.spi.function.FunctionNamespaceTransactionHandle; +import com.facebook.presto.spi.function.SqlInvokedFunction; import com.facebook.presto.sqlfunction.SqlInvokedFunctionNamespaceManagerConfig; -import com.facebook.presto.sqlfunction.SqlInvokedRegularFunction; import com.facebook.presto.testing.InMemoryFunctionNamespaceManager; import com.google.common.collect.ImmutableSet; import io.airlift.units.Duration; @@ -27,12 +27,11 @@ import java.util.Collection; import java.util.Optional; -import static com.facebook.presto.metadata.SqlInvokedRegularFunctionTestUtils.FUNCTION_POWER_TOWER_DOUBLE; -import static com.facebook.presto.metadata.SqlInvokedRegularFunctionTestUtils.FUNCTION_POWER_TOWER_DOUBLE_UPDATED; -import static com.facebook.presto.metadata.SqlInvokedRegularFunctionTestUtils.FUNCTION_POWER_TOWER_INT; -import static com.facebook.presto.metadata.SqlInvokedRegularFunctionTestUtils.POWER_TOWER; import static com.facebook.presto.spi.StandardErrorCode.GENERIC_USER_ERROR; -import static com.facebook.presto.sqlfunction.SqlInvokedRegularFunction.versioned; +import static com.facebook.presto.sqlfunction.testing.SqlInvokedFunctionTestUtils.FUNCTION_POWER_TOWER_DOUBLE; +import static com.facebook.presto.sqlfunction.testing.SqlInvokedFunctionTestUtils.FUNCTION_POWER_TOWER_DOUBLE_UPDATED; +import static com.facebook.presto.sqlfunction.testing.SqlInvokedFunctionTestUtils.FUNCTION_POWER_TOWER_INT; +import static com.facebook.presto.sqlfunction.testing.SqlInvokedFunctionTestUtils.POWER_TOWER; import static com.facebook.presto.testing.assertions.Assert.assertEquals; import static com.google.common.collect.Iterables.getOnlyElement; import static java.lang.String.format; @@ -49,17 +48,17 @@ public void testCreateFunction() { InMemoryFunctionNamespaceManager functionNamespaceManager = createFunctionNamespaceManager(); functionNamespaceManager.createFunction(FUNCTION_POWER_TOWER_DOUBLE, false); - assertEquals(functionNamespaceManager.listFunctions(), ImmutableSet.of(versioned(FUNCTION_POWER_TOWER_DOUBLE, 1))); + assertEquals(functionNamespaceManager.listFunctions(), ImmutableSet.of(FUNCTION_POWER_TOWER_DOUBLE.withVersion(1))); functionNamespaceManager.createFunction(FUNCTION_POWER_TOWER_INT, false); assertEquals( ImmutableSet.copyOf(functionNamespaceManager.listFunctions()), - ImmutableSet.of(versioned(FUNCTION_POWER_TOWER_DOUBLE, 1), versioned(FUNCTION_POWER_TOWER_INT, 1))); + ImmutableSet.of(FUNCTION_POWER_TOWER_DOUBLE.withVersion(1), FUNCTION_POWER_TOWER_INT.withVersion(1))); functionNamespaceManager.createFunction(FUNCTION_POWER_TOWER_DOUBLE_UPDATED, true); assertEquals( ImmutableSet.copyOf(functionNamespaceManager.listFunctions()), - ImmutableSet.of(versioned(FUNCTION_POWER_TOWER_DOUBLE_UPDATED, 2), versioned(FUNCTION_POWER_TOWER_INT, 1))); + ImmutableSet.of(FUNCTION_POWER_TOWER_DOUBLE_UPDATED.withVersion(2), FUNCTION_POWER_TOWER_INT.withVersion(1))); System.out.println(FUNCTION_POWER_TOWER_DOUBLE); } @@ -72,7 +71,7 @@ public void testCreateFunctionFailed() assertPrestoException( () -> functionNamespaceManager.createFunction(FUNCTION_POWER_TOWER_DOUBLE_UPDATED, false), GENERIC_USER_ERROR, - ".*Function 'unittest.memory.power_tower' already exists"); + ".*Function 'unittest.memory.power_tower\\(double\\)' already exists"); } @Test @@ -93,21 +92,21 @@ public void testTransactionalGetFunction() // second transaction sees newly created function FunctionNamespaceTransactionHandle transaction2 = functionNamespaceManager.beginTransaction(); - Collection functions2 = functionNamespaceManager.getFunctions(Optional.of(transaction2), POWER_TOWER); + Collection functions2 = functionNamespaceManager.getFunctions(Optional.of(transaction2), POWER_TOWER); assertEquals(functions2.size(), 1); - assertEquals(getOnlyElement(functions2), versioned(FUNCTION_POWER_TOWER_DOUBLE, 1)); + assertEquals(getOnlyElement(functions2), FUNCTION_POWER_TOWER_DOUBLE.withVersion(1)); // update the function, second transaction still sees the old functions functionNamespaceManager.createFunction(FUNCTION_POWER_TOWER_DOUBLE_UPDATED, true); functions2 = functionNamespaceManager.getFunctions(Optional.of(transaction2), POWER_TOWER); assertEquals(functions2.size(), 1); - assertEquals(getOnlyElement(functions2), versioned(FUNCTION_POWER_TOWER_DOUBLE, 1)); + assertEquals(getOnlyElement(functions2), FUNCTION_POWER_TOWER_DOUBLE.withVersion(1)); // third transaction sees the updated function FunctionNamespaceTransactionHandle transaction3 = functionNamespaceManager.beginTransaction(); - Collection functions3 = functionNamespaceManager.getFunctions(Optional.of(transaction3), POWER_TOWER); + Collection functions3 = functionNamespaceManager.getFunctions(Optional.of(transaction3), POWER_TOWER); assertEquals(functions3.size(), 1); - assertEquals(getOnlyElement(functions3), versioned(FUNCTION_POWER_TOWER_DOUBLE_UPDATED, 2)); + assertEquals(getOnlyElement(functions3), FUNCTION_POWER_TOWER_DOUBLE_UPDATED.withVersion(2)); functionNamespaceManager.commit(transaction1); functionNamespaceManager.commit(transaction2); @@ -121,8 +120,8 @@ public void testCaching() functionNamespaceManager.createFunction(FUNCTION_POWER_TOWER_DOUBLE, false); // fetchFunctionsDirect does not produce the same function reference - SqlInvokedRegularFunction function1 = getOnlyElement(functionNamespaceManager.fetchFunctionsDirect(POWER_TOWER)); - SqlInvokedRegularFunction function2 = getOnlyElement(functionNamespaceManager.fetchFunctionsDirect(POWER_TOWER)); + SqlInvokedFunction function1 = getOnlyElement(functionNamespaceManager.fetchFunctionsDirect(POWER_TOWER)); + SqlInvokedFunction function2 = getOnlyElement(functionNamespaceManager.fetchFunctionsDirect(POWER_TOWER)); assertEquals(function1, function2); assertNotSame(function1, function2); @@ -141,8 +140,8 @@ public void testCaching() functionNamespaceManager.createFunction(FUNCTION_POWER_TOWER_INT, false); FunctionNamespaceTransactionHandle transaction1 = functionNamespaceManager.beginTransaction(); FunctionNamespaceTransactionHandle transaction2 = functionNamespaceManager.beginTransaction(); - Collection functions1 = functionNamespaceManager.getFunctions(Optional.of(transaction1), POWER_TOWER); - Collection functions2 = functionNamespaceManager.getFunctions(Optional.of(transaction2), POWER_TOWER); + Collection functions1 = functionNamespaceManager.getFunctions(Optional.of(transaction1), POWER_TOWER); + Collection functions2 = functionNamespaceManager.getFunctions(Optional.of(transaction2), POWER_TOWER); assertEquals(functions1.size(), 2); assertSame(functions1, functions2); } diff --git a/presto-main/src/test/java/com/facebook/presto/metadata/TestSignature.java b/presto-main/src/test/java/com/facebook/presto/metadata/TestSignature.java index 42b8d492f76bd..2117e81753c2e 100644 --- a/presto-main/src/test/java/com/facebook/presto/metadata/TestSignature.java +++ b/presto-main/src/test/java/com/facebook/presto/metadata/TestSignature.java @@ -16,8 +16,8 @@ import com.facebook.airlift.json.JsonCodec; import com.facebook.airlift.json.JsonCodecFactory; import com.facebook.airlift.json.ObjectMapperProvider; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.Type; import com.facebook.presto.type.TypeDeserializer; @@ -41,7 +41,7 @@ public void testSerializationRoundTrip() JsonCodec codec = new JsonCodecFactory(objectMapperProvider, true).jsonCodec(Signature.class); Signature expected = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "function"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "function"), SCALAR, parseTypeSignature(StandardTypes.BIGINT), ImmutableList.of(parseTypeSignature(StandardTypes.BOOLEAN), parseTypeSignature(StandardTypes.DOUBLE), parseTypeSignature(StandardTypes.VARCHAR))); diff --git a/presto-main/src/test/java/com/facebook/presto/operator/GenericLongFunction.java b/presto-main/src/test/java/com/facebook/presto/operator/GenericLongFunction.java index 06fda738af66f..4bbd8f694f337 100644 --- a/presto-main/src/test/java/com/facebook/presto/operator/GenericLongFunction.java +++ b/presto-main/src/test/java/com/facebook/presto/operator/GenericLongFunction.java @@ -17,8 +17,8 @@ import com.facebook.presto.metadata.FunctionManager; import com.facebook.presto.metadata.SqlScalarFunction; import com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.TypeManager; import com.google.common.collect.ImmutableList; @@ -45,7 +45,7 @@ public final class GenericLongFunction GenericLongFunction(String suffix, LongUnaryOperator longUnaryOperator) { - super(new Signature(FullyQualifiedName.of(DEFAULT_NAMESPACE, "generic_long_" + requireNonNull(suffix, "suffix is null")), SCALAR, + super(new Signature(QualifiedFunctionName.of(DEFAULT_NAMESPACE, "generic_long_" + requireNonNull(suffix, "suffix is null")), SCALAR, emptyList(), emptyList(), parseTypeSignature(BIGINT), singletonList(parseTypeSignature(BIGINT)), false)); this.longUnaryOperator = longUnaryOperator; } diff --git a/presto-main/src/test/java/com/facebook/presto/operator/TestAnnotationEngineForAggregates.java b/presto-main/src/test/java/com/facebook/presto/operator/TestAnnotationEngineForAggregates.java index 7940f8d492607..2f2ca4328bbc8 100644 --- a/presto-main/src/test/java/com/facebook/presto/operator/TestAnnotationEngineForAggregates.java +++ b/presto-main/src/test/java/com/facebook/presto/operator/TestAnnotationEngineForAggregates.java @@ -44,11 +44,11 @@ import com.facebook.presto.spi.function.LongVariableConstraint; import com.facebook.presto.spi.function.OperatorDependency; import com.facebook.presto.spi.function.OutputFunction; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; import com.facebook.presto.spi.function.SqlType; import com.facebook.presto.spi.function.TypeParameter; import com.facebook.presto.spi.function.TypeParameterSpecialization; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.DoubleType; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; @@ -111,7 +111,7 @@ public static void output(@AggregationState NullableDoubleState state, BlockBuil public void testSimpleExactAggregationParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "simple_exact_aggregate"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "simple_exact_aggregate"), FunctionKind.AGGREGATE, DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); @@ -163,7 +163,7 @@ public static void output(BlockBuilder out, @AggregationState NullableDoubleStat public void testStateOnDifferentThanFirstPositionAggregationParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "simple_exact_aggregate_aggregation_state_moved"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "simple_exact_aggregate_aggregation_state_moved"), FunctionKind.AGGREGATE, DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); @@ -306,7 +306,7 @@ public static AccumulatorStateSerializer createSerializer() public void testNotDecomposableAggregationParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "custom_decomposable_aggregate"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "custom_decomposable_aggregate"), FunctionKind.AGGREGATE, DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); @@ -381,7 +381,7 @@ public static void output( public void testSimpleGenericAggregationFunctionParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "simple_generic_implementations"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "simple_generic_implementations"), FunctionKind.AGGREGATE, ImmutableList.of(typeVariable("T")), ImmutableList.of(), @@ -457,7 +457,7 @@ public static void output( public void testSimpleBlockInputAggregationParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "block_input_aggregate"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "block_input_aggregate"), FunctionKind.AGGREGATE, DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); @@ -541,7 +541,7 @@ public static void output( public void testSimpleImplicitSpecializedAggregationParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "implicit_specialized_aggregate"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "implicit_specialized_aggregate"), FunctionKind.AGGREGATE, ImmutableList.of(typeVariable("T")), ImmutableList.of(), @@ -633,7 +633,7 @@ public static void output( public void testSimpleExplicitSpecializedAggregationParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "explicit_specialized_aggregate"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "explicit_specialized_aggregate"), FunctionKind.AGGREGATE, ImmutableList.of(typeVariable("T")), ImmutableList.of(), @@ -708,13 +708,13 @@ public static void output2( public void testMultiOutputAggregationParse() { Signature expectedSignature1 = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "multi_output_aggregate_1"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "multi_output_aggregate_1"), FunctionKind.AGGREGATE, DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); Signature expectedSignature2 = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "multi_output_aggregate_2"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "multi_output_aggregate_2"), FunctionKind.AGGREGATE, DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); @@ -794,7 +794,7 @@ public static CustomStateSerializerAggregationFunction.CustomSerializer createSe public void testInjectOperatorAggregateParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "inject_operator_aggregate"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "inject_operator_aggregate"), FunctionKind.AGGREGATE, DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); @@ -874,7 +874,7 @@ public static CustomStateSerializerAggregationFunction.CustomSerializer createSe public void testInjectTypeAggregateParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "inject_type_aggregate"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "inject_type_aggregate"), FunctionKind.AGGREGATE, ImmutableList.of(typeVariable("T")), ImmutableList.of(), @@ -958,7 +958,7 @@ public static CustomStateSerializerAggregationFunction.CustomSerializer createSe public void testInjectLiteralAggregateParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "inject_literal_aggregate"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "inject_literal_aggregate"), FunctionKind.AGGREGATE, parseTypeSignature("varchar(x)", ImmutableSet.of("x")), ImmutableList.of(parseTypeSignature("varchar(x)", ImmutableSet.of("x")))); @@ -1031,7 +1031,7 @@ public static void output( public void testLongConstraintAggregateFunctionParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "parametric_aggregate_long_constraint"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "parametric_aggregate_long_constraint"), FunctionKind.AGGREGATE, ImmutableList.of(), ImmutableList.of(new LongVariableConstraint("z", "x + y")), @@ -1108,7 +1108,7 @@ public static void output( public void testFixedTypeParameterInjectionAggregateFunctionParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "fixed_type_parameter_injection"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "fixed_type_parameter_injection"), FunctionKind.AGGREGATE, ImmutableList.of(), ImmutableList.of(), @@ -1174,7 +1174,7 @@ public static void output( public void testPartiallyFixedTypeParameterInjectionAggregateFunctionParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "partially_fixed_type_parameter_injection"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "partially_fixed_type_parameter_injection"), FunctionKind.AGGREGATE, ImmutableList.of(typeVariable("T1"), typeVariable("T2")), ImmutableList.of(), diff --git a/presto-main/src/test/java/com/facebook/presto/operator/TestAnnotationEngineForScalars.java b/presto-main/src/test/java/com/facebook/presto/operator/TestAnnotationEngineForScalars.java index 71b4998b92b80..74841b28c84eb 100644 --- a/presto-main/src/test/java/com/facebook/presto/operator/TestAnnotationEngineForScalars.java +++ b/presto-main/src/test/java/com/facebook/presto/operator/TestAnnotationEngineForScalars.java @@ -27,12 +27,12 @@ import com.facebook.presto.spi.function.FunctionKind; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.ScalarFunction; import com.facebook.presto.spi.function.Signature; import com.facebook.presto.spi.function.SqlNullable; import com.facebook.presto.spi.function.SqlType; import com.facebook.presto.spi.function.TypeParameter; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.Type; import com.facebook.presto.type.LiteralParameter; @@ -78,7 +78,7 @@ public static double fun(@SqlType(StandardTypes.DOUBLE) double v) public void testSingleImplementationScalarParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "single_implementation_parametric_scalar"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "single_implementation_parametric_scalar"), FunctionKind.SCALAR, DOUBLE.getTypeSignature(), ImmutableList.of(DOUBLE.getTypeSignature())); @@ -162,7 +162,7 @@ public static double fun( public void testWithNullablePrimitiveArgScalarParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "scalar_with_nullable"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "scalar_with_nullable"), FunctionKind.SCALAR, DOUBLE.getTypeSignature(), ImmutableList.of(DOUBLE.getTypeSignature(), DOUBLE.getTypeSignature())); @@ -200,7 +200,7 @@ public static double fun( public void testWithNullableComplexArgScalarParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "scalar_with_nullable_complex"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "scalar_with_nullable_complex"), FunctionKind.SCALAR, DOUBLE.getTypeSignature(), ImmutableList.of(DOUBLE.getTypeSignature(), DOUBLE.getTypeSignature())); @@ -236,7 +236,7 @@ public static double fun(@SqlType(StandardTypes.DOUBLE) double v) public void testStaticMethodScalarParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "static_method_scalar"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "static_method_scalar"), FunctionKind.SCALAR, DOUBLE.getTypeSignature(), ImmutableList.of(DOUBLE.getTypeSignature())); @@ -274,13 +274,13 @@ public static long fun2(@SqlType(StandardTypes.BIGINT) long v) public void testMultiScalarParse() { Signature expectedSignature1 = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "static_method_scalar_1"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "static_method_scalar_1"), FunctionKind.SCALAR, DOUBLE.getTypeSignature(), ImmutableList.of(DOUBLE.getTypeSignature())); Signature expectedSignature2 = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "static_method_scalar_2"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "static_method_scalar_2"), FunctionKind.SCALAR, BIGINT.getTypeSignature(), ImmutableList.of(BIGINT.getTypeSignature())); @@ -327,7 +327,7 @@ public static long fun(@SqlType("T") long v) public void testParametricScalarParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "parametric_scalar"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "parametric_scalar"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T")), ImmutableList.of(), @@ -368,7 +368,7 @@ public static boolean fun2(@SqlType("array(varchar(17))") Block array) public void testComplexParametricScalarParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "with_exact_scalar"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "with_exact_scalar"), FunctionKind.SCALAR, ImmutableList.of(), ImmutableList.of(), @@ -377,7 +377,7 @@ public void testComplexParametricScalarParse() false); Signature exactSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "with_exact_scalar"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "with_exact_scalar"), FunctionKind.SCALAR, ImmutableList.of(), ImmutableList.of(), @@ -415,7 +415,7 @@ public static long fun( public void testSimpleInjectionScalarParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "parametric_scalar_inject"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "parametric_scalar_inject"), FunctionKind.SCALAR, ImmutableList.of(), ImmutableList.of(), @@ -475,7 +475,7 @@ public long funDouble(@SqlType("array(double)") Block val) public void testConstructorInjectionScalarParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "parametric_scalar_inject_constructor"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "parametric_scalar_inject_constructor"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T")), ImmutableList.of(), @@ -518,7 +518,7 @@ public static long fun( public void testFixedTypeParameterParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "fixed_type_parameter_scalar_function"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "fixed_type_parameter_scalar_function"), FunctionKind.SCALAR, ImmutableList.of(), ImmutableList.of(), @@ -556,7 +556,7 @@ public static long fun( public void testPartiallyFixedTypeParameterParse() { Signature expectedSignature = new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "partially_fixed_type_parameter_scalar_function"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "partially_fixed_type_parameter_scalar_function"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T1"), typeVariable("T2")), ImmutableList.of(), diff --git a/presto-main/src/test/java/com/facebook/presto/operator/scalar/AbstractTestFunctions.java b/presto-main/src/test/java/com/facebook/presto/operator/scalar/AbstractTestFunctions.java index 8db7cbe13e4f9..ccaa6ba6a1934 100644 --- a/presto-main/src/test/java/com/facebook/presto/operator/scalar/AbstractTestFunctions.java +++ b/presto-main/src/test/java/com/facebook/presto/operator/scalar/AbstractTestFunctions.java @@ -97,7 +97,7 @@ protected void assertFunction(String projection, Type expectedType, Object expec protected void assertOperator(OperatorType operator, String value, Type expectedType, Object expected) { - functionAssertions.assertFunction(format("\"%s\"(%s)", operator.getFunctionName().getSuffix(), value), expectedType, expected); + functionAssertions.assertFunction(format("\"%s\"(%s)", operator.getFunctionName().getFunctionName(), value), expectedType, expected); } protected void assertDecimalFunction(String statement, SqlDecimal expectedResult) diff --git a/presto-main/src/test/java/com/facebook/presto/operator/scalar/BenchmarkArrayFilter.java b/presto-main/src/test/java/com/facebook/presto/operator/scalar/BenchmarkArrayFilter.java index 260b290b54c84..60728c9036f3a 100644 --- a/presto-main/src/test/java/com/facebook/presto/operator/scalar/BenchmarkArrayFilter.java +++ b/presto-main/src/test/java/com/facebook/presto/operator/scalar/BenchmarkArrayFilter.java @@ -25,9 +25,9 @@ import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionHandle; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; import com.facebook.presto.spi.relation.CallExpression; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.relation.LambdaDefinitionExpression; import com.facebook.presto.spi.relation.RowExpression; import com.facebook.presto.spi.relation.VariableReferenceExpression; @@ -203,7 +203,7 @@ public static final class ExactArrayFilterFunction private ExactArrayFilterFunction() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "exact_filter"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "exact_filter"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T")), ImmutableList.of(), diff --git a/presto-main/src/test/java/com/facebook/presto/operator/scalar/BenchmarkArrayHashCodeOperator.java b/presto-main/src/test/java/com/facebook/presto/operator/scalar/BenchmarkArrayHashCodeOperator.java index 04e9d8a90895e..51e340f0f2974 100644 --- a/presto-main/src/test/java/com/facebook/presto/operator/scalar/BenchmarkArrayHashCodeOperator.java +++ b/presto-main/src/test/java/com/facebook/presto/operator/scalar/BenchmarkArrayHashCodeOperator.java @@ -104,7 +104,7 @@ public List> arrayHashCode(BenchmarkData data) public static class BenchmarkData { @Param({"$operator$hash_code", "old_hash", "another_hash"}) - private String name = HASH_CODE.getFunctionName().getSuffix(); + private String name = HASH_CODE.getFunctionName().getFunctionName(); @Param({"BIGINT", "VARCHAR", "DOUBLE", "BOOLEAN"}) private String type = "BIGINT"; diff --git a/presto-main/src/test/java/com/facebook/presto/operator/scalar/TestProvidedBlockBuilderReturnPlaceConvention.java b/presto-main/src/test/java/com/facebook/presto/operator/scalar/TestProvidedBlockBuilderReturnPlaceConvention.java index 8a8b33c47beb4..69bc83c23b345 100644 --- a/presto-main/src/test/java/com/facebook/presto/operator/scalar/TestProvidedBlockBuilderReturnPlaceConvention.java +++ b/presto-main/src/test/java/com/facebook/presto/operator/scalar/TestProvidedBlockBuilderReturnPlaceConvention.java @@ -21,8 +21,8 @@ import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.block.BlockBuilder; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.ArrayType; import com.facebook.presto.spi.type.Type; import com.facebook.presto.spi.type.TypeManager; @@ -155,7 +155,7 @@ public static class FunctionWithProvidedBlockReturnPlaceConvention1 protected FunctionWithProvidedBlockReturnPlaceConvention1() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "identity1"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "identity1"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T")), ImmutableList.of(), @@ -275,7 +275,7 @@ public static class FunctionWithProvidedBlockReturnPlaceConvention2 protected FunctionWithProvidedBlockReturnPlaceConvention2() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "identity2"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "identity2"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("T")), ImmutableList.of(), diff --git a/presto-main/src/test/java/com/facebook/presto/sql/gen/TestVarArgsToArrayAdapterGenerator.java b/presto-main/src/test/java/com/facebook/presto/sql/gen/TestVarArgsToArrayAdapterGenerator.java index 5199ba101c3a1..706a0a227f1e1 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/gen/TestVarArgsToArrayAdapterGenerator.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/gen/TestVarArgsToArrayAdapterGenerator.java @@ -20,8 +20,8 @@ import com.facebook.presto.operator.scalar.AbstractTestFunctions; import com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.TypeManager; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; @@ -79,7 +79,7 @@ public static class TestVarArgsSum private TestVarArgsSum() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "var_args_sum"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "var_args_sum"), FunctionKind.SCALAR, ImmutableList.of(), ImmutableList.of(), diff --git a/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionEqualityInference.java b/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionEqualityInference.java index e3ecd9eba3b7a..22ab85dc3bf8f 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionEqualityInference.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionEqualityInference.java @@ -481,7 +481,7 @@ private static Set setCopy(Iterable elements) private static CallExpression compare(OperatorType type, RowExpression left, RowExpression right) { return call( - type.getFunctionName().getSuffix(), + type.getFunctionName().getFunctionName(), METADATA.getFunctionManager().resolveOperator(type, fromTypes(left.getType(), right.getType())), BOOLEAN, left, @@ -503,7 +503,7 @@ private static RowExpression getRight(RowExpression expression) private static CallExpression arithmeticOperation(OperatorType type, RowExpression left, RowExpression right) { return call( - type.getFunctionName().getSuffix(), + type.getFunctionName().getFunctionName(), METADATA.getFunctionManager().resolveOperator(type, fromTypes(left.getType(), right.getType())), left.getType(), left, diff --git a/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionPredicateExtractor.java b/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionPredicateExtractor.java index 80cf869825b77..5ba572b7848ab 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionPredicateExtractor.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionPredicateExtractor.java @@ -755,7 +755,7 @@ private RowExpression greaterThan(RowExpression expression1, RowExpression expre private RowExpression compare(OperatorType type, RowExpression left, RowExpression right) { return call( - type.getFunctionName().getSuffix(), + type.getFunctionName().getFunctionName(), metadata.getFunctionManager().resolveOperator(type, fromTypes(left.getType(), right.getType())), BOOLEAN, left, diff --git a/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionVariableInliner.java b/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionVariableInliner.java index 408ac5585ff15..8bacb88ed8502 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionVariableInliner.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/planner/TestRowExpressionVariableInliner.java @@ -13,9 +13,10 @@ */ package com.facebook.presto.sql.planner; +import com.facebook.presto.spi.CatalogSchemaName; import com.facebook.presto.spi.function.FunctionHandle; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.relation.CallExpression; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.relation.LambdaDefinitionExpression; import com.facebook.presto.spi.relation.VariableReferenceExpression; import com.google.common.collect.ImmutableList; @@ -31,9 +32,9 @@ private static class TestFunctionHandle implements FunctionHandle { @Override - public FullyQualifiedName.Prefix getFunctionNamespace() + public CatalogSchemaName getFunctionNamespace() { - return FullyQualifiedName.of("a.b.c").getPrefix(); + return QualifiedFunctionName.of("a.b.c").getFunctionNamespace(); } } diff --git a/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/AggregationFunctionMatcher.java b/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/AggregationFunctionMatcher.java index fecb957f14fa2..5b1bbc0ee676e 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/AggregationFunctionMatcher.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/AggregationFunctionMatcher.java @@ -71,7 +71,7 @@ public Optional getAssignedVariable(PlanNode node, private static boolean verifyAggregation(FunctionManager functionManager, Aggregation aggregation, FunctionCall expectedCall) { - return functionManager.getFunctionMetadata(aggregation.getFunctionHandle()).getName().getSuffix().equalsIgnoreCase(expectedCall.getName().getSuffix()) && + return functionManager.getFunctionMetadata(aggregation.getFunctionHandle()).getName().getFunctionName().equalsIgnoreCase(expectedCall.getName().getSuffix()) && aggregation.getArguments().size() == expectedCall.getArguments().size() && Streams.zip( aggregation.getArguments().stream(), diff --git a/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/RowExpressionVerifier.java b/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/RowExpressionVerifier.java index 7523539e2206c..c174fe18a7994 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/RowExpressionVerifier.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/RowExpressionVerifier.java @@ -483,7 +483,7 @@ protected Boolean visitFunctionCall(FunctionCall expected, RowExpression actual) } CallExpression actualFunction = (CallExpression) actual; - if (!expected.getName().getSuffix().equals(metadata.getFunctionManager().getFunctionMetadata(actualFunction.getFunctionHandle()).getName().getSuffix())) { + if (!expected.getName().getSuffix().equals(metadata.getFunctionManager().getFunctionMetadata(actualFunction.getFunctionHandle()).getName().getFunctionName())) { return false; } diff --git a/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/WindowFunctionMatcher.java b/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/WindowFunctionMatcher.java index b9e4a3d452abc..a60c914057de2 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/WindowFunctionMatcher.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/planner/assertions/WindowFunctionMatcher.java @@ -74,7 +74,7 @@ public Optional getAssignedVariable(PlanNode node, List matchedOutputs = windowNode.getWindowFunctions().entrySet().stream() .filter(assignment -> { - if (!expectedCall.getName().equals(QualifiedName.of(metadata.getFunctionManager().getFunctionMetadata(assignment.getValue().getFunctionCall().getFunctionHandle()).getName().getSuffix()))) { + if (!expectedCall.getName().equals(QualifiedName.of(metadata.getFunctionManager().getFunctionMetadata(assignment.getValue().getFunctionCall().getFunctionHandle()).getName().getFunctionName()))) { return false; } if (!functionHandle.map(assignment.getValue().getFunctionHandle()::equals).orElse(true)) { diff --git a/presto-orc/src/test/java/com/facebook/presto/orc/TestTupleDomainFilterUtils.java b/presto-orc/src/test/java/com/facebook/presto/orc/TestTupleDomainFilterUtils.java index 4509f5b3dadbb..154d01932db53 100644 --- a/presto-orc/src/test/java/com/facebook/presto/orc/TestTupleDomainFilterUtils.java +++ b/presto-orc/src/test/java/com/facebook/presto/orc/TestTupleDomainFilterUtils.java @@ -557,7 +557,7 @@ private static Expression cast(Expression expression, Type type) private static FunctionCall colorLiteral(long value) { - return new FunctionCall(QualifiedName.of(getMagicLiteralFunctionSignature(COLOR).getName().getParts()), ImmutableList.of(bigintLiteral(value))); + return new FunctionCall(QualifiedName.of(getMagicLiteralFunctionSignature(COLOR).getName().getFunctionName()), ImmutableList.of(bigintLiteral(value))); } private Expression varbinaryLiteral(Slice value) diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/CatalogSchemaName.java b/presto-spi/src/main/java/com/facebook/presto/spi/CatalogSchemaName.java index b96897b5ddbfa..78c3de9e4b60d 100644 --- a/presto-spi/src/main/java/com/facebook/presto/spi/CatalogSchemaName.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/CatalogSchemaName.java @@ -13,7 +13,10 @@ */ package com.facebook.presto.spi; +import com.facebook.presto.spi.function.CatalogSchemaPrefix; + import java.util.Objects; +import java.util.Optional; import static java.util.Locale.ENGLISH; import static java.util.Objects.requireNonNull; @@ -39,6 +42,11 @@ public String getSchemaName() return schemaName; } + public CatalogSchemaPrefix asCatalogSchemaPrefix() + { + return new CatalogSchemaPrefix(catalogName, Optional.of(schemaName)); + } + @Override public boolean equals(Object obj) { diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/function/CatalogSchemaPrefix.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/CatalogSchemaPrefix.java new file mode 100644 index 0000000000000..4d9c69b4229a5 --- /dev/null +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/CatalogSchemaPrefix.java @@ -0,0 +1,90 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.facebook.presto.spi.function; + +import com.facebook.presto.spi.CatalogSchemaName; + +import java.util.Objects; +import java.util.Optional; + +import static java.util.Objects.requireNonNull; + +public class CatalogSchemaPrefix +{ + private final String catalogName; + private final Optional schemaName; + + public CatalogSchemaPrefix(String catalogName, Optional schemaName) + { + this.catalogName = requireNonNull(catalogName, "catalogName is null"); + this.schemaName = requireNonNull(schemaName, "schemaName is null"); + } + + public static CatalogSchemaPrefix of(String prefix) + { + String[] parts = prefix.split("\\."); + if (parts.length != 1 && parts.length != 2) { + throw new IllegalArgumentException("CatalogSchemaPrefix should have 1 or 2 parts"); + } + return parts.length == 1 ? new CatalogSchemaPrefix(parts[0], Optional.empty()) : new CatalogSchemaPrefix(parts[0], Optional.of(parts[1])); + } + + public String getCatalogName() + { + return catalogName; + } + + public Optional getSchemaName() + { + return schemaName; + } + + public boolean includes(CatalogSchemaName catalogSchemaName) + { + return catalogName.equals(catalogSchemaName.getCatalogName()) + && (!schemaName.isPresent() || schemaName.get().equals(catalogSchemaName.getSchemaName())); + } + + public boolean includes(CatalogSchemaPrefix that) + { + return catalogName.equals(that.getCatalogName()) + && (!schemaName.isPresent() || (that.schemaName.isPresent() && schemaName.get().equals(that.schemaName.get()))); + } + + @Override + public boolean equals(Object o) + { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CatalogSchemaPrefix that = (CatalogSchemaPrefix) o; + return Objects.equals(catalogName, that.catalogName) && + Objects.equals(schemaName, that.schemaName); + } + + @Override + public int hashCode() + { + return Objects.hash(catalogName, schemaName); + } + + @Override + public String toString() + { + return catalogName + (schemaName.map(name -> "." + name).orElse("")); + } +} diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionHandle.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionHandle.java index 82fed7c05122d..600cc20e08f29 100644 --- a/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionHandle.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionHandle.java @@ -13,8 +13,8 @@ */ package com.facebook.presto.spi.function; +import com.facebook.presto.spi.CatalogSchemaName; import com.facebook.presto.spi.api.Experimental; -import com.facebook.presto.spi.relation.FullyQualifiedName; /** * FunctionHandle is a unique handle to identify the function implementation from namespaces. @@ -23,5 +23,5 @@ @Experimental public interface FunctionHandle { - FullyQualifiedName.Prefix getFunctionNamespace(); + CatalogSchemaName getFunctionNamespace(); } diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionMetadata.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionMetadata.java index cf400ff2d7c31..a9f7b3460d4ab 100644 --- a/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionMetadata.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionMetadata.java @@ -13,7 +13,6 @@ */ package com.facebook.presto.spi.function; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.TypeSignature; import java.util.ArrayList; @@ -26,7 +25,7 @@ public class FunctionMetadata { - private final FullyQualifiedName name; + private final QualifiedFunctionName name; private final Optional operatorType; private final List argumentTypes; private final Optional> argumentNames; @@ -37,7 +36,7 @@ public class FunctionMetadata private final boolean calledOnNullInput; public FunctionMetadata( - FullyQualifiedName name, + QualifiedFunctionName name, List argumentTypes, TypeSignature returnType, FunctionKind functionKind, @@ -49,7 +48,7 @@ public FunctionMetadata( } public FunctionMetadata( - FullyQualifiedName name, + QualifiedFunctionName name, List argumentTypes, List argumentNames, TypeSignature returnType, @@ -74,7 +73,7 @@ public FunctionMetadata( } private FunctionMetadata( - FullyQualifiedName name, + QualifiedFunctionName name, Optional operatorType, List argumentTypes, Optional> argumentNames, @@ -100,7 +99,7 @@ public FunctionKind getFunctionKind() return functionKind; } - public FullyQualifiedName getName() + public QualifiedFunctionName getName() { return name; } diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionNamespaceManager.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionNamespaceManager.java index f8afbffd13400..ad0740f2f29bb 100644 --- a/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionNamespaceManager.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/FunctionNamespaceManager.java @@ -14,7 +14,6 @@ package com.facebook.presto.spi.function; import com.facebook.presto.spi.api.Experimental; -import com.facebook.presto.spi.relation.FullyQualifiedName; import java.util.Collection; import java.util.Optional; @@ -31,7 +30,7 @@ public interface FunctionNamespaceManager /** * Commit the transaction. Will be called at most once and will not be called if - * {@link #rollback(FunctionNamespaceTransactionHandle)} is called. + * {@link #abort(FunctionNamespaceTransactionHandle)} is called. */ void commit(FunctionNamespaceTransactionHandle transactionHandle); @@ -39,13 +38,13 @@ public interface FunctionNamespaceManager * Rollback the transaction. Will be called at most once and will not be called if * {@link #commit(FunctionNamespaceTransactionHandle)} is called. */ - void rollback(FunctionNamespaceTransactionHandle transactionHandle); + void abort(FunctionNamespaceTransactionHandle transactionHandle); /** * Create or replace the specified function. * TODO: Support transaction */ - void createFunction(F function, boolean replace); + void createFunction(SqlInvokedFunction function, boolean replace); /** * List all functions managed by the {@link FunctionNamespaceManager}. @@ -53,7 +52,7 @@ public interface FunctionNamespaceManager */ Collection listFunctions(); - Collection getFunctions(Optional transactionHandle, FullyQualifiedName functionName); + Collection getFunctions(Optional transactionHandle, QualifiedFunctionName functionName); FunctionHandle getFunctionHandle(Optional transactionHandle, Signature signature); diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/function/OperatorType.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/OperatorType.java index 38cf779486b16..65ed2d60c6824 100644 --- a/presto-spi/src/main/java/com/facebook/presto/spi/function/OperatorType.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/OperatorType.java @@ -13,8 +13,6 @@ */ package com.facebook.presto.spi.function; -import com.facebook.presto.spi.relation.FullyQualifiedName; - import java.util.Arrays; import java.util.Map; import java.util.Optional; @@ -45,16 +43,16 @@ public enum OperatorType XX_HASH_64("XX HASH 64", false), INDETERMINATE("INDETERMINATE", true); - private static final Map OPERATOR_TYPES = Arrays.stream(OperatorType.values()).collect(toMap(OperatorType::getFunctionName, Function.identity())); + private static final Map OPERATOR_TYPES = Arrays.stream(OperatorType.values()).collect(toMap(OperatorType::getFunctionName, Function.identity())); private final String operator; - private final FullyQualifiedName functionName; + private final QualifiedFunctionName functionName; private final boolean calledOnNullInput; OperatorType(String operator, boolean calledOnNullInput) { this.operator = operator; - this.functionName = FullyQualifiedName.of("presto.default.$operator$" + name()); + this.functionName = QualifiedFunctionName.of("presto.default.$operator$" + name()); this.calledOnNullInput = calledOnNullInput; } @@ -63,7 +61,7 @@ public String getOperator() return operator; } - public FullyQualifiedName getFunctionName() + public QualifiedFunctionName getFunctionName() { return functionName; } @@ -73,7 +71,7 @@ public boolean isCalledOnNullInput() return calledOnNullInput; } - public static Optional tryGetOperatorType(FullyQualifiedName operatorName) + public static Optional tryGetOperatorType(QualifiedFunctionName operatorName) { return Optional.ofNullable(OPERATOR_TYPES.get(operatorName)); } diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/function/QualifiedFunctionName.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/QualifiedFunctionName.java new file mode 100644 index 0000000000000..1804d6fbe9e8e --- /dev/null +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/QualifiedFunctionName.java @@ -0,0 +1,88 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.facebook.presto.spi.function; + +import com.facebook.presto.spi.CatalogSchemaName; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Objects; + +import static java.util.Locale.ENGLISH; +import static java.util.Objects.requireNonNull; + +public class QualifiedFunctionName +{ + private final CatalogSchemaName functionNamespace; + private final String functionName; + + private QualifiedFunctionName(CatalogSchemaName functionNamespace, String functionName) + { + this.functionNamespace = requireNonNull(functionNamespace, "functionNamespace is null"); + this.functionName = requireNonNull(functionName, "name is null").toLowerCase(ENGLISH); + } + + @JsonCreator + public static QualifiedFunctionName of(String dottedName) + { + String[] parts = dottedName.split("\\."); + if (parts.length != 3) { + throw new IllegalArgumentException("QualifiedFunctionName should have exactly 3 parts"); + } + return of(new CatalogSchemaName(parts[0], parts[1]), parts[2]); + } + + public static QualifiedFunctionName of(CatalogSchemaName functionNamespace, String name) + { + return new QualifiedFunctionName(functionNamespace, name); + } + + public CatalogSchemaName getFunctionNamespace() + { + return functionNamespace; + } + + // TODO: Examine all callers to limit the usage of the method + public String getFunctionName() + { + return functionName; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + QualifiedFunctionName o = (QualifiedFunctionName) obj; + return Objects.equals(functionNamespace, o.functionNamespace) && + Objects.equals(functionName, o.functionName); + } + + @Override + public int hashCode() + { + return Objects.hash(functionNamespace, functionName); + } + + @JsonValue + @Override + public String toString() + { + return functionNamespace + "." + functionName; + } +} diff --git a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/RoutineCharacteristics.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/RoutineCharacteristics.java similarity index 90% rename from presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/RoutineCharacteristics.java rename to presto-spi/src/main/java/com/facebook/presto/spi/function/RoutineCharacteristics.java index 64a6540d1a3b3..67f78341d55bb 100644 --- a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/RoutineCharacteristics.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/RoutineCharacteristics.java @@ -11,12 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.facebook.presto.sqlfunction; +package com.facebook.presto.spi.function; import java.util.Objects; -import static com.facebook.presto.sqlfunction.RoutineCharacteristics.Determinism.DETERMINISTIC; -import static com.facebook.presto.sqlfunction.RoutineCharacteristics.NullCallClause.CALLED_ON_NULL_INPUT; +import static com.facebook.presto.spi.function.RoutineCharacteristics.Determinism.DETERMINISTIC; +import static com.facebook.presto.spi.function.RoutineCharacteristics.NullCallClause.CALLED_ON_NULL_INPUT; import static java.lang.String.format; import static java.util.Objects.requireNonNull; diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/function/Signature.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/Signature.java index 4bba5bf204db4..8564b2bd44f32 100644 --- a/presto-spi/src/main/java/com/facebook/presto/spi/function/Signature.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/Signature.java @@ -13,7 +13,6 @@ */ package com.facebook.presto.spi.function; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.TypeSignature; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -31,7 +30,7 @@ public final class Signature { - private final FullyQualifiedName name; + private final QualifiedFunctionName name; private final FunctionKind kind; private final List typeVariableConstraints; private final List longVariableConstraints; @@ -41,7 +40,7 @@ public final class Signature @JsonCreator public Signature( - @JsonProperty("name") FullyQualifiedName name, + @JsonProperty("name") QualifiedFunctionName name, @JsonProperty("kind") FunctionKind kind, @JsonProperty("typeVariableConstraints") List typeVariableConstraints, @JsonProperty("longVariableConstraints") List longVariableConstraints, @@ -62,25 +61,25 @@ public Signature( this.variableArity = variableArity; } - public Signature(FullyQualifiedName name, FunctionKind kind, TypeSignature returnType, TypeSignature... argumentTypes) + public Signature(QualifiedFunctionName name, FunctionKind kind, TypeSignature returnType, TypeSignature... argumentTypes) { this(name, kind, returnType, unmodifiableList(Arrays.asList(argumentTypes))); } - public Signature(FullyQualifiedName name, FunctionKind kind, TypeSignature returnType, List argumentTypes) + public Signature(QualifiedFunctionName name, FunctionKind kind, TypeSignature returnType, List argumentTypes) { this(name, kind, emptyList(), emptyList(), returnType, argumentTypes, false); } @JsonProperty - public FullyQualifiedName getName() + public QualifiedFunctionName getName() { return name; } public String getNameSuffix() { - return name.getSuffix(); + return name.getFunctionName(); } @JsonProperty diff --git a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlInvokedRegularFunctionHandle.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/SqlFunctionHandle.java similarity index 50% rename from presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlInvokedRegularFunctionHandle.java rename to presto-spi/src/main/java/com/facebook/presto/spi/function/SqlFunctionHandle.java index b505aa385c2f6..e7e26b1627779 100644 --- a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlInvokedRegularFunctionHandle.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/SqlFunctionHandle.java @@ -11,48 +11,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.facebook.presto.sqlfunction; +package com.facebook.presto.spi.function; -import com.facebook.presto.spi.function.FunctionHandle; -import com.facebook.presto.spi.relation.FullyQualifiedName; -import com.facebook.presto.spi.type.TypeSignature; +import com.facebook.presto.spi.CatalogSchemaName; +import com.facebook.presto.spi.api.Experimental; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; import java.util.Objects; import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.joining; -public class SqlInvokedRegularFunctionHandle +@Experimental +public class SqlFunctionHandle implements FunctionHandle { - private final FullyQualifiedName name; - private final List argumentTypes; + private final SqlFunctionId functionId; private final long version; @JsonCreator - public SqlInvokedRegularFunctionHandle( - @JsonProperty("name") FullyQualifiedName name, - @JsonProperty("argumentTypes") List argumentTypes, + public SqlFunctionHandle( + @JsonProperty("functionId") SqlFunctionId functionId, @JsonProperty("version") long version) { - this.name = requireNonNull(name, "name is null"); - this.argumentTypes = requireNonNull(argumentTypes, "argumentTypes is null"); + this.functionId = requireNonNull(functionId, "functionId is null"); this.version = version; } @JsonProperty - public FullyQualifiedName getName() + public SqlFunctionId getFunctionId() { - return name; - } - - @JsonProperty - public List getArgumentTypes() - { - return argumentTypes; + return functionId; } @JsonProperty @@ -62,9 +51,9 @@ public long getVersion() } @Override - public FullyQualifiedName.Prefix getFunctionNamespace() + public CatalogSchemaName getFunctionNamespace() { - return name.getPrefix(); + return functionId.getFunctionName().getFunctionNamespace(); } @Override @@ -76,24 +65,30 @@ public boolean equals(Object obj) if (obj == null || getClass() != obj.getClass()) { return false; } - SqlInvokedRegularFunctionHandle o = (SqlInvokedRegularFunctionHandle) obj; - return Objects.equals(name, o.name) - && Objects.equals(argumentTypes, o.argumentTypes) + SqlFunctionHandle o = (SqlFunctionHandle) obj; + return Objects.equals(functionId, o.functionId) && Objects.equals(version, o.version); } @Override public int hashCode() { - return Objects.hash(name, argumentTypes, version); + return Objects.hash(functionId, version); } @Override public String toString() { - String arguments = argumentTypes.stream() - .map(Object::toString) - .collect(joining(", ")); - return String.format("%s(%s):%s", name, arguments, version); + return String.format("%s:%s", functionId, version); + } + + public static class Resolver + implements FunctionHandleResolver + { + @Override + public Class getFunctionHandleClass() + { + return SqlFunctionHandle.class; + } } } diff --git a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlFunctionId.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/SqlFunctionId.java similarity index 74% rename from presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlFunctionId.java rename to presto-spi/src/main/java/com/facebook/presto/spi/function/SqlFunctionId.java index 5d03ec25e07ef..ae5fb64246c61 100644 --- a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlFunctionId.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/SqlFunctionId.java @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.facebook.presto.sqlfunction; +package com.facebook.presto.spi.function; -import com.facebook.presto.spi.relation.FullyQualifiedName; +import com.facebook.presto.spi.api.Experimental; import com.facebook.presto.spi.type.TypeSignature; import java.util.List; @@ -23,22 +23,23 @@ import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.joining; +@Experimental public class SqlFunctionId { - private final FullyQualifiedName name; + private final QualifiedFunctionName functionName; private final List argumentTypes; public SqlFunctionId( - FullyQualifiedName name, + QualifiedFunctionName functionName, List argumentTypes) { - this.name = requireNonNull(name, "name is null"); + this.functionName = requireNonNull(functionName, "functionName is null"); this.argumentTypes = requireNonNull(argumentTypes, "argumentTypes is null"); } - public FullyQualifiedName getName() + public QualifiedFunctionName getFunctionName() { - return name; + return functionName; } public List getArgumentTypes() @@ -46,6 +47,11 @@ public List getArgumentTypes() return argumentTypes; } + public String getId() + { + return toString(); + } + @Override public boolean equals(Object obj) { @@ -56,14 +62,14 @@ public boolean equals(Object obj) return false; } SqlFunctionId o = (SqlFunctionId) obj; - return Objects.equals(name, o.name) + return Objects.equals(functionName, o.functionName) && Objects.equals(argumentTypes, o.argumentTypes); } @Override public int hashCode() { - return Objects.hash(name, argumentTypes); + return Objects.hash(functionName, argumentTypes); } @Override @@ -72,6 +78,6 @@ public String toString() String arguments = argumentTypes.stream() .map(Object::toString) .collect(joining(", ")); - return format("%s(%s)", name, arguments); + return format("%s(%s)", functionName, arguments); } } diff --git a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlInvokedRegularFunction.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/SqlInvokedFunction.java similarity index 62% rename from presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlInvokedRegularFunction.java rename to presto-spi/src/main/java/com/facebook/presto/spi/function/SqlInvokedFunction.java index 131d371bf4939..9f0405c4d5f5b 100644 --- a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlInvokedRegularFunction.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/SqlInvokedFunction.java @@ -11,55 +11,47 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.facebook.presto.sqlfunction; +package com.facebook.presto.spi.function; -import com.facebook.presto.spi.function.FunctionImplementationType; -import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.function.SqlFunction; -import com.facebook.presto.spi.relation.FullyQualifiedName; +import com.facebook.presto.spi.api.Experimental; import com.facebook.presto.spi.type.TypeSignature; -import com.google.common.collect.ImmutableMap; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; import static com.facebook.presto.spi.function.FunctionKind.SCALAR; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.ImmutableList.toImmutableList; import static java.lang.String.format; import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; -public class SqlInvokedRegularFunction +@Experimental +public class SqlInvokedFunction implements SqlFunction { - private static final Map LANGUAGE_TO_IMPLEMENTATION_MAP = ImmutableMap.of(RoutineCharacteristics.Language.SQL, FunctionImplementationType.SQL); - private final List parameters; - private final Optional comment; + private final String description; private final RoutineCharacteristics routineCharacteristics; private final String body; private final Signature signature; private final SqlFunctionId functionId; - private final Optional functionHandle; + private final Optional functionHandle; - public SqlInvokedRegularFunction( - FullyQualifiedName functionName, + public SqlInvokedFunction( + QualifiedFunctionName functionName, List parameters, TypeSignature returnType, - Optional comment, + String description, RoutineCharacteristics routineCharacteristics, String body, Optional version) { this.parameters = requireNonNull(parameters, "parameters is null"); - this.comment = requireNonNull(comment, "comment is null"); + this.description = requireNonNull(description, "description is null"); this.routineCharacteristics = requireNonNull(routineCharacteristics, "routineCharacteristics is null"); this.body = requireNonNull(body, "body is null"); @@ -68,21 +60,21 @@ public SqlInvokedRegularFunction( .collect(collectingAndThen(toList(), Collections::unmodifiableList)); this.signature = new Signature(functionName, SCALAR, returnType, argumentTypes); this.functionId = new SqlFunctionId(functionName, argumentTypes); - this.functionHandle = version.map(v -> new SqlInvokedRegularFunctionHandle(functionName, argumentTypes, v)); + this.functionHandle = version.map(v -> new SqlFunctionHandle(this.functionId, v)); } - public static SqlInvokedRegularFunction versioned(SqlInvokedRegularFunction function, long version) + public SqlInvokedFunction withVersion(long version) { - if (function.getVersion().isPresent()) { - throw new IllegalArgumentException(format("function %s is already versioned", function.getVersion().get())); + if (getVersion().isPresent()) { + throw new IllegalArgumentException(format("function %s is already with version %s", signature.getName(), getVersion().get())); } - return new SqlInvokedRegularFunction( - function.getSignature().getName(), - function.getParameters(), - function.getSignature().getReturnType(), - function.comment, - function.getRoutineCharacteristics(), - function.getBody(), + return new SqlInvokedFunction( + signature.getName(), + parameters, + signature.getReturnType(), + description, + routineCharacteristics, + body, Optional.of(version)); } @@ -113,7 +105,7 @@ public boolean isCalledOnNullInput() @Override public String getDescription() { - return comment.orElse(""); + return description; } public List getParameters() @@ -121,46 +113,52 @@ public List getParameters() return parameters; } - public List getParameterNames() + public RoutineCharacteristics getRoutineCharacteristics() { - return parameters.stream().map(SqlParameter::getName).collect(toImmutableList()); + return routineCharacteristics; } - public Optional getComment() + public String getBody() { - return comment; + return body; } - public RoutineCharacteristics getRoutineCharacteristics() + public SqlFunctionId getFunctionId() { - return routineCharacteristics; + return functionId; } - public FunctionImplementationType getFunctionImplementationType() + public Optional getFunctionHandle() { - checkState(LANGUAGE_TO_IMPLEMENTATION_MAP.containsKey(routineCharacteristics.getLanguage()), "Language is not supported: %s", routineCharacteristics.getLanguage()); - return LANGUAGE_TO_IMPLEMENTATION_MAP.get(routineCharacteristics.getLanguage()); + return functionHandle; } - public String getBody() + public Optional getVersion() { - return body; + return functionHandle.map(SqlFunctionHandle::getVersion); } - public SqlFunctionId getFunctionId() + public FunctionImplementationType getFunctionImplementationType() { - return functionId; + return FunctionImplementationType.SQL; } - public SqlInvokedRegularFunctionHandle getRequiredFunctionHandle() + public SqlFunctionHandle getRequiredFunctionHandle() { - checkState(functionHandle.isPresent(), "missing function handle"); + Optional functionHandle = getFunctionHandle(); + if (!functionHandle.isPresent()) { + throw new IllegalStateException("missing functionHandle"); + } return functionHandle.get(); } - public Optional getVersion() + public long getRequiredVersion() { - return functionHandle.map(SqlInvokedRegularFunctionHandle::getVersion); + Optional version = getVersion(); + if (!version.isPresent()) { + throw new IllegalStateException("missing version"); + } + return version.get(); } @Override @@ -172,9 +170,9 @@ public boolean equals(Object obj) if (obj == null || getClass() != obj.getClass()) { return false; } - SqlInvokedRegularFunction o = (SqlInvokedRegularFunction) obj; + SqlInvokedFunction o = (SqlInvokedFunction) obj; return Objects.equals(parameters, o.parameters) - && Objects.equals(comment, o.comment) + && Objects.equals(description, o.description) && Objects.equals(routineCharacteristics, o.routineCharacteristics) && Objects.equals(body, o.body) && Objects.equals(signature, o.signature) @@ -185,7 +183,7 @@ public boolean equals(Object obj) @Override public int hashCode() { - return Objects.hash(parameters, comment, routineCharacteristics, body, signature, functionId, functionHandle); + return Objects.hash(parameters, description, routineCharacteristics, body, signature, functionId, functionHandle); } @Override diff --git a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlParameter.java b/presto-spi/src/main/java/com/facebook/presto/spi/function/SqlParameter.java similarity index 83% rename from presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlParameter.java rename to presto-spi/src/main/java/com/facebook/presto/spi/function/SqlParameter.java index 535ee31472b85..452a3e4380858 100644 --- a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/SqlParameter.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/function/SqlParameter.java @@ -11,9 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.facebook.presto.sqlfunction; +package com.facebook.presto.spi.function; import com.facebook.presto.spi.type.TypeSignature; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Objects; @@ -24,17 +26,22 @@ public class SqlParameter private final String name; private final TypeSignature type; - public SqlParameter(String name, TypeSignature type) + @JsonCreator + public SqlParameter( + @JsonProperty("name") String name, + @JsonProperty("type") TypeSignature type) { this.name = requireNonNull(name, "name is null"); this.type = requireNonNull(type, "type is null"); } + @JsonProperty public String getName() { return name; } + @JsonProperty public TypeSignature getType() { return type; diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/relation/FullyQualifiedName.java b/presto-spi/src/main/java/com/facebook/presto/spi/relation/FullyQualifiedName.java deleted file mode 100644 index f55d1af45dfb8..0000000000000 --- a/presto-spi/src/main/java/com/facebook/presto/spi/relation/FullyQualifiedName.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.facebook.presto.spi.relation; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -import java.util.ArrayList; -import java.util.List; - -import static java.util.Arrays.asList; -import static java.util.Collections.unmodifiableList; -import static java.util.Locale.ENGLISH; -import static java.util.Objects.requireNonNull; - -public class FullyQualifiedName -{ - private final List parts; - private final List originalParts; - - @JsonCreator - public static FullyQualifiedName of(String dottedName) - { - String[] parts = dottedName.split("\\."); - if (parts.length < 3) { - throw new IllegalArgumentException("FullyQualifiedName should be in the form of 'a.b.c' and have at least 3 parts"); - } - return of(asList(parts)); - } - - public static FullyQualifiedName of(String part1, String part2, String part3, String... rest) - { - List parts = new ArrayList<>(rest.length + 3); - parts.add(part1); - parts.add(part2); - parts.add(part3); - parts.addAll(asList(rest)); - return of(parts); - } - - public static FullyQualifiedName of(List originalParts) - { - requireNonNull(originalParts, "originalParts is null"); - if (originalParts.size() < 3) { - throw new IllegalArgumentException("originalParts should have at least 3 parts"); - } - - List parts = new ArrayList<>(originalParts.size()); - for (String originalPart : originalParts) { - parts.add(originalPart.toLowerCase(ENGLISH)); - } - - return new FullyQualifiedName(originalParts, parts); - } - - public static FullyQualifiedName of(FullyQualifiedName.Prefix prefix, String name) - { - List parts = new ArrayList<>(prefix.parts); - parts.add(name); - return of(parts); - } - - private FullyQualifiedName(List originalParts, List parts) - { - this.originalParts = unmodifiableList(originalParts); - this.parts = unmodifiableList(parts); - } - - public List getParts() - { - return parts; - } - - public List getOriginalParts() - { - return originalParts; - } - - public String getSuffix() - { - return parts.get(parts.size() - 1); - } - - public Prefix getPrefix() - { - return new Prefix(parts.subList(0, parts.size() - 1)); - } - - @JsonValue - @Override - public String toString() - { - return String.join(".", parts); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - return parts.equals(((FullyQualifiedName) o).parts); - } - - @Override - public int hashCode() - { - return parts.hashCode(); - } - - public static class Prefix - { - private final List parts; - - private Prefix(List parts) - { - this.parts = unmodifiableList(parts); - } - - public static Prefix of(String dottedName) - { - String[] parts = dottedName.split("\\."); - if (parts.length < 2) { - throw new IllegalArgumentException("Prefix should be in the form of a.b(.c...) with at least 1 dot"); - } - return new Prefix(asList(parts)); - } - - public boolean contains(Prefix other) - { - if (parts.size() > other.parts.size()) { - return false; - } - for (int i = 0; i < parts.size(); i++) { - if (!parts.get(i).equals(other.parts.get(i))) { - return false; - } - } - return true; - } - - @Override - public String toString() - { - return String.join(".", parts); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - return parts.equals(((FullyQualifiedName.Prefix) o).parts); - } - - @Override - public int hashCode() - { - return parts.hashCode(); - } - } -} diff --git a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/AbstractSqlInvokedFunctionNamespaceManager.java b/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/AbstractSqlInvokedFunctionNamespaceManager.java index 2c0bc844109bc..b28839bb4ada2 100644 --- a/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/AbstractSqlInvokedFunctionNamespaceManager.java +++ b/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/AbstractSqlInvokedFunctionNamespaceManager.java @@ -17,14 +17,19 @@ import com.facebook.presto.spi.function.FunctionMetadata; import com.facebook.presto.spi.function.FunctionNamespaceManager; import com.facebook.presto.spi.function.FunctionNamespaceTransactionHandle; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.ScalarFunctionImplementation; import com.facebook.presto.spi.function.Signature; +import com.facebook.presto.spi.function.SqlFunctionHandle; +import com.facebook.presto.spi.function.SqlFunctionId; +import com.facebook.presto.spi.function.SqlInvokedFunction; import com.facebook.presto.spi.function.SqlInvokedScalarFunctionImplementation; -import com.facebook.presto.spi.relation.FullyQualifiedName; +import com.facebook.presto.spi.function.SqlParameter; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.concurrent.GuardedBy; import java.util.Collection; @@ -36,29 +41,31 @@ import static com.facebook.presto.spi.function.FunctionImplementationType.SQL; import static com.facebook.presto.spi.function.FunctionKind.SCALAR; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableMap.toImmutableMap; import static java.util.concurrent.TimeUnit.MILLISECONDS; public abstract class AbstractSqlInvokedFunctionNamespaceManager - implements FunctionNamespaceManager + implements FunctionNamespaceManager { private final ConcurrentMap transactions = new ConcurrentHashMap<>(); - private final LoadingCache> functions; - private final LoadingCache metadataByHandle; - private final LoadingCache implementationByHandle; + private final LoadingCache> functions; + private final LoadingCache metadataByHandle; + private final LoadingCache implementationByHandle; public AbstractSqlInvokedFunctionNamespaceManager(SqlInvokedFunctionNamespaceManagerConfig config) { this.functions = CacheBuilder.newBuilder() .expireAfterWrite(config.getFunctionCacheExpiration().toMillis(), MILLISECONDS) - .build(new CacheLoader>() + .build(new CacheLoader>() { @Override - public Collection load(FullyQualifiedName functionName) + @ParametersAreNonnullByDefault + public Collection load(QualifiedFunctionName functionName) { - Collection functions = fetchFunctionsDirect(functionName); - for (SqlInvokedRegularFunction function : functions) { + Collection functions = fetchFunctionsDirect(functionName); + for (SqlInvokedFunction function : functions) { metadataByHandle.put(function.getRequiredFunctionHandle(), sqlInvokedFunctionToMetadata(function)); } return functions; @@ -66,30 +73,32 @@ public Collection load(FullyQualifiedName functionNam }); this.metadataByHandle = CacheBuilder.newBuilder() .expireAfterWrite(config.getFunctionInstanceCacheExpiration().toMillis(), MILLISECONDS) - .build(new CacheLoader() + .build(new CacheLoader() { @Override - public FunctionMetadata load(SqlInvokedRegularFunctionHandle functionHandle) + @ParametersAreNonnullByDefault + public FunctionMetadata load(SqlFunctionHandle functionHandle) { return fetchFunctionMetadataDirect(functionHandle); } }); this.implementationByHandle = CacheBuilder.newBuilder() .expireAfterWrite(config.getFunctionInstanceCacheExpiration().toMillis(), MILLISECONDS) - .build(new CacheLoader() { + .build(new CacheLoader() + { @Override - public ScalarFunctionImplementation load(SqlInvokedRegularFunctionHandle functionHandle) + public ScalarFunctionImplementation load(SqlFunctionHandle functionHandle) { return fetchFunctionImplementationDirect(functionHandle); } }); } - protected abstract Collection fetchFunctionsDirect(FullyQualifiedName functionName); + protected abstract Collection fetchFunctionsDirect(QualifiedFunctionName functionName); - protected abstract FunctionMetadata fetchFunctionMetadataDirect(SqlInvokedRegularFunctionHandle functionHandle); + protected abstract FunctionMetadata fetchFunctionMetadataDirect(SqlFunctionHandle functionHandle); - protected abstract ScalarFunctionImplementation fetchFunctionImplementationDirect(SqlInvokedRegularFunctionHandle functionHandle); + protected abstract ScalarFunctionImplementation fetchFunctionImplementationDirect(SqlFunctionHandle functionHandle); @Override public final FunctionNamespaceTransactionHandle beginTransaction() @@ -107,14 +116,14 @@ public final void commit(FunctionNamespaceTransactionHandle transactionHandle) } @Override - public final void rollback(FunctionNamespaceTransactionHandle transactionHandle) + public final void abort(FunctionNamespaceTransactionHandle transactionHandle) { // Transactional rollback is not supported yet. transactions.remove(transactionHandle); } @Override - public final Collection getFunctions(Optional transactionHandle, FullyQualifiedName functionName) + public final Collection getFunctions(Optional transactionHandle, QualifiedFunctionName functionName) { checkArgument(transactionHandle.isPresent(), "missing transactionHandle"); return transactions.get(transactionHandle.get()).loadAndGetFunctionsTransactional(functionName); @@ -124,6 +133,7 @@ public final Collection getFunctions(Optional transactionHandle, Signature signature) { checkArgument(transactionHandle.isPresent(), "missing transactionHandle"); + // This is the only assumption in this class that we're dealing with sql-invoked regular function. SqlFunctionId functionId = new SqlFunctionId(signature.getName(), signature.getArgumentTypes()); return transactions.get(transactionHandle.get()).getFunctionHandle(functionId); } @@ -131,23 +141,30 @@ public final FunctionHandle getFunctionHandle(Optional fetchFunctions(FullyQualifiedName functionName) + private Collection fetchFunctions(QualifiedFunctionName functionName) { return functions.getUnchecked(functionName); } @@ -169,15 +186,15 @@ private Collection fetchFunctions(FullyQualifiedName private class FunctionCollection { @GuardedBy("this") - private final Map> functions = new ConcurrentHashMap<>(); + private final Map> functions = new ConcurrentHashMap<>(); @GuardedBy("this") - private final Map functionHandles = new ConcurrentHashMap<>(); + private final Map functionHandles = new ConcurrentHashMap<>(); - public synchronized Collection loadAndGetFunctionsTransactional(FullyQualifiedName functionName) + public synchronized Collection loadAndGetFunctionsTransactional(QualifiedFunctionName functionName) { - Collection functions = this.functions.computeIfAbsent(functionName, AbstractSqlInvokedFunctionNamespaceManager.this::fetchFunctions); - functionHandles.putAll(functions.stream().collect(toImmutableMap(SqlInvokedRegularFunction::getFunctionId, SqlInvokedRegularFunction::getRequiredFunctionHandle))); + Collection functions = this.functions.computeIfAbsent(functionName, AbstractSqlInvokedFunctionNamespaceManager.this::fetchFunctions); + functionHandles.putAll(functions.stream().collect(toImmutableMap(SqlInvokedFunction::getFunctionId, SqlInvokedFunction::getRequiredFunctionHandle))); return functions; } diff --git a/presto-main/src/test/java/com/facebook/presto/metadata/SqlInvokedRegularFunctionTestUtils.java b/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/testing/SqlInvokedFunctionTestUtils.java similarity index 56% rename from presto-main/src/test/java/com/facebook/presto/metadata/SqlInvokedRegularFunctionTestUtils.java rename to presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/testing/SqlInvokedFunctionTestUtils.java index 8d017df4cbfe0..4ddd26621cbf2 100644 --- a/presto-main/src/test/java/com/facebook/presto/metadata/SqlInvokedRegularFunctionTestUtils.java +++ b/presto-sql-function/src/main/java/com/facebook/presto/sqlfunction/testing/SqlInvokedFunctionTestUtils.java @@ -11,55 +11,55 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.facebook.presto.metadata; +package com.facebook.presto.sqlfunction.testing; -import com.facebook.presto.spi.relation.FullyQualifiedName; -import com.facebook.presto.sqlfunction.RoutineCharacteristics; -import com.facebook.presto.sqlfunction.SqlInvokedRegularFunction; -import com.facebook.presto.sqlfunction.SqlParameter; +import com.facebook.presto.spi.function.QualifiedFunctionName; +import com.facebook.presto.spi.function.RoutineCharacteristics; +import com.facebook.presto.spi.function.SqlInvokedFunction; +import com.facebook.presto.spi.function.SqlParameter; import com.google.common.collect.ImmutableList; import java.util.Optional; +import static com.facebook.presto.spi.function.RoutineCharacteristics.Determinism.DETERMINISTIC; +import static com.facebook.presto.spi.function.RoutineCharacteristics.Language.SQL; +import static com.facebook.presto.spi.function.RoutineCharacteristics.NullCallClause.CALLED_ON_NULL_INPUT; +import static com.facebook.presto.spi.function.RoutineCharacteristics.NullCallClause.RETURNS_NULL_ON_NULL_INPUT; import static com.facebook.presto.spi.type.StandardTypes.DOUBLE; import static com.facebook.presto.spi.type.StandardTypes.INTEGER; import static com.facebook.presto.spi.type.TypeSignature.parseTypeSignature; -import static com.facebook.presto.sqlfunction.RoutineCharacteristics.Determinism.DETERMINISTIC; -import static com.facebook.presto.sqlfunction.RoutineCharacteristics.Language.SQL; -import static com.facebook.presto.sqlfunction.RoutineCharacteristics.NullCallClause.CALLED_ON_NULL_INPUT; -import static com.facebook.presto.sqlfunction.RoutineCharacteristics.NullCallClause.RETURNS_NULL_ON_NULL_INPUT; -public class SqlInvokedRegularFunctionTestUtils +public class SqlInvokedFunctionTestUtils { - private SqlInvokedRegularFunctionTestUtils() + private SqlInvokedFunctionTestUtils() { } - public static final FullyQualifiedName POWER_TOWER = FullyQualifiedName.of("unittest.memory.power_tower"); + public static final QualifiedFunctionName POWER_TOWER = QualifiedFunctionName.of("unittest.memory.power_tower"); - public static final SqlInvokedRegularFunction FUNCTION_POWER_TOWER_DOUBLE = new SqlInvokedRegularFunction( + public static final SqlInvokedFunction FUNCTION_POWER_TOWER_DOUBLE = new SqlInvokedFunction( POWER_TOWER, ImmutableList.of(new SqlParameter("x", parseTypeSignature(DOUBLE))), parseTypeSignature(DOUBLE), - Optional.of("power tower"), + "power tower", new RoutineCharacteristics(SQL, DETERMINISTIC, CALLED_ON_NULL_INPUT), "pow(x, x)", Optional.empty()); - public static final SqlInvokedRegularFunction FUNCTION_POWER_TOWER_DOUBLE_UPDATED = new SqlInvokedRegularFunction( + public static final SqlInvokedFunction FUNCTION_POWER_TOWER_DOUBLE_UPDATED = new SqlInvokedFunction( POWER_TOWER, ImmutableList.of(new SqlParameter("x", parseTypeSignature(DOUBLE))), parseTypeSignature(DOUBLE), - Optional.of("power tower"), + "power tower", new RoutineCharacteristics(SQL, DETERMINISTIC, RETURNS_NULL_ON_NULL_INPUT), "pow(x, x)", Optional.empty()); - public static final SqlInvokedRegularFunction FUNCTION_POWER_TOWER_INT = new SqlInvokedRegularFunction( + public static final SqlInvokedFunction FUNCTION_POWER_TOWER_INT = new SqlInvokedFunction( POWER_TOWER, ImmutableList.of(new SqlParameter("x", parseTypeSignature(INTEGER))), parseTypeSignature(INTEGER), - Optional.of("power tower"), + "power tower", new RoutineCharacteristics(SQL, DETERMINISTIC, RETURNS_NULL_ON_NULL_INPUT), "pow(x, x)", Optional.empty()); diff --git a/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java b/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java index 7d342a5b2d494..eb48c47c3de0b 100644 --- a/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java +++ b/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java @@ -4652,6 +4652,7 @@ public void testExplainDdl() { assertExplainDdl("CREATE TABLE foo (pk bigint)", "CREATE TABLE foo"); assertExplainDdl("CREATE VIEW foo AS SELECT * FROM orders", "CREATE VIEW foo"); + assertExplainDdl("CREATE OR REPLACE FUNCTION testing.default.tan (x int) RETURNS double COMMENT 'tangent trigonometric function' LANGUAGE SQL DETERMINISTIC CALLED ON NULL INPUT RETURN sin(x) / cos(x)", "CREATE FUNCTION testing.default.tan"); assertExplainDdl("DROP TABLE orders"); assertExplainDdl("DROP VIEW view"); assertExplainDdl("ALTER TABLE orders RENAME TO new_name"); @@ -7979,6 +7980,8 @@ public void testDescribeOutputNonSelect() assertDescribeOutputEmpty("ALTER TABLE foo RENAME TO bar"); assertDescribeOutputEmpty("DROP TABLE foo"); assertDescribeOutputEmpty("CREATE VIEW foo AS SELECT * FROM nation"); + assertDescribeOutputEmpty("CREATE FUNCTION testing.default.tan (x int) RETURNS double COMMENT 'tangent trigonometric function' LANGUAGE SQL DETERMINISTIC CALLED ON NULL INPUT RETURN sin(x) / cos(x)"); + assertDescribeOutputEmpty("DROP VIEW foo"); assertDescribeOutputEmpty("PREPARE test FROM SELECT * FROM orders"); assertDescribeOutputEmpty("EXECUTE test"); diff --git a/presto-tests/src/main/java/com/facebook/presto/tests/StatefulSleepingSum.java b/presto-tests/src/main/java/com/facebook/presto/tests/StatefulSleepingSum.java index 7c9c9877ef9e5..35abb77c33670 100644 --- a/presto-tests/src/main/java/com/facebook/presto/tests/StatefulSleepingSum.java +++ b/presto-tests/src/main/java/com/facebook/presto/tests/StatefulSleepingSum.java @@ -18,8 +18,8 @@ import com.facebook.presto.metadata.SqlScalarFunction; import com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation; import com.facebook.presto.spi.function.FunctionKind; +import com.facebook.presto.spi.function.QualifiedFunctionName; import com.facebook.presto.spi.function.Signature; -import com.facebook.presto.spi.relation.FullyQualifiedName; import com.facebook.presto.spi.type.TypeManager; import com.google.common.collect.ImmutableList; @@ -45,7 +45,7 @@ public class StatefulSleepingSum private StatefulSleepingSum() { super(new Signature( - FullyQualifiedName.of(DEFAULT_NAMESPACE, "stateful_sleeping_sum"), + QualifiedFunctionName.of(DEFAULT_NAMESPACE, "stateful_sleeping_sum"), FunctionKind.SCALAR, ImmutableList.of(typeVariable("bigint")), ImmutableList.of(), diff --git a/presto-tests/src/test/java/com/facebook/presto/tests/TestSqlFunctions.java b/presto-tests/src/test/java/com/facebook/presto/tests/TestSqlFunctions.java new file mode 100644 index 0000000000000..61679d90abc3d --- /dev/null +++ b/presto-tests/src/test/java/com/facebook/presto/tests/TestSqlFunctions.java @@ -0,0 +1,51 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.facebook.presto.tests; + +import com.facebook.presto.tests.tpch.TpchQueryRunnerBuilder; +import org.testng.annotations.Test; + +public class TestSqlFunctions + extends AbstractTestQueryFramework +{ + protected TestSqlFunctions() + { + super(() -> TpchQueryRunnerBuilder.builder().build()); + } + + @Test + public void testCreateFunctionInvalidFunctionName() + { + assertQueryFails( + "CREATE FUNCTION testing.tan (x int) RETURNS double COMMENT 'tangent trigonometric function' RETURN sin(x) / cos(x)", + "Invalid function name: testing\\.tan, require exactly 3 parts"); + assertQueryFails( + "CREATE FUNCTION presto.default.tan (x int) RETURNS double COMMENT 'tangent trigonometric function' RETURN sin(x) / cos(x)", + "Cannot create function in built-in function namespace: presto\\.default\\.tan"); + } + + @Test + public void testCreateFunctionInvalidSemantics() + { + assertQueryFails( + "CREATE FUNCTION testing.default.tan (x int) RETURNS varchar COMMENT 'tangent trigonometric function' RETURN sin(x) / cos(x)", + "Function implementation type 'double' does not match declared return type 'varchar'"); + assertQueryFails( + "CREATE FUNCTION testing.default.tan (x int) RETURNS varchar COMMENT 'tangent trigonometric function' RETURN sin(y) / cos(y)", + ".*Column 'y' cannot be resolved"); + assertQueryFails( + "CREATE FUNCTION testing.default.tan (x double) RETURNS double COMMENT 'tangent trigonometric function' RETURN sum(x)", + ".*CREATE FUNCTION body cannot contain aggregations, window functions or grouping operations:.*"); + } +}