I'm trying to figure when temporary tables are created and deleted.
I thought that a temporary table is dropped at the end of a session, but this test makes me unsure of that.
The connection string has Pooling=true;Maximum Pool Size=50
so there is pooling, with a max of 50 connections.
I run the following piece of code concurrently, 30 jobs at a time. I can see that there are 30 distinct process id values used (which makes me assume that a total of 30 connections are opened and reused) no matter how many times i run the code. So the pooling seems to work.
using (var connection = new NpgsqlConnection(connectionString))
{
var insertIds = GetInsertIds(1000).ToList();
await connection.OpenAsync();
var transaction = connection.BeginTransaction();
await connection.ExecuteAsync(@"
CREATE TEMP TABLE tmp_data
(
insertid INTEGER NOT NULL
);", transaction: transaction);
const string copyItemSql = @"
COPY tmp_data(
insertid
) FROM STDIN (FORMAT BINARY)
";
using (var writer = connection.BeginBinaryImport(copyItemSql))
{
foreach (var insertId in insertIds)
{
writer.StartRow();
writer.Write(insertId, NpgsqlDbType.Integer);
}
}
await connection.ExecuteAsync(@"
INSERT INTO data (insertid)
SELECT tmpd.insertid
FROM tmp_data tmpd;
", transaction: transaction);
transaction.Commit();
}
My assumptions where that:
- I would get an exception when a connection is taken from the pool and reused, because
tmp_data
already exists. This does not happen, the code runs just fine. - I could work around this by doing
CREATE TEMP TABLE IF NOT EXISTS tmp_data ...
. But then I would have the problem that sincetmp_data
already exists, there would still be rows from the previous insert. And I would be able to work around that by doingON COMMIT DELETE ROWS
.
So am I wrong about this? Isn't a connection in the pool the same thing as a session? Why doesn't the temp table exist the second time a connection is reused?