Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DROP FUNCTION without knowing the number/type of parameters?

I keep all my functions in a text file with 'CREATE OR REPLACE FUNCTION somefunction'.
So if I add or change some function I just feed the file to psql.

Now if I add or remove parameters to an existing function, it creates an overload with the same name and to delete the original I need type in all the parameter types in the exact order which is kind of tedious.

Is there some kind of wildcard I can use to DROP all functions with a given name so I can just add DROP FUNCTION lines to the top of my file?

like image 635
Steinthor.palsson Avatar asked Oct 01 '11 20:10

Steinthor.palsson


People also ask

What is the syntax of drop function?

The DROP FUNCTION statement is used to drop a stored function or a user-defined function (UDF). That is, the specified routine is removed from the server, along with all privileges specific to the function. You must have the ALTER ROUTINE privilege for the routine in order to drop it.

What is drop function?

Description. DROP FUNCTION removes the definition of an existing function. To execute this command the user must be the owner of the function. The argument types to the function must be specified, since several different functions can exist with the same name and different argument lists.


1 Answers

Basic query

This query creates all necessary DDL statements:

SELECT 'DROP FUNCTION ' || oid::regprocedure FROM   pg_proc WHERE  proname = 'my_function_name'  -- name without schema-qualification AND    pg_function_is_visible(oid);  -- restrict to current search_path 

Output:

DROP FUNCTION my_function_name(string text, form text, maxlen integer); DROP FUNCTION my_function_name(string text, form text); DROP FUNCTION my_function_name(string text); 

Execute the commands after checking plausibility.

Pass the function name case-sensitive and with no added double-quotes to match against pg_proc.proname.

The cast to the object identifier type regprocedure (oid::regprocedure), and then to text implicitly, produces function names with argument types, automatically double-quoted and schema-qualified according to the current search_path where needed. No SQL injection possible.

pg_function_is_visible(oid) restricts the selection to functions in the current search_path ("visible"). You may or may not want this.

If you have multiple functions of the same name in multiple schemas, or overloaded functions with various function arguments, all of those will be listed separately. You may want to restrict to specific schema(s) or specific function parameter(s).

Related:

  • When / how are default value expression functions bound with regard to search_path?

Function

You can build a plpgsql function around this to execute the statements immediately with EXECUTE. For Postgres 9.1 or later: Careful! It drops your functions!

CREATE OR REPLACE FUNCTION f_delfunc(_name text, OUT functions_dropped int)    LANGUAGE plpgsql AS $func$ -- drop all functions with given _name in the current search_path, regardless of function parameters DECLARE    _sql text; BEGIN    SELECT count(*)::int         , 'DROP FUNCTION ' || string_agg(oid::regprocedure::text, '; DROP FUNCTION ')    FROM   pg_catalog.pg_proc    WHERE  proname = _name    AND    pg_function_is_visible(oid)  -- restrict to current search_path    INTO   functions_dropped, _sql;     -- count only returned if subsequent DROPs succeed     IF functions_dropped > 0 THEN       -- only if function(s) found      EXECUTE _sql;    END IF; END $func$; 

Call:

SELECT f_delfunc('my_function_name'); 

The function returns the number of functions found and dropped if no exceptions are raised. 0 if none were found.

Further reading:

  • How does the search_path influence identifier resolution and the "current schema"
  • Truncating all tables in a Postgres database
  • PostgreSQL parameterized Order By / Limit in table function

For Postgres versions older than 9.1 or older variants of the function using regproc and pg_get_function_identity_arguments(oid) check the edit history of this answer.

like image 169
Erwin Brandstetter Avatar answered Oct 25 '22 12:10

Erwin Brandstetter