PostgreSQL raises the duplicate function error (code 42723) when you try to CREATE a function with the same name and parameter types as an existing function. Use CREATE OR REPLACE FUNCTION to update existing functions or DROP the old one first.
PostgreSQL enforces uniqueness on function names combined with their parameter types (signature). When you attempt to create a new function with `CREATE FUNCTION` and a function with identical name and argument types already exists in the same schema, PostgreSQL rejects the operation with error code 42723. This is a safety mechanism to prevent accidental function definition conflicts. PostgreSQL allows function overloading (same name, different parameters), but two functions cannot share both the same name and identical parameter signatures.
Query the pg_proc system catalog to see if your function is already defined:
SELECT proname, pg_get_functiondef(oid)
FROM pg_proc
WHERE proname = 'your_function_name'
AND pg_catalog.pg_function_is_visible(oid);Replace your_function_name with the name of the function you're trying to create. If results appear, the function exists.
If you want to update an existing function, use CREATE OR REPLACE FUNCTION instead of CREATE FUNCTION:
CREATE OR REPLACE FUNCTION calculate_age(birth_date DATE)
RETURNS INT AS $$
BEGIN
RETURN DATE_PART('year', AGE(birth_date))::INT;
END;
$$ LANGUAGE plpgsql;This works as long as you don't change the function signature (name and parameter types). Note: You cannot change parameter names that were previously defined, but you can add new output parameters.
If you need to change the function signature (parameter types, count, or order), you must drop the old function first:
DROP FUNCTION IF EXISTS calculate_age(DATE);
CREATE FUNCTION calculate_age(birth_date DATE)
RETURNS INT AS $$
BEGIN
RETURN DATE_PART('year', AGE(birth_date))::INT;
END;
$$ LANGUAGE plpgsql;The IF EXISTS clause prevents errors if the function doesn't exist. Always specify the complete parameter list in the DROP statement.
Update your database migration scripts to check for function existence:
CREATE OR REPLACE FUNCTION calculate_age(birth_date DATE)
RETURNS INT AS $$
BEGIN
RETURN DATE_PART('year', AGE(birth_date))::INT;
END;
$$ LANGUAGE plpgsql;Or use conditional drops:
DROP FUNCTION IF EXISTS old_function_name(INT, TEXT) CASCADE;
CREATE FUNCTION new_function_name(id INT, name TEXT)
RETURNS VOID AS $$
BEGIN
-- function body
END;
$$ LANGUAGE plpgsql;The CASCADE keyword drops dependent objects (views, triggers, etc.) automatically.
If the function is used in triggers, views, or other objects, dropping it may fail:
DROP FUNCTION IF EXISTS your_function(param_types) CASCADE;Using CASCADE drops all dependent objects, but verify nothing critical depends on the old function. If it's used in multiple places, update those references to use the new function signature, then drop the old one with CASCADE.
Function overloading: PostgreSQL supports multiple functions with the same name as long as they have different parameter types. For example, you can have both calculate_age(DATE) and calculate_age(TIMESTAMP) in the same schema. PostgreSQL uses the parameter types to determine which version to call. When using CREATE OR REPLACE, you must maintain the exact parameter signature; PostgreSQL won't let you change parameter types, count, or order. Owned functions: When you drop and recreate a function, it becomes a different database object with separate permissions and ownership. If the function is referenced in rules, views, or triggers, those relationships break. Use CREATE OR REPLACE when possible to preserve object relationships. Schema namespace: Functions exist within a schema. If you have multiple schemas, you might have functions with the same name in different schemas without conflict. Always specify the schema if working with non-public schemas: CREATE OR REPLACE FUNCTION schema_name.function_name().
ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL