As you might know, you can create temporary tables, views and sequences in PostgreSQL. Temporary means, that the temporary table, view or sequence will be dropped when you either end your session or you transaction. When the drop will happen depends on the options you used when you created the object. As all objects in PostgreSQL are stored in a schema, temporary objects need to be created in a schema as well. But when you try to explicitly specify a schema for a temporary object, you’ll get an error message. Let’s have a look.
To confirm that we are not allowed to specify a schema for a temporary object, we try to do so:
postgres=# create temporary table public.tt ( a int ); ERROR: cannot create temporary relation in non-temporary schema LINE 1: create temporary table public.tt ( a int ); ^
The error message clearly states that these types of objects need to go into a temporary schema, but a temporary schema cannot be created:
postgres=# \h create schema Command: CREATE SCHEMA Description: define a new schema Syntax: CREATE SCHEMA schema_name [ AUTHORIZATION role_specification ] [ schema_element [ ... ] ] CREATE SCHEMA AUTHORIZATION role_specification [ schema_element [ ... ] ] CREATE SCHEMA IF NOT EXISTS schema_name [ AUTHORIZATION role_specification ] CREATE SCHEMA IF NOT EXISTS AUTHORIZATION role_specification where role_specification can be: user_name | CURRENT_ROLE | CURRENT_USER | SESSION_USER URL: https://www.postgresql.org/docs/devel/sql-createschema.html
This somehow needs to happen automatically. Once more, let’s create a temporary table, but this time we do not specify a schema:
postgres=# create temporary table tt ( a int ); CREATE TABLE
Where did it go to? If we ask for the list of schemas there is only public, and we already know from the error message above that it cannot be public:
postgres=# \dn List of schemas Name | Owner --------+------------------- public | pg_database_owner (1 row)
The answer becomes clear once we list the system schemas as well:
postgres=# \dnS List of schemas Name | Owner --------------------+------------------- information_schema | postgres pg_catalog | postgres pg_temp_3 | postgres pg_toast | postgres pg_toast_temp_3 | postgres public | pg_database_owner (6 rows)
We got two new schema after we created the temporary table: One for the temporary table itself and another one for toasted data, if any. To verify that the temporary table really is in the schema we can either full reference the table in a select:
postgres=# select * from pg_temp_3.tt; a --- (0 rows)
… or we can always ask pg_class:
postgres=# select relnamespace::regnamespace from pg_class where relname = 'tt'; relnamespace -------------- pg_temp_3 (1 row)
This temporary schema will not be dropped once we end our session and will still be there if we reconnect. The temporary table, however, was dropped:
postgres=# \q 14:52:39 postgres@debian11pg:/home/postgres/ [pgdev] psql psql (16devel) Type "help" for help. postgres=# \dnS List of schemas Name | Owner --------------------+------------------- information_schema | postgres pg_catalog | postgres pg_temp_3 | postgres pg_toast | postgres pg_toast_temp_3 | postgres public | pg_database_owner (6 rows) postgres=# select * from pg_temp_3.tt; ERROR: relation "pg_temp_3.tt" does not exist LINE 1: select * from pg_temp_3.tt; ^
The temporary schema will be re-used for future temporary objects:
postgres=# create temporary table xx ( a int ); CREATE TABLE postgres=# select relnamespace::regnamespace from pg_class where relname = 'xx'; relnamespace -------------- pg_temp_3 (1 row)
One more thing to know: If someone, in another session, also creates a temporary object there will be a new temporary schema created:
postgres@debian11pg:/home/postgres/ [pgdev] psql psql (16devel) Type "help" for help. postgres=# create temporary table hh ( a int ); CREATE TABLE postgres=# \dnS List of schemas Name | Owner --------------------+------------------- information_schema | postgres pg_catalog | postgres pg_temp_3 | postgres pg_temp_4 | postgres pg_toast | postgres pg_toast_temp_3 | postgres pg_toast_temp_4 | postgres public | pg_database_owner (8 rows) postgres=#
This means, that you potentially can have many temporary schemas.