232

How to print functions and triggers sourcecode in postgresql? please let me know if any one know the query to display the function, triggers source code.

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
ganesh
  • 2,369
  • 2
  • 15
  • 5
  • 12
    as a note for followers who got here trying to figure out how to list all triggers, it's `select * from pg_trigger;` or, if you also want to see which table each trigger applies to `select tgrelid::regclass, tgname from pg_trigger;` FWIW ` – rogerdpack Oct 01 '14 at 17:33
  • 6
    The `\sf` (explanation [below](https://stackoverflow.com/a/38341540/287948)) is the best way to see function's source code. – Peter Krauss Nov 17 '21 at 07:34

9 Answers9

215

\df+ in psql gives you the sourcecode.

mkobit
  • 43,979
  • 12
  • 156
  • 150
Mateusz Grotek
  • 2,607
  • 1
  • 14
  • 8
  • 29
    Nice one :) I suggest using `\df` to find the name of your function, then `\x` for expanded output, then `\df+ name_of_function` – Sam Watkins Sep 03 '14 at 07:47
  • 59
    \df+ outputs a lot more than the code. If all you want is the code, \sf will do the trick! – Telic May 10 '17 at 22:47
  • 1
    How to see **functions of an installed EXTENSION?** Example I am using [ltree](https://www.postgresql.org/docs/current/static/ltree.html), but there are no response with `\df ltxtquery`. – Peter Krauss Jan 04 '18 at 19:02
  • 2
    `\x ON` is a must for transposed display – andilabs Jun 15 '20 at 12:49
  • why \sf+ Coalesce wrote me ERROR: function "Coalesce" does not exist – El_L Feb 03 '23 at 05:28
160

For function:

you can query the pg_proc view , just as the following

select proname,prosrc from pg_proc where proname= your_function_name; 

Another way is that just execute the commont \df and \ef which can list the functions.

skytf=> \df           
                                             List of functions
 Schema |         Name         | Result data type |              Argument data types               |  Type  
--------+----------------------+------------------+------------------------------------------------+--------
 public | pg_buffercache_pages | SETOF record     |                                                | normal


skytf=> \ef  pg_buffercache_pages

It will show the source code of the function.

For triggers:

I dont't know if there is a direct way to get the source code. Just know the following way, may be it will help you!

  • step 1 : Get the table oid of the trigger:
    skytf=> select tgrelid from pg_trigger  where tgname='insert_tbl_tmp_trigger';
      tgrelid
    ---------
       26599
    (1 row)
  • step 2: Get the table name of the above oid !
    skytf=> select oid,relname  from pg_class where oid=26599;
      oid  |           relname           
    -------+-----------------------------
     26599 | tbl_tmp
    (1 row)
  • step 3: list the table information
    skytf=> \d tbl_tmp

It will show you the details of the trigger of the table . Usually a trigger uses a function. So you can get the source code of the trigger function just as the above that I pointed out !

regilero
  • 29,806
  • 6
  • 60
  • 99
francs
  • 8,511
  • 7
  • 39
  • 43
62

Here are few examples from PostgreSQL-9.5

Display list:

  1. Functions: \df+
  2. Triggers : \dy+

Display Definition:

postgres=# \sf
function name is required

postgres=# \sf pg_reload_conf()
CREATE OR REPLACE FUNCTION pg_catalog.pg_reload_conf()
 RETURNS boolean
 LANGUAGE internal
 STRICT
AS $function$pg_reload_conf$function$

postgres=# \sf pg_encoding_to_char
CREATE OR REPLACE FUNCTION pg_catalog.pg_encoding_to_char(integer)
 RETURNS name
 LANGUAGE internal
 STABLE STRICT
AS $function$PG_encoding_to_char$function$
Sathish
  • 12,453
  • 3
  • 41
  • 59
  • 10
    Using `\x` first to turn on expanded display also helps with readability. – Pocketsand Jun 29 '18 at 13:09
  • This was helpful -- thanks! -- though oddly including the parens (e.g., `\sf shared.is_authorized()`) failed with `function ... does not exist` while omitting the parens worked fine (e.g., `\sf shared.is_authorized`). (psql 12.9) – Glenn Dec 07 '21 at 12:55
32

There are many possibilities. Simplest way is to just use pgAdmin and get this from SQL window. However if you want to get this programmatically then examinate pg_proc and pg_trigger system catalogs or routines and triggers views from information schema (that's SQL standard way, but it might not cover all features especially PostgreSQL-specific). For example:

SELECT
    routine_definition 
FROM
    information_schema.routines 
WHERE
    specific_schema LIKE 'public'
    AND routine_name LIKE 'functionName';
Grzegorz Szpetkowski
  • 36,988
  • 6
  • 90
  • 137
  • 3
    Mmmm.. I have PGPSQL functions, that have an empty routine_defintion, and state 'EXTERNAL' in the field routine_body. Any hint where i can find those? – alfonx Jan 12 '12 at 22:44
  • 2
    +1 This is more standard/portable solution. For views the SQL is: `SELECT view_definition FROM information_schema.views WHERE table_schema = ? AND table_name = ?` – Franta Mar 01 '15 at 10:25
  • But what about the case where a function name is not unique because someone made functions with the same name and different function arguments? https://stackoverflow.com/questions/47341513/postgresql-how-to-display-function-or-trigger-or-view-code-for-a-unique-item – mg1075 Nov 17 '17 at 01:00
  • 1
    @alfonx see `pgproc.prosrc` column – Tomáš Záluský Apr 01 '19 at 14:19
  • I happy with this solution but is there any reason why use ``LIKE`` oprator? – Ray Ronnaret Aug 19 '22 at 11:34
21

Slightly more than just displaying the function, how about getting the edit in-place facility as well.

\ef <function_name> is very handy. It will open the source code of the function in editable format. You will not only be able to view it, you can edit and execute it as well.

Just \ef without function_name will open editable CREATE FUNCTION template.

For further reference -> https://www.postgresql.org/docs/9.6/static/app-psql.html

mythicalcoder
  • 3,143
  • 1
  • 32
  • 42
20

\sf function_name in psql yields editable source code of a single function.

From https://www.postgresql.org/docs/9.6/static/app-psql.html:

\sf[+] function_description This command fetches and shows the definition of the named function, in the form of a CREATE OR REPLACE FUNCTION command.

If + is appended to the command name, then the output lines are numbered, with the first line of the function body being line 1.

Sergey Tarasov
  • 858
  • 11
  • 18
  • 2
    shows the source code of a function. \ef function name opens it in editable templet – amar Apr 07 '19 at 06:25
  • 1
    This should absolutely be the accepted answer! It's just a three-character command - that's it. – Bill Jun 17 '22 at 17:12
14

additionally to @franc's answer you can use this from sql interface:

select 
    prosrc
from pg_trigger, pg_proc
where
 pg_proc.oid=pg_trigger.tgfoid
 and pg_trigger.tgname like '<name>'

(taken from here: http://www.postgresql.org/message-id/Pine.BSF.4.10.10009140858080.28013-100000@megazone23.bigpanda.com)

Andreas Covidiot
  • 4,286
  • 5
  • 51
  • 96
7

Since Version: psql (9.6.17, server 11.6)

I have tried all of above answer but For me

postgres=> \sf jsonb_extract_path_text
CREATE OR REPLACE FUNCTION pg_catalog.jsonb_extract_path_text(from_json jsonb, VARIADIC path_elems text[])
 RETURNS text
 LANGUAGE internal
 IMMUTABLE PARALLEL SAFE STRICT
AS $function$jsonb_extract_path_text$function$



postgres=> \df+
ERROR:  column p.proisagg does not exist
LINE 6:   WHEN p.proisagg THEN 'agg'
               ^
HINT:  Perhaps you meant to reference the column "p.prolang".

df seems not working for me.

Ravi Parekh
  • 5,253
  • 9
  • 46
  • 58
  • This seems to happen with an outdated version of psql, e. g. when `psql --version` prints a version like 10.x and the server is 11+ https://dba.stackexchange.com/a/238906 – Falco Preiseni Aug 28 '20 at 09:57
7

To list all functions:

select n.nspname as function_schema,
       p.proname as function_name,
       l.lanname as function_language,
       case when l.lanname = 'internal' then p.prosrc
            else pg_get_functiondef(p.oid)
            end as definition,
       pg_get_function_arguments(p.oid) as function_arguments,
       t.typname as return_type
from pg_proc p
left join pg_namespace n on p.pronamespace = n.oid
left join pg_language l on p.prolang = l.oid
left join pg_type t on t.oid = p.prorettype 
where n.nspname not in ('pg_catalog', 'information_schema')
order by function_schema,
             function_name;

Now if you want to search a specific word or text in all function is something like that, make sure you replace your text in the function:

with tbl as (
select n.nspname as function_schema,
       p.proname as function_name,
       l.lanname as function_language,
       case when l.lanname = 'internal' then p.prosrc
            else pg_get_functiondef(p.oid)
            end as definition,
       pg_get_function_arguments(p.oid) as function_arguments,
       t.typname as return_type
from pg_proc p
left join pg_namespace n on p.pronamespace = n.oid
left join pg_language l on p.prolang = l.oid
left join pg_type t on t.oid = p.prorettype 
where n.nspname not in ('pg_catalog', 'information_schema')
)
    select *
    from tbl
    where definition ilike '%word or text you want to search%'
    order by function_schema,
             function_name;
Blackcross
  • 79
  • 1
  • 2