{"record":{"id":"fa87f1289e7612f2","repo":"apache/beam","slug":"function-s-is-already-defined","errorCode":null,"errorMessage":"Function %s is already defined.","messagePattern":"Function (.+?) is already defined\\.","errorType":"validation","errorClass":"SqlUtil.newContextException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/parser/SqlCreateFunction.java","lineNumber":98,"sourceCode":"  }\n\n  @Override\n  public SqlOperator getOperator() {\n    return OPERATOR;\n  }\n\n  @Override\n  public List<SqlNode> getOperandList() {\n    return Arrays.asList(functionName, jarPath);\n  }\n\n  @Override\n  public void execute(CalcitePrepare.Context context) {\n    final Pair<CalciteSchema, String> pair = SqlDdlNodes.schema(context, true, functionName);\n    SchemaPlus schema = pair.left.plus();\n    String lastName = pair.right;\n    if (!schema.getFunctions(lastName).isEmpty()) {\n      throw SqlUtil.newContextException(\n          functionName.getParserPosition(),\n          RESOURCE.internal(String.format(\"Function %s is already defined.\", lastName)));\n    }\n    JavaUdfLoader udfLoader = new JavaUdfLoader();\n    // TODO(https://github.com/apache/beam/issues/20834) Support qualified function names.\n    List<String> functionPath = ImmutableList.of(lastName);\n    if (!(jarPath instanceof SqlCharStringLiteral)) {\n      throw SqlUtil.newContextException(\n          jarPath.getParserPosition(),\n          RESOURCE.internal(\"Jar path is not instanceof SqlCharStringLiteral.\"));\n    }\n    String unquotedJarPath = ((SqlCharStringLiteral) jarPath).getNlsString().getValue();\n    if (isAggregate) {\n      // Try loading the aggregate function just to make sure it exists. LazyAggregateCombineFn will\n      // need to fetch it again at runtime.\n      udfLoader.loadAggregateFunction(functionPath, unquotedJarPath);\n      LazyAggregateCombineFn<?, ?, ?> combineFn =\n          new LazyAggregateCombineFn<>(functionPath, unquotedJarPath);","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/parser/SqlCreateFunction.java#L80-L116","documentation":"Thrown by CREATE FUNCTION when a function with the same name already exists in the target schema (schema.getFunctions(lastName) is non-empty). Beam does not allow redefinition of a UDF name within one schema, so it raises a parse-context internal error naming the function.","triggerScenarios":"`CREATE FUNCTION fname ...` where fname is already registered in the same schema — e.g. re-running a setup script or re-declaring a built-in/previous UDF name without dropping it first.","commonSituations":"Idempotent DDL scripts executed twice; name collision with a Beam built-in SQL function; re-registering a UDF after changing its jar without dropping the old one.","solutions":["DROP FUNCTION fname first, then re-create it","Use a different function name","Guard DDL scripts to run only once or check function existence beforehand"],"exampleFix":"// before\nCREATE FUNCTION my_udf AS 'com.x.MyUdf' USING JAR 'gs://bucket/udf.jar';\n// after\nDROP FUNCTION IF EXISTS my_udf;\nCREATE FUNCTION my_udf AS 'com.x.MyUdf' USING JAR 'gs://bucket/udf.jar';","handlingStrategy":"validation","validationCode":"boolean fnExists = !schema.getFunctions(\"my_udf\").isEmpty();\nif (fnExists) { /* skip or drop first */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefix DROP FUNCTION IF EXISTS before CREATE FUNCTION in scripts","Avoid colliding with built-in Beam SQL function names","Make UDF registration idempotent"],"tags":["sql","ddl","udf","duplicate-function"],"backgroundTag":"file-already-exists","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}