When I do a \dt in psql I only get a listing of tables in the current schema (public by default).
How can I get a list of all tables in all schemas or a particular schema?
In all schemas:
=> \dt *.*
In a particular schema:
=> \dt public.*
It is possible to use regular expressions with some restrictions
\dt (public|s).(s|t)
List of relations
Schema | Name | Type | Owner
--------+------+-------+-------
public | s | table | cpn
public | t | table | cpn
s | t | table | cpn
Advanced users can use regular-expression notations such as character classes, for example [0-9] to match any digit. All regular expression special characters work as specified in Section 9.7.3, except for . which is taken as a separator as mentioned above, * which is translated to the regular-expression notation .*, ? which is translated to ., and $ which is matched literally. You can emulate these pattern characters at need by writing ? for ., (R+|) for R*, or (R|) for R?. $ is not needed as a regular-expression character since the pattern must match the whole name, unlike the usual interpretation of regular expressions (in other words, $ is automatically appended to your pattern). Write * at the beginning and/or end if you don't wish the pattern to be anchored. Note that within double quotes, all regular expression special characters lose their special meanings and are matched literally. Also, the regular expression special characters are matched literally in operator name patterns (i.e., the argument of \do).
You can select the tables from information_schema
SELECT * FROM information_schema.tables
WHERE table_schema = 'public'
Alternatively to information_schema it is possible to use pg_tables:
select * from pg_tables where schemaname='public';
For those coming across this in the future:
If you would like to see a list of relations for several schemas:
$psql mydatabase
mydatabase=# SET search_path TO public, usa; #schema examples
SET
mydatabase=# \dt
List of relations
Schema | Name | Type | Owner
--------+-----------------+-------+----------
public | counties | table | postgres
public | spatial_ref_sys | table | postgres
public | states | table | postgres
public | us_cities | table | postgres
usa | census2010 | table | postgres
If you are interested in listing all tables in a particular schema, I found this answer relevant :
SELECT table_schema||'.'||table_name AS full_rel_name
FROM information_schema.tables
WHERE table_schema = 'yourschemaname';
Related
is there any way to get the source code of the newly customized data type?
After sometime, I forgot the meaning of the newly created data type...
postgres=# \dT+ twoints
List of data types
Schema | Name | Internal name | Size | Elements | Owner | Access privileges | Description
--------+---------+---------------+-------+----------+----------+-------------------+-------------
public | twoints | twoints | tuple | | postgres | |
\dT+ seems don't give much info about the customized data type...
Also tried the pg_type catelog.
https://www.postgresql.org/docs/current/catalog-pg-type.html
typinput regproc (references pg_proc.oid)
Input conversion function (text format)
maybe typinput can help me, but I don't know.
through pgadmin4.
databases >> postgres >> schema >> Types >> twoints, right click CREATE Script
I'm using pgAdmin 4.23, PostgreSQL 12.3 for Windows
Looks like all functions are dumped into one "folder". I installed the uuid and tablefunc extensions and they get tossed in with my own user defined functions. At least the 10 uuid ones are all prefixed with "uuid_". The 11 tablefunc ones all start with "connectby", "crosstab"*, "normal_rand".
I did prefix my own functions so those at least grouped together. But as this thing grows and I add extensions, I'm concerned that maintenance will become more difficult. Is there some sort of sub-foldering option I am missing, or is naming convention the normal approach for organization? Looks like stored procs would work the same way.
Would also be nice to be able to filter the Functions based on the names. I see the Search Objects popup, but it isn't as useful as a filter.
To filter functions based on their names you can use this function:
CREATE OR REPLACE FUNCTION public.find_function(fname text DEFAULT NULL::text)
RETURNS TABLE(routine_name text, routine_schema text, return_type text)
LANGUAGE sql
AS $function$
select routine_name, routine_schema, data_type
from information_schema.routines
where specific_schema not in ('pg_catalog', 'information_schema')
and case when fname is null then true else routine_name ~* fname end
order by routine_name;
$function$;
Here is an example - find all functions that have "test" in their name:
select * from find_function('test');
+-----------------------------+----------------+-------------+
| routine_name | routine_schema | return_type |
+-----------------------------+----------------+-------------+
| clear_web_tests | datavato | void |
+-----------------------------+----------------+-------------+
| etl_generic_tests | webaccess | text |
+-----------------------------+----------------+-------------+
| fill_web_tests | datavato | void |
+-----------------------------+----------------+-------------+
| pan_arguments_test | helpers | jsonb |
+-----------------------------+----------------+-------------+
| test_bizday | public | boolean |
+-----------------------------+----------------+-------------+
| test_checkdigits | public | boolean |
+-----------------------------+----------------+-------------+
| test_jasper_dynamic_columns | scratch | record |
+-----------------------------+----------------+-------------+
I'm adding this here in case it helps for future searches...
Per #horse_with_no_name's suggestion above, and the official documentation I went with a separate schema for my third-party stuff. Here is a bit from conversation with the other db people in our company:
I didn't want third party extensions (like uuid-ossp for Guids)
installed in my public schema since that is where we keep all of our
user defined functions specific to that database. When I originally
installed the extension I put it into the public schema, then just
transferred it to a schema named extfunc. Then we have a table named
usr that references extfunc.uuid_generate_v4() in one of the column
constraints. Everything works as expected.
However, when I try to backup our Dev db and restore to QA, the
pg_dump and pg_restore tasks do not handle it properly. The restore
would error and not create the usr table. The extension was not being
properly restored to extfunc, which prevented the usr table from being
created.
The solution is to create the extension in the desired schema from the
start. Do not create it and try and move it to the destination
schema. Backup/restore now work as expected.
When using the PostgreSQL cli I can run \dT and see a list of my defined ENUMs
postgres=# \dT
List of data types
Schema | Name | Description
--------+----------------------+-------------
public | collection_qualifier |
public | image_class |
public | profile_type |
(3 rows)
There is a Description column, but I do not see any way to add a comment to type.
Is this possible?
Use comment on
comment on type profile_type is 'The type for profiles'
Can you give me suggestion to create table with starting with digits in postgresql.
use double quotes, eg:
t=# create table "42 Might be not The be$t idea" (i serial);
CREATE TABLE
t=# \d+ "42 Might be not The be$t idea"
Table "public.42 Might be not The be$t idea"
Column | Type | Modifiers | Storage | Stats target | Descript
ion
--------+---------+-----------------------------------------------------------------------------+---------+--------------+---------
----
i | integer | not null default nextval('"42 Might be not The be$t idea_i_seq"'::regclass) | plain | |
Please look close at what it leads to. Generally using mixed case, special characters and starting relation from number is kept a bad practice. Despite the fact that Postgres understands and works with such relation names, you have a risk to hit the bug with other software.
Without an experience you most probably shoot yourself in the foot. Eg pg_dump -t "badName" won't work. Bash will understand double quotes as own - and it is meant to work this way. So you have to specify pg_dump -t '"badName"' to find the table. And if you just fail to find a table you are lucky. Disaster is when you have badname and Badname in same schema.
The fact that it is doable does not mean you should jump into using it.
I'm trying to fix an issue with a legacy database. The quote_literal function is not working for a specific database on an 8.4 install of postgres.
Here's my results on a fresh test database:
select quote_literal(42);
quote_literal
---------------
'42'
(1 row)
And now the same on the target db
select quote_literal(42);
ERROR: function quote_literal(integer) is not unique
LINE 1: select quote_literal(42);
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
AIUI, the quote_literal(anyvalue) function should handle integer values ok, and this seems to be upheld by the first test.
So I figured the quote_literal function must have been overridden in this db but no this doesn't seem to be the case. I could override it with a specific quote_literal(integer) function but I don't see why I should have to.
The question is what is could be causing the failure of this function in this specific database whilst not affecting the fresh db?
Another possibility: Somebody has added implicit casts from text to your database. This was a common workaround for an intentional BC break in 8.3. See the release notes for 8.3, E.57.2. Migration to Version 8.3
Demo:
regress=# \df quote_literal
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+---------------+------------------+---------------------+--------
pg_catalog | quote_literal | text | anyelement | normal
pg_catalog | quote_literal | text | text | normal
(2 rows)
regress=# CREATE FUNCTION pg_catalog.text(integer) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int4out($1));';
CREATE FUNCTION
regress=# CREATE CAST (integer AS text) WITH FUNCTION pg_catalog.text(integer) AS IMPLICIT;
CREATE CAST
regress=# SELECT quote_literal(42);
ERROR: function quote_literal(integer) is not unique
LINE 1: SELECT quote_literal(42);
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
regress=#
This'll fix it, but probably break other code that's still relying on the cast:
regress=# DROP CAST (integer AS text);
DROP CAST
regress=# SELECT quote_literal(42);
quote_literal
---------------
'42'
(1 row)
Somebody has probably defined another single-argument quote_literal function with an argument type that's assignment-compatible to integer, like bigint.
In psql, connect and run:
\df quote_literal
and you'll see multiple entries, like this:
regress=> \df quote_literal
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+---------------+------------------+---------------------+--------
pg_catalog | quote_literal | text | anyelement | normal
pg_catalog | quote_literal | text | text | normal
public | quote_literal | text | bigint | normal
(3 rows)
You only want the 1st two, in pg_catalog. However, I can't advise you to just:
DROP FUNCTION public.quote_literal(bigint);
... because you might have code that expects it to exist. Time to go digging and see where it's used. Have fun.
Demo showing that this is likely the problem:
regress=> SELECT quote_literal(42);
quote_literal
---------------
'42'
(1 row)
regress=> CREATE OR REPLACE FUNCTION quote_literal(bigint) RETURNS text AS 'SELECT ''borkborkbork''::text;' LANGUAGE sql;
CREATE FUNCTION
regress=> SELECT quote_literal(42);
ERROR: function quote_literal(integer) is not unique
LINE 1: SELECT quote_literal(42);
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
regress=>