How can I detect if a Postgres temporary table already exists?

11,895

Solution 1

User Defined Function to check whether temp table exists.

CREATE or REPLACE FUNCTION public.iftableexists( varchar)
RETURNS pg_catalog.bool AS
$BODY$
DECLARE

 BEGIN

     /* check the table exist in database and is visible*/
 perform n.nspname ,c.relname
FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid
= c.relnamespace
where n.nspname like 'pg_temp_%' AND pg_catalog.pg_table_is_visible(c.oid)
AND Upper(relname) = Upper($1);

     IF FOUND THEN
        RETURN TRUE;
     ELSE
        RETURN FALSE;
     END IF;

 END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE

See here for more details

Solution 2

What I would like to do is only create the temporary table if it doesn't already exist.

CREATE TEMPORARY TABLE IF NOT EXISTS tester AS
  SELECT * FROM tester WHERE name='bananas';

Solution 3

This works for me:

SELECT EXISTS (
   SELECT 1
   FROM   information_schema.tables 
   WHERE  table_schema like 'pg_temp_%'
   AND table_name=LOWER('table_name')
)
Share:
11,895
KidTempo
Author by

KidTempo

Updated on June 06, 2022

Comments

  • KidTempo
    KidTempo almost 2 years

    I have a table called tester which I need to overlay with a temporary table in order to do some testing. So far I have managed that using:

    CREATE TEMPORARY TABLE tester AS
      SELECT * FROM tester WHERE name='bananas';
    

    This temporary table will disappear at the end of the session which is fine by me, however it is the external application that is responsible for the connection and it has a tendency to cache connections for reuse (thus there is no guarantee that the temporary table has been dropped). This means that if I try to execute the above query again it may fail because the temporary table still exists.

    Explicitly dropping the temporary table is not really an option. I'd rather live with the failed query than risk dropping the underlying "real" table by mistake.

    What I would like to do is only create the temporary table if it doesn't already exist. I did find this query which people suggested should be used when checking to see if a table exists:

    SELECT * FROM pg_catalog.pg_class WHERE relkind = 'r' AND relname = 'tester';
    
    result when temporary table exists:
    
     relname | relnamespace | reltype | relowner | relam | relfilenode | reltablespace | relpages | reltuples | reltoastrelid | reltoastidxid | relhasindex | relisshared | relkind | relnatts | relchecks | reltriggers | relukeys | relfkeys | relrefs | relhasoids | relhaspkey | relhasrules | relhassubclass | relfrozenxid | relacl | reloptions
    ---------+--------------+---------+----------+-------+-------------+---------------+----------+-----------+---------------+---------------+-------------+-------------+---------+----------+-----------+-------------+----------+----------+---------+------------+------------+-------------+----------------+--------------+--------+------------
     tester  |         2200 | 1533065 |  1531747 |     0 |     1533063 |             0 |        0 |         0 |       1533067 |             0 | t           | f           | r       |        3 |         0 |           0 |        0 |        0 |       0 | f          | t          | f           | f              |     17654031 |        |
     tester  |      1533088 | 1533065 |  1531747 |     0 |     1533160 |             0 |        0 |         0 |       1533163 |             0 | f           | f           | r       |        3 |         0 |           0 |        0 |        0 |       0 | f          | f          | f           | f              |     17654066 |        |
    

    As you can see, there are two records. One for the original table, and one for the temp table. The second record is the temporary table - I know this because it disappears when working in a different session - but other than the lack of an index or a primary key that's the only way I can identify it as being temporary. This is only a test table - some of the real tables I'm working with may lack indexes and/or primary keys.

    Question (tl;dr edition): How can I test if a temporary table exists if there is already a "real" table with the same name? (or at least identify that a table is temporary?)

    disclaimer: I added the Java tag because that's what I'm using to execute queries (the SQL is only a small part of the application). Even though Java is not directly relevant to the question, I kinda need than answer that I can use from a Java context.