martyw.dev

Note ·

TIL that CREATE TEMPORARY TABLE in Postgres takes an ON COMMIT clause:

CREATE TEMP TABLE staging (id bigint, payload jsonb) ON COMMIT DROP;

Three settings. PRESERVE ROWS is the default and keeps the table around for the whole session. DELETE ROWS truncates it at every commit. DROP bins the table itself at the end of the transaction that created it, which is almost always what I actually wanted — a scratch table for one bulk load or one gnarly multi-step query, gone the moment I’m done with it. No cleanup step, no DROP TABLE IF EXISTS at the top guarding against whatever the last run left lying around.

Postgres deviates from the standard here, incidentally: SQL says the default should be DELETE ROWS, and Postgres went with PRESERVE ROWS.

The thing that made it click was PgBouncer’s feature map, which lists ON COMMIT DROP temp tables as working under transaction pooling and PRESERVE/DELETE ROWS as “Never”. Of course it does — in transaction pooling the server connection goes back in the pool after each commit, so anything session-scoped either leaks into someone else’s transaction or vanishes. Scope the table to the transaction and there’s nothing left to leak.

Comments