{"record":{"id":"671db6514c6db47c","repo":"apache/cassandra","slug":"function-s-cannot-replace-an-aggregate","errorCode":null,"errorMessage":"Function '%s' cannot replace an aggregate","messagePattern":"Function '(.+?)' cannot replace an aggregate","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateFunctionStatement.java","lineNumber":140,"sourceCode":"            rawArgumentTypes.stream()\n                            .map(t -> t.prepare(keyspaceName, keyspace.types).getType().udfType())\n                            .collect(toList());\n        AbstractType<?> returnType = rawReturnType.prepare(keyspaceName, keyspace.types).getType().udfType();\n\n        UDFunction function =\n            UDFunction.create(new FunctionName(keyspaceName, functionName),\n                              argumentNames,\n                              argumentTypes,\n                              returnType,\n                              calledOnNullInput,\n                              language,\n                              body);\n\n        UserFunction existingFunction = keyspace.userFunctions.find(function.name(), argumentTypes).orElse(null);\n        if (null != existingFunction)\n        {\n            if (existingFunction.isAggregate())\n                throw ire(\"Function '%s' cannot replace an aggregate\", functionName);\n\n            if (ifNotExists)\n                return schema;\n\n            if (!orReplace)\n                throw ire(\"Function '%s' already exists\", functionName);\n\n            if (calledOnNullInput != ((UDFunction) existingFunction).isCalledOnNullInput())\n            {\n                throw ire(\"Function '%s' must have %s directive\",\n                          functionName,\n                          calledOnNullInput ? \"CALLED ON NULL INPUT\" : \"RETURNS NULL ON NULL INPUT\");\n            }\n\n            if (!returnType.isCompatibleWith(existingFunction.returnType()))\n            {\n                throw ire(\"Cannot replace function '%s', the new return type %s is not compatible with the return type %s of existing function\",\n                          functionName,","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateFunctionStatement.java#L122-L158","documentation":"CREATE FUNCTION (without OR REPLACE semantics allowed) resolved an existing entity at the function's name/signature that is an aggregate, not a function. Cassandra keeps functions and aggregates in separate namespaces but shares the name; replacing an aggregate via CREATE FUNCTION is rejected to avoid accidentally overwriting an aggregate.","triggerScenarios":"CREATE FUNCTION [IF NOT EXISTS] whose name and argument types match an existing aggregate created with CREATE AGGREGATE.","commonSituations":"Reusing an aggregate's name for a new function; migrations that create functions where aggregates previously existed; confusion between the function and aggregate namespaces.","solutions":["Pick a different name for the new function","Drop the aggregate first with DROP AGGREGATE if it is no longer needed","Note that OR REPLACE does not bypass this check - a name change or drop is required"],"exampleFix":"// before\nCREATE OR REPLACE FUNCTION ks.avg(int) ...   -- ks.avg(int) is an aggregate\n// after\nDROP AGGREGATE IF EXISTS ks.avg(int);\nCREATE FUNCTION ks.avg(int) ...","handlingStrategy":"validation","validationCode":"ResultSet rs = session.execute(\"SELECT function_name FROM system_schema.aggregates WHERE keyspace_name = ? AND aggregate_name = ?\", ks, fn);\nif (!rs.all().isEmpty()) throw new IllegalStateException(\"Name collides with an aggregate: \" + fn);","typeGuard":null,"tryCatchPattern":"try { session.execute(stmt); } catch (InvalidRequestException e) { if (e.getMessage().contains(\"cannot replace an aggregate\")) { /* rename function or drop aggregate */ } else throw e; }","preventionTips":["Check system_schema.aggregates when reusing names","Never assume OR REPLACE can convert an aggregate into a function","Keep naming conventions distinct for aggregates and functions"],"tags":["cql","udf","aggregate","conflict"],"backgroundTag":"file-already-exists","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}