{"record":{"id":"790c4f67b35228c3","repo":"prestodb/presto","slug":"function-not-found-790c4f","errorCode":"FUNCTION_NOT_FOUND","errorMessage":"Invalid function name: ","messagePattern":"Invalid function name: ","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/metadata/TableFunctionRegistry.java","lineNumber":84,"sourceCode":"            builder.put(\n                    new SchemaFunctionName(\n                            function.getSchema().toLowerCase(ENGLISH),\n                            function.getName().toLowerCase(ENGLISH)),\n                    new TableFunctionMetadata(catalogName, function));\n        }\n        tableFunctions.putIfAbsent(catalogName, builder.buildOrThrow());\n    }\n\n    public void removeTableFunctions(ConnectorId catalogName)\n    {\n        tableFunctions.remove(catalogName);\n    }\n\n    public static List<CatalogSchemaFunctionName> toPath(Session session, QualifiedName name)\n    {\n        List<String> parts = name.getParts();\n        if (parts.size() > 3) {\n            throw new PrestoException(StandardErrorCode.FUNCTION_NOT_FOUND, \"Invalid function name: \" + name);\n        }\n        if (parts.size() == 3) {\n            return ImmutableList.of(new CatalogSchemaFunctionName(parts.get(0), parts.get(1), parts.get(2)));\n        }\n\n        if (parts.size() == 2) {\n            String currentCatalog = session.getCatalog()\n                    .orElseThrow(() -> new PrestoException(SESSION_CATALOG_NOT_SET, \"Session default catalog must be set to resolve a partial function name: \" + name));\n            return ImmutableList.of(new CatalogSchemaFunctionName(currentCatalog, parts.get(0), parts.get(1)));\n        }\n\n        ImmutableList.Builder<CatalogSchemaFunctionName> names = ImmutableList.builder();\n\n        String currentCatalog = session.getCatalog()\n                .orElseThrow(() -> new SemanticException(CATALOG_NOT_SPECIFIED, \"Catalog must be specified when session catalog is not set\"));\n        String currentSchema = session.getSchema()\n                .orElseThrow(() -> new SemanticException(SCHEMA_NOT_SPECIFIED, \"Schema must be specified when session schema is not set\"));\n","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/metadata/TableFunctionRegistry.java#L66-L102","documentation":"TableFunctionRegistry.toPath resolves a QualifiedName into a list of catalog/schema-qualified function names for table function lookup. A qualified name with more than three parts is not a valid function path, so it throws FUNCTION_NOT_FOUND with the offending name. Valid paths are 1–3 parts (function, schema.function, catalog.schema.function).","triggerScenarios":"Invoking a table function with a name having 4+ dot-separated parts, e.g. SELECT * FROM TABLE(a.b.c.d(...)) or an over-qualified name in a saved query.","commonSituations":"Copy-pasted fully-qualified names including cluster/catalog prefix beyond what Presto allows; generated SQL that over-qualifies; typos adding an extra qualifier.","solutions":["Reduce the function name to at most catalog.schema.function","Use schema.function or plain function name and rely on session catalog/schema","Fix SQL generators/templates that prepend an extra catalog qualifier"],"exampleFix":"// before\nSELECT * FROM TABLE(mycluster.mycatalog.my_schema.my_func(x));\n// after\nSELECT * FROM TABLE(my_schema.my_func(x));","handlingStrategy":"validation","validationCode":"QualifiedName name = ...;\nif (name.getParts().size() > 3) {\n    throw new IllegalArgumentException(\"Function name must have at most 3 parts: \" + name);\n}","typeGuard":"boolean isValidFunctionName(QualifiedName name) {\n    return name.getParts().size() >= 1 && name.getParts().size() <= 3;\n}","tryCatchPattern":"try {\n    List<CatalogSchemaFunctionName> path = TableFunctionRegistry.toPath(session, name);\n} catch (PrestoException e) {\n    if (e.getErrorCode().getCode() == StandardErrorCode.FUNCTION_NOT_FOUND.toErrorCode().getCode()) {\n        // retry with trimmed qualification: drop leading catalog parts\n    }\n    throw e;\n}","preventionTips":["Qualify table functions with at most catalog.schema.function","Validate generated SQL templates for over-qualification","Prefer session catalog/schema defaults over full qualification"],"tags":["presto","table-function","function-not-found","qualified-name"],"backgroundTag":"function-not-found","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}