diff --git a/core/trino-main/src/main/java/io/trino/metadata/FunctionResolver.java b/core/trino-main/src/main/java/io/trino/metadata/FunctionResolver.java index eaaf77e362c9a..190780d3e48e4 100644 --- a/core/trino-main/src/main/java/io/trino/metadata/FunctionResolver.java +++ b/core/trino-main/src/main/java/io/trino/metadata/FunctionResolver.java @@ -23,13 +23,13 @@ import io.trino.spi.function.CatalogSchemaFunctionName; import io.trino.spi.function.FunctionMetadata; import io.trino.spi.function.FunctionNullability; -import io.trino.spi.function.QualifiedFunctionName; import io.trino.spi.function.Signature; import io.trino.spi.type.Type; import io.trino.spi.type.TypeManager; import io.trino.sql.SqlPathElement; import io.trino.sql.analyzer.TypeSignatureProvider; import io.trino.sql.tree.Identifier; +import io.trino.sql.tree.QualifiedName; import java.util.ArrayList; import java.util.Collection; @@ -68,7 +68,7 @@ public FunctionResolver(Metadata metadata, TypeManager typeManager) this.typeManager = requireNonNull(typeManager, "typeManager is null"); } - boolean isAggregationFunction(Session session, QualifiedFunctionName name, Function> candidateLoader) + boolean isAggregationFunction(Session session, QualifiedName name, Function> candidateLoader) { for (CatalogSchemaFunctionName catalogSchemaFunctionName : toPath(session, name)) { Collection candidates = candidateLoader.apply(catalogSchemaFunctionName); @@ -82,7 +82,7 @@ boolean isAggregationFunction(Session session, QualifiedFunctionName name, Funct return false; } - boolean isWindowFunction(Session session, QualifiedFunctionName name, Function> candidateLoader) + boolean isWindowFunction(Session session, QualifiedName name, Function> candidateLoader) { for (CatalogSchemaFunctionName catalogSchemaFunctionName : toPath(session, name)) { Collection candidates = candidateLoader.apply(catalogSchemaFunctionName); @@ -158,7 +158,7 @@ private static boolean possibleExactCastMatch(Signature signature, Signature dec CatalogFunctionBinding resolveFunction( Session session, - QualifiedFunctionName name, + QualifiedName name, List parameterTypes, Function> candidateLoader) { @@ -231,28 +231,32 @@ private Optional match(List param return matchFunctionWithCoercion(candidates, parameterTypes); } - public static List toPath(Session session, QualifiedFunctionName name) + public static List toPath(Session session, QualifiedName name) { - if (name.getCatalogName().isPresent()) { - return ImmutableList.of(new CatalogSchemaFunctionName(name.getCatalogName().orElseThrow(), name.getSchemaName().orElseThrow(), name.getFunctionName())); + List parts = name.getParts(); + if (parts.size() > 3) { + throw new TrinoException(FUNCTION_NOT_FOUND, "Invalid function name: " + name); + } + if (parts.size() == 3) { + return ImmutableList.of(new CatalogSchemaFunctionName(parts.get(0), parts.get(1), parts.get(2))); } - if (name.getSchemaName().isPresent()) { + if (parts.size() == 2) { String currentCatalog = session.getCatalog() .orElseThrow(() -> new TrinoException(MISSING_CATALOG_NAME, "Session default catalog must be set to resolve a partial function name: " + name)); - return ImmutableList.of(new CatalogSchemaFunctionName(currentCatalog, name.getSchemaName().orElseThrow(), name.getFunctionName())); + return ImmutableList.of(new CatalogSchemaFunctionName(currentCatalog, parts.get(0), parts.get(1))); } ImmutableList.Builder names = ImmutableList.builder(); // global namespace - names.add(builtinFunctionName(name.getFunctionName())); + names.add(builtinFunctionName(parts.get(0))); // add resolved path items for (SqlPathElement sqlPathElement : session.getPath().getParsedPath()) { String catalog = sqlPathElement.getCatalog().map(Identifier::getCanonicalValue).or(session::getCatalog) .orElseThrow(() -> new TrinoException(MISSING_CATALOG_NAME, "Session default catalog must be set to resolve a partial function name: " + name)); - names.add(new CatalogSchemaFunctionName(catalog, sqlPathElement.getSchema().getCanonicalValue(), name.getFunctionName())); + names.add(new CatalogSchemaFunctionName(catalog, sqlPathElement.getSchema().getCanonicalValue(), parts.get(0))); } return names.build(); } diff --git a/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java b/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java index 915145d25646f..cfd63d8ddb50b 100644 --- a/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java +++ b/core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java @@ -96,7 +96,6 @@ import io.trino.spi.function.FunctionId; import io.trino.spi.function.FunctionMetadata; import io.trino.spi.function.OperatorType; -import io.trino.spi.function.QualifiedFunctionName; import io.trino.spi.function.SchemaFunctionName; import io.trino.spi.function.Signature; import io.trino.spi.predicate.TupleDomain; @@ -2308,7 +2307,7 @@ public ResolvedFunction resolveFunction(Session session, QualifiedName name, Lis CatalogFunctionBinding catalogFunctionBinding = functionResolver.resolveFunction( session, - toQualifiedFunctionName(name), + name, parameterTypes, catalogSchemaFunctionName -> getFunctions(session, catalogSchemaFunctionName)); return resolve(session, catalogFunctionBinding); @@ -2344,20 +2343,6 @@ public ResolvedFunction resolveOperator(OperatorType operatorType, List parts = qualifiedName.getParts(); - checkArgument(parts.size() <= 3, "Function name can only have 3 parts: " + qualifiedName); - if (parts.size() == 3) { - return QualifiedFunctionName.of(parts.get(0), parts.get(1), parts.get(2)); - } - if (parts.size() == 2) { - return QualifiedFunctionName.of(parts.get(0), parts.get(1)); - } - return QualifiedFunctionName.of(parts.get(0)); - } - @Override public ResolvedFunction getCoercion(OperatorType operatorType, Type fromType, Type toType) { @@ -2559,7 +2544,7 @@ public boolean isAggregationFunction(Session session, QualifiedName name) { return functionDecoder.fromQualifiedName(name) .map(function -> function.getFunctionKind() == AGGREGATE) - .orElseGet(() -> functionResolver.isAggregationFunction(session, toQualifiedFunctionName(name), catalogSchemaFunctionName -> getFunctions(session, catalogSchemaFunctionName))); + .orElseGet(() -> functionResolver.isAggregationFunction(session, name, catalogSchemaFunctionName -> getFunctions(session, catalogSchemaFunctionName))); } @Override @@ -2567,7 +2552,7 @@ public boolean isWindowFunction(Session session, QualifiedName name) { return functionDecoder.fromQualifiedName(name) .map(function -> function.getFunctionKind() == WINDOW) - .orElseGet(() -> functionResolver.isWindowFunction(session, toQualifiedFunctionName(name), catalogSchemaFunctionName -> getFunctions(session, catalogSchemaFunctionName))); + .orElseGet(() -> functionResolver.isWindowFunction(session, name, catalogSchemaFunctionName -> getFunctions(session, catalogSchemaFunctionName))); } private Collection getFunctions(Session session, CatalogSchemaFunctionName name) diff --git a/core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java b/core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java index e73266e035b5c..ed167e76f8bb5 100644 --- a/core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java +++ b/core/trino-main/src/main/java/io/trino/sql/analyzer/StatementAnalyzer.java @@ -285,7 +285,6 @@ import static io.trino.SystemSessionProperties.getMaxGroupingSets; import static io.trino.SystemSessionProperties.isLegacyMaterializedViewGracePeriod; import static io.trino.metadata.FunctionResolver.toPath; -import static io.trino.metadata.MetadataManager.toQualifiedFunctionName; import static io.trino.metadata.MetadataUtil.createQualifiedObjectName; import static io.trino.metadata.MetadataUtil.getRequiredCatalogHandle; import static io.trino.spi.StandardErrorCode.AMBIGUOUS_NAME; @@ -1778,7 +1777,7 @@ else if (argument.getPartitionBy().isPresent()) { private Optional resolveTableFunction(TableFunctionInvocation node) { - for (CatalogSchemaFunctionName name : toPath(session, toQualifiedFunctionName(node.getName()))) { + for (CatalogSchemaFunctionName name : toPath(session, node.getName())) { CatalogHandle catalogHandle = getRequiredCatalogHandle(metadata, session, node, name.getCatalogName()); Optional resolved = tableFunctionRegistry.resolve(catalogHandle, name.getSchemaFunctionName()); if (resolved.isPresent()) { diff --git a/core/trino-spi/src/main/java/io/trino/spi/function/QualifiedFunctionName.java b/core/trino-spi/src/main/java/io/trino/spi/function/QualifiedFunctionName.java deleted file mode 100644 index 70a2f0da34875..0000000000000 --- a/core/trino-spi/src/main/java/io/trino/spi/function/QualifiedFunctionName.java +++ /dev/null @@ -1,107 +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 io.trino.spi.function; - -import io.trino.spi.Experimental; - -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -@Experimental(eta = "2022-10-31") -public class QualifiedFunctionName -{ - private final Optional catalogName; - private final Optional schemaName; - private final String functionName; - - public static QualifiedFunctionName of(String functionName) - { - return new QualifiedFunctionName(Optional.empty(), Optional.empty(), functionName); - } - - public static QualifiedFunctionName of(String schemaName, String functionName) - { - return new QualifiedFunctionName(Optional.empty(), Optional.of(schemaName), functionName); - } - - public static QualifiedFunctionName of(String catalogName, String schemaName, String functionName) - { - return new QualifiedFunctionName(Optional.of(catalogName), Optional.of(schemaName), functionName); - } - - private QualifiedFunctionName(Optional catalogName, Optional schemaName, String functionName) - { - this.catalogName = requireNonNull(catalogName, "catalogName is null"); - if (catalogName.map(String::isEmpty).orElse(false)) { - throw new IllegalArgumentException("catalogName is empty"); - } - this.schemaName = requireNonNull(schemaName, "schemaName is null"); - if (schemaName.map(String::isEmpty).orElse(false)) { - throw new IllegalArgumentException("schemaName is empty"); - } - if (catalogName.isPresent() && schemaName.isEmpty()) { - throw new IllegalArgumentException("Schema name must be provided when catalog name is provided"); - } - this.functionName = requireNonNull(functionName, "functionName is null"); - if (functionName.isEmpty()) { - throw new IllegalArgumentException("functionName is empty"); - } - } - - public Optional getCatalogName() - { - return catalogName; - } - - public Optional getSchemaName() - { - return schemaName; - } - - public String getFunctionName() - { - return functionName; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - QualifiedFunctionName that = (QualifiedFunctionName) o; - return catalogName.equals(that.catalogName) && - schemaName.equals(that.schemaName) && - functionName.equals(that.functionName); - } - - @Override - public int hashCode() - { - return Objects.hash(catalogName, schemaName, functionName); - } - - @Override - public String toString() - { - return catalogName.map(name -> name + ".").orElse("") + - schemaName.map(name -> name + ".").orElse("") + - functionName; - } -}