Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

postgresql thread safety for temporary tables

This the syntax I use for creating a temporary table:

create temp table tmpTable (id bigint not null, primary key (id)) on commit drop;

I know this means that at the end of each transaction, this table will be dropped. My question is, if two or more threads on the same session create and insert values into a temporary table, will they each get their own instance or is the temporary instance shared across the session? If it's shared, is there a way to make it local per thread?

Thanks Netta

like image 635
netta Avatar asked May 15 '12 08:05

netta


1 Answers

Temporary tables are visible to all operations in the same session. So you cannot create a temporary table of the same name in the same session before you drop the one that exists (commit the transaction in your case).

You may want to use:

CREATE TEMP TABLE tmptbl IF NOT EXISTS ...

More about CREATE TABLE in the manual.


Unique temp tables

To make the temp table local per "thread" (in the same session) you need to use unique table names. One way would be to use an unbound SEQUENCE and dynamic SQL - in a procedural language like plpgsql or in a DO statement (which is basically the same without storing a function.

Run one:

CREATE SEQUENCE myseq;

Use:

DO $$
BEGIN
EXECUTE 'CREATE TABLE tmp' || nextval('myseq')  ||'(id int)';
END;
$$

To know the latest table name:

SELECT 'tmp' || currval('myseq');

Or put it all into a plpgsql function and return the table or reuse the table name.

All further SQL commands have to be executed dynamically, though, as plain SQL statements operate with hard coded identifiers. So, it is probably best, to put it all into a plpgsql function.


Unique ID to use same temp table

Another possible solution could be to use the same temp table for all threads in the same session and add a column thread_id to the table. Be sure to index the column, if you make heavy use of the feature. Then use a unique thread_id per thread (in the same session).

Once only:

CREATE SEQUENCE myseq;

Once per thread:

CREATE TEMP TABLE tmptbl(thread_id int, col1 int) IF NOT EXISTS;
my_id :=  nextval('myseq'); -- in plpgsql
-- else find another way to assign unique id per thread

SQL:

INSERT INTO tmptbl(thread_id, col1) VALUES
(my_id, 2), (my_id, 3), (my_id, 4);

SELECT * FROM tmptbl WHERE thread_id = my_id;
like image 185
Erwin Brandstetter Avatar answered Sep 21 '22 01:09

Erwin Brandstetter