{"record":{"id":"7ed1cd48bcbc5a73","repo":"t8y2/dbx","slug":"databend-procedure-names-with-special-characters-a","errorCode":null,"errorMessage":"Databend procedure names with special characters are not supported: {name}","messagePattern":"Databend procedure names with special characters are not supported: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agents/drivers/databend/src/main/java/com/dbx/agent/databend/DatabendAgent.java","lineNumber":208,"sourceCode":"        String body = properties.getOrDefault(\"body\", \"\").trim();\n        StringBuilder source = new StringBuilder();\n        source.append(\"CREATE PROCEDURE \").append(simpleProcedureName(name)).append(\"(\").append(String.join(\", \", arguments)).append(\")\");\n        if (!returns.isEmpty()) {\n            source.append(\"\\nRETURNS \").append(returns);\n        }\n        source.append(\"\\nLANGUAGE \").append(language);\n        if (procedure.comment != null && !procedure.comment.isEmpty()) {\n            source.append(\"\\nCOMMENT = '\").append(procedure.comment.replace(\"'\", \"''\")).append(\"'\");\n        }\n        source.append(\"\\nAS $$\\n\").append(body).append(\"\\n$$;\");\n        return source.toString();\n    }\n\n    private static String simpleProcedureName(String name) {\n        if (name != null && name.matches(\"[A-Za-z_][A-Za-z0-9_]*\")) {\n            return name;\n        }\n        throw new IllegalArgumentException(\"Databend procedure names with special characters are not supported: \" + name);\n    }\n\n    private static List<String> inputTypesFromArguments(String arguments) {\n        if (arguments == null) {\n            return Collections.emptyList();\n        }\n        int open = arguments.indexOf('(');\n        if (open < 0) {\n            return Collections.emptyList();\n        }\n        int close = matchingParen(arguments, open);\n        if (close < 0) {\n            return Collections.emptyList();\n        }\n        return splitTopLevel(arguments.substring(open + 1, close));\n    }\n\n    private static List<String> signatureNames(String signature) {","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/databend/src/main/java/com/dbx/agent/databend/DatabendAgent.java#L190-L226","documentation":"DatabendAgent only supports procedures whose names are simple identifiers (letters, digits, underscores, not starting with a digit). simpleProcedureName validates the name against the regex [A-Za-z_][A-Za-z0-9_]* and throws IllegalArgumentException when it doesn't match, because describeProcedure/buildProcedureSource cannot safely handle quoted or special-character identifiers.","triggerScenarios":"Calling getObjectSource for a Databend procedure whose name contains characters outside [A-Za-z0-9_] (spaces, dashes, dots, unicode) or starts with a digit; null names are also rejected.","commonSituations":"Procedures created with quoted/backtick identifiers like `daily-rollup` or `2024 report`; names generated by migration tools with hyphens; names containing schema prefixes or dots passed by mistake.","solutions":["Rename the procedure to a simple identifier (letters, digits, underscores) and fetch it again.","Pass the bare procedure name without schema prefix or quoting characters.","If the special-character name must be kept, extend the driver to handle quoted identifiers, or retrieve the source with an equivalent SHOW CREATE PROCEDURE call manually.","Reject or skip such procedures in tooling before calling getObjectSource."],"exampleFix":"// before\nagent.getObjectSource(conn, schema, \"daily-rollup\", \"PROCEDURE\");\n// after\nagent.getObjectSource(conn, schema, \"daily_rollup\", \"PROCEDURE\"); // renamed to a simple identifier","handlingStrategy":"validation","validationCode":"// Java (caller side)\nprivate static boolean isSimpleProcedureName(String name) {\n    return name != null && name.matches(\"[A-Za-z_][A-Za-z0-9_]*\");\n}\nif (!isSimpleProcedureName(procedureName)) {\n    throw new IllegalArgumentException(\"Use a simple identifier: \" + procedureName);\n}\nObjectSource src = agent.getObjectSource(conn, schema, procedureName, \"PROCEDURE\");","typeGuard":null,"tryCatchPattern":"try {\n    src = agent.getObjectSource(conn, schema, name, \"PROCEDURE\");\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"special characters\")) {\n        throw new UnsupportedOperationException(\n            \"Procedure \\\"\" + name + \"\\\" needs a simple identifier for source extraction\", e);\n    } else { throw e; }\n}","preventionTips":["Adopt a naming convention of letters, digits, and underscores for all Databend procedures.","Validate identifiers against [A-Za-z_][A-Za-z0-9_]* in CI before deploying or extracting sources.","Strip any schema prefixes or quoting characters before passing names to the agent.","Treat procedures with special-character names as unsupported and handle them with raw SQL manually."],"tags":["validation","databend","identifier"],"backgroundTag":"unsupported-identifier","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}