SELECT
  'CREATE FUNCTION ' 
  || quote_ident(p.proname)
  || '(' 
  || pg_get_function_arguments(p.oid)
  || ') RETURNS ' 
  || CASE WHEN proretset THEN 'SETOF ' ELSE '' END 
  || prorettype::regtype::text 
  || ' LANGUAGE '
  || lanname
  || CASE provolatile WHEN 'i' THEN ' IMMUTABLE' 
                      WHEN 's' THEN ' STABLE' 
                      WHEN 'v' THEN '' -- VOLATILE is DEFAULT
                      ELSE '' END 
  || CASE WHEN proisstrict THEN ' STRICT' ELSE '' END 
  || CASE WHEN (procost != 1   and lanname = 'internal') OR
               (procost != 100 and lanname = 'sql')
          THEN ' COST ' 
          || procost::text
          ELSE '' END
  || CASE WHEN proretset and prorows != 1000   --- 1000 is the DEFAULT
          THEN ' ROWS '
          || prorows::text
          ELSE '' END
  || ' AS '
  || CASE WHEN prolang = 12 THEN '''' ELSE '$$' END
  || prosrc
  || CASE WHEN prolang = 12 THEN '''' ELSE '$$' END
  || ' WITH (OID='
  || p.oid::text
  || ');'
  || CASE WHEN description IS NOT NULL 
          THEN E'\nCOMMENT ON FUNCTION '
          || p.oid::regprocedure::text
          || ' IS '
          || quote_literal(description)
          || ';'
          ELSE '' END
  || E'\n'
FROM pg_proc p 
    join pg_language l on (p.prolang = l.oid)
     left outer join pg_description d on (d.objoid=p.oid and d.classoid='pg_proc'::regclass)
WHERE p.oid < 10000
    AND lanname in ('sql', 'internal')      /* Builtin And SQL Functions */
    AND p.oid not in (                      /* Type serialization functions */
        SELECT unnest(array[typinput, typoutput, typreceive, typsend, typmodin, 
                    typmodout, typanalyze]) 
        FROM pg_type)
    AND p.oid not in (                      /* Operator functions */
        SELECT unnest(array[oprcode, oprrest, oprjoin])
        FROM pg_operator)
    AND not proisagg                        /* Aggregates */      
    AND p.oid not in (
        SELECT unnest(array[aggtransfn, aggfinalfn, aggmtransfn, aggminvtransfn, aggmfinalfn])
        FROM pg_aggregate)
    AND p.oid not in (                      /* Access Methods */
        SELECT unnest(array[aminsert, ambeginscan, amgettuple, amgetbitmap, amrescan,
                    amendscan, ammarkpos, amrestrpos, ambuild, ambuildempty, ambulkdelete,
                    amvacuumcleanup, amcanreturn, amcostestimate, amoptions])
        FROM pg_am)
    AND p.oid not in (SELECT amproc from pg_amproc)
    AND p.oid not in (                     /* Ranges */
        SELECT unnest(array[rngcanonical, rngsubdiff]) from pg_range)
    AND p.oid not in (                     /* Parsers */
        SELECT unnest(array[prsstart,prstoken,prsend,prsheadline,prslextype])
        FROM pg_ts_parser)
    AND p.oid not in (SELECT unnest(array[tmplinit, tmpllexize]) from pg_ts_template)
    AND p.oid not in (                     /* Language Validators */
        SELECT unnest(array[lanvalidator,laninline,lanplcallfoid]) 
        FROM pg_language)
    AND prorettype != 'anyenum'::regtype   /* Enum is special */
    AND 'anyenum'::regtype not in (SELECT unnest(proargtypes))
    AND not proiswindow                    /* Window Functions */
order by p.prolang, p.oid
;

