How to get a list of UDFs in Redshift? - amazon-redshift

Is there an easy way to get the list of all UDFs that are available in Redshift?
Moreover, I would like to find UDFs with parameter types and search for UDFs by name.

You can query the pg_proc table to get all the UDFs available.
Filter by name
You can filter by name using the proname column:
SELECT * FROM pg_proc WHERE proname ILIKE '%<name_here>%';
Filter by parameter type
You can filter by parameter types using the proargtypes column:
SELECT * FROM pg_proc WHERE proargtypes = 1043;
Here, 1043 is varchar as can be seen by querying the pg_type table:
SELECT * FROM pg_type WHERE typname ILIKE '%char%';
Filter by parameter name
You can also filter by parameter name using the proargnames column:
SELECT * FROM pg_proc WHERE proargnames = ARRAY['foo'];
References:
http://docs.aws.amazon.com/redshift/latest/dg/c_join_PG.html
http://www.postgresql.org/docs/8.0/static/catalog-pg-proc.html

Related

PostgreSQL information schema query for tables without a specific data type

I'm trying to write a PostgreSQL query to get all the tables (from a specified schema) which don't have any columns of a specific data type, for example, show all tables without any integer type columns. so far I can manage to get only the table names, the data types of the columns they have and their count but I feel like that's the wrong direction in order to get what I want. any help appreciated, thanks
SELECT Table_Name, Data_Type, COUNT(Data_Type)
FROM Information_schema.Columns
WHERE Table_Schema = 'project'
GROUP BY Table_Name, Data_Type
You'll want to start with the tables table and then use an EXISTS subquery:
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'project'
AND NOT EXISTS (
SELECT *
FROM information_schema.columns
WHERE column.table_schema = tables.table_schema
AND column.table_name = tables.table_name
AND data_type = 'integer'
)

How can I get a list of column definitions of the return type of a table returning function

I am working on postgres 12. I have some functions defined that have TABLE(...) as return values. I know how to query the information_schema and/or pg_proc to get the list of arguments of the function given its name and schema. I would like to do something similar for the return type when it is a TABLE, that is, to find a query, that when the function returns a set of records, will return a list of the ordinal position and oid (or name) for the columns of the return table.
Is that possible?
EDIT: I know of pg_get_function_result() which returns the text of the return definition as it is written in the function definition but I would have to parse that and i wonder if there is a simpler way.
pg_proc.prorettype will contain the OID of the table's type, so you can use:
select prorettype::regtype::text
from pg_proc
where proname = 'your_function';
to get the name of the type - which is also the name of the table.
To get all the columns, you can join pg_proc with pg_class to get the table's oid and then use that to find the columns.
select col.attname, col.attnum, format_type(col.atttypid, col.atttypmod) as data_type
from pg_attribute col
where not attisdropped
and attnum > 0
and attrelid in (select tbl.oid
from pg_class tbl
join pg_proc p on p.prorettype = tbl.reltype
where p.proname = 'your_function_name_here')
order by col.attnum
If you need to get the column names returned by a function defined as returns table(), they are available in the array pg_proc.proargnames for those that are defined as "out" parameters through proargmodes
select t.column_name, t.arg_type::regtype::text, t.col_num
from pg_proc p
cross join unnest(proargnames, proargmodes, proallargtypes) with ordinality as t(column_name, arg_mode, arg_type, col_num)
where p.proname = 'your_function_name_here'
and t.arg_mode = 't'
order by t.col_num;

How can I find point geometry typed tables from postgis?

I want to get all point geometry type tables from postgis. Can I use sql select for this operations.
I can select all tables from select * from information_schema.tables table.
And I can get all geometry columns like this:
SELECT type FROM geometry_columns;
This query returns "GEOMETRY"
But I want to select all tables hthat has POINT geometry type.
If I get your question right, you can just query it from information_schema with:
select distinct table_schema, table_name
from information_schema.columns
where data_type = 'point';
eg:
t=# create table p(i point);
CREATE TABLE
t=# select distinct table_schema,table_name from information_schema.columns where data_type = 'point';
table_schema | table_name
--------------+------------
postgres | p
(1 row)

Select columns of a particular data type in PostgreSQL

I am looking for a piece of information, but the table I'm looking at has dozens of columns, and I can't remember the exact name of the column. I only know that it is of a date type. Is there a way to select only date columns so that it will be easier to find the name of the column?
e.g.
SELECT * FROM "MySchema"."MyTable"
WHERE {column.data_type} = 'date'
You can use the information_schema.columns view:
select column_name
from information_schema.columns
where table_schema = 'MySchema' and table_name = 'MyTable' and data_type = 'date';
Now that you have the names of the columns of type date, you can use that information create a view that selects only the values of such columns.

How can I get a list of all functions stored in the database of a particular schema in PostgreSQL?

I want to be able to connect to a PostgreSQL database and find all of the functions for a particular schema.
My thought was that I could make some query to pg_catalog or information_schema and get a list of all functions, but I can't figure out where the names and parameters are stored. I'm looking for a query that will give me the function name and the parameter types it takes (and what order it takes them in).
Is there a way to do this?
\df <schema>.*
in psql gives the necessary information.
To see the query that's used internally connect to a database with psql and supply an extra "-E" (or "--echo-hidden") option and then execute the above command.
After some searching, I was able to find the information_schema.routines table and the information_schema.parameters tables. Using those, one can construct a query for this purpose. LEFT JOIN, instead of JOIN, is necessary to retrieve functions without parameters.
SELECT routines.routine_name, parameters.data_type, parameters.ordinal_position
FROM information_schema.routines
LEFT JOIN information_schema.parameters ON routines.specific_name=parameters.specific_name
WHERE routines.specific_schema='my_specified_schema_name'
ORDER BY routines.routine_name, parameters.ordinal_position;
If any one is interested here is what query is executed by psql on postgres 9.1:
SELECT n.nspname as "Schema",
p.proname as "Name",
pg_catalog.pg_get_function_result(p.oid) as "Result data type",
pg_catalog.pg_get_function_arguments(p.oid) as "Argument data types",
CASE
WHEN p.proisagg THEN 'agg'
WHEN p.proiswindow THEN 'window'
WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN 'trigger'
ELSE 'normal'
END as "Type"
FROM pg_catalog.pg_proc p
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE pg_catalog.pg_function_is_visible(p.oid)
AND n.nspname <> 'pg_catalog'
AND n.nspname <> 'information_schema'
ORDER BY 1, 2, 4;
You can get what psql runs for a backslash command by running psql with the -E flag.
There's a handy function, oidvectortypes, that makes this a lot easier.
SELECT format('%I.%I(%s)', ns.nspname, p.proname, oidvectortypes(p.proargtypes))
FROM pg_proc p INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid)
WHERE ns.nspname = 'my_namespace';
Credit to Leo Hsu and Regina Obe at Postgres Online for pointing out oidvectortypes. I wrote similar functions before, but used complex nested expressions that this function gets rid of the need for.
See related answer.
(edit in 2016)
Summarizing typical report options:
-- Compact:
SELECT format('%I.%I(%s)', ns.nspname, p.proname, oidvectortypes(p.proargtypes))
-- With result data type:
SELECT format(
'%I.%I(%s)=%s',
ns.nspname, p.proname, oidvectortypes(p.proargtypes),
pg_get_function_result(p.oid)
)
-- With complete argument description:
SELECT format('%I.%I(%s)', ns.nspname, p.proname, pg_get_function_arguments(p.oid))
-- ... and mixing it.
-- All with the same FROM clause:
FROM pg_proc p INNER JOIN pg_namespace ns ON (p.pronamespace = ns.oid)
WHERE ns.nspname = 'my_namespace';
NOTICE: use p.proname||'_'||p.oid AS specific_name to obtain unique names, or to JOIN with information_schema tables — see routines and parameters at #RuddZwolinski's answer.
The function's OID (see pg_catalog.pg_proc) and the function's specific_name (see information_schema.routines) are the main reference options to functions. Below, some useful functions in reporting and other contexts.
--- --- --- --- ---
--- Useful overloads:
CREATE FUNCTION oidvectortypes(p_oid int) RETURNS text AS $$
SELECT oidvectortypes(proargtypes) FROM pg_proc WHERE oid=$1;
$$ LANGUAGE SQL IMMUTABLE;
CREATE FUNCTION oidvectortypes(p_specific_name text) RETURNS text AS $$
-- Extract OID from specific_name and use it in oidvectortypes(oid).
SELECT oidvectortypes(proargtypes)
FROM pg_proc WHERE oid=regexp_replace($1, '^.+?([^_]+)$', '\1')::int;
$$ LANGUAGE SQL IMMUTABLE;
CREATE FUNCTION pg_get_function_arguments(p_specific_name text) RETURNS text AS $$
-- Extract OID from specific_name and use it in pg_get_function_arguments.
SELECT pg_get_function_arguments(regexp_replace($1, '^.+?([^_]+)$', '\1')::int)
$$ LANGUAGE SQL IMMUTABLE;
--- --- --- --- ---
--- User customization:
CREATE FUNCTION pg_get_function_arguments2(p_specific_name text) RETURNS text AS $$
-- Example of "special layout" version.
SELECT trim(array_agg( op||'-'||dt )::text,'{}')
FROM (
SELECT data_type::text as dt, ordinal_position as op
FROM information_schema.parameters
WHERE specific_name = p_specific_name
ORDER BY ordinal_position
) t
$$ LANGUAGE SQL IMMUTABLE;
Run below SQL query to create a view which will show all functions:
CREATE OR REPLACE VIEW show_functions AS
SELECT routine_name FROM information_schema.routines
WHERE routine_type='FUNCTION' AND specific_schema='public';
Get List of function_schema and function_name...
SELECT
n.nspname AS function_schema,
p.proname AS function_name
FROM
pg_proc p
LEFT JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE
n.nspname NOT IN ('pg_catalog', 'information_schema')
ORDER BY
function_schema,
function_name;
Is a good idea named the functions with commun alias on the first words for filtre the name with LIKE
Example with public schema in Postgresql 9.4, be sure to replace with his scheme
SELECT routine_name
FROM information_schema.routines
WHERE routine_type='FUNCTION'
AND specific_schema='public'
AND routine_name LIKE 'aliasmyfunctions%';
Example:
perfdb-# \df information_schema.*;
List of functions
Schema | Name | Result data type | Argument data types | Type
information_schema | _pg_char_max_length | integer | typid oid, typmod integer | normal
information_schema | _pg_char_octet_length | integer | typid oid, typmod integer | normal
information_schema | _pg_datetime_precision| integer | typid oid, typmod integer | normal
.....
information_schema | _pg_numeric_scale | integer | typid oid, typmod integer | normal
information_schema | _pg_truetypid | oid | pg_attribute, pg_type | normal
information_schema | _pg_truetypmod | integer | pg_attribute, pg_type | normal
(11 rows)
This function returns all user defined routines in current database.
SELECT pg_get_functiondef(p.oid) FROM pg_proc p
INNER JOIN pg_namespace ns ON p.pronamespace = ns.oid
WHERE ns.nspname = 'public';
The joins in abovementioned answers returns not only input parameters, but also outputs. So it is necessary to specify also parameter_mode. This select will return list of functions with its input parametrs (if having some). Postgres 14.
select r.routine_name, array_agg(p.data_type::text order by p.ordinal_position) from information_schema.routines r left join information_schema.parameters p on r.specific_name = p.specific_name
where r.routine_type = 'FUNCTION' and r.specific_schema = 'schema_name' and (p.parameter_mode = 'IN' or p.parameter_mode is null)
group by r.routine_name order by r.routine_name;