Pgpool-II version
4.8devel (1a873669), backend_clustering_mode = raw, connection_cache = on, one configured PostgreSQL node.
Description
Without an explicit BEGIN, a pipeline that creates a temporary table with ON COMMIT DROP and then queries it succeeds on direct PostgreSQL. Through Pgpool, an extra Sync commits the implicit transaction before the later query, so ON COMMIT DROP removes the table and the query fails with UndefinedTable. The client sends only one Sync, after the later query; Pgpool inserts another one before forwarding that query's Parse.
In Parse(), Pgpool sends Sync whenever the backend is not already in an explicit transaction:
if (TSTATE(backend, MAIN_NODE_ID) != 'T')
{
/* <snip> */
send_extended_protocol_message(backend, i, "S", 0, "");
}
The current Parse() path later forwards the frontend Parse through pool_extended_send_and_wait(). The injected Sync therefore ends the transaction containing the preceding temporary-table creation.
Reproduce
Start PostgreSQL 16 and Pgpool-II in the configuration above, install psycopg, and run:
import psycopg
def run(label, dsn):
conn = psycopg.connect(dsn, autocommit=True)
try:
with conn.pipeline() as pipeline:
create = conn.cursor()
select = conn.cursor()
create.execute("CREATE TEMP TABLE scm_tmp(i int) ON COMMIT DROP")
select.execute("SELECT count(*) FROM scm_tmp")
pipeline.sync()
print(f"{label}: {select.fetchone()[0]}")
except Exception as exc:
print(f"{label}: {type(exc).__name__}: {exc}")
finally:
conn.close()
run("direct", DIRECT_DSN)
run("pgpool", PGPOOL_DSN)
Expected behavior
Both endpoints should print 0. The temporary table is empty and remains available until the pipeline Sync.
Actual behavior
The direct endpoint prints 0. Pgpool raises an undefined-table error while executing the second statement:
direct: 0
pgpool: UndefinedTable: relation "scm_tmp" does not exist
LINE 1: SELECT count(*) FROM scm_tmp
^
Pgpool-II version
4.8devel(1a873669),backend_clustering_mode = raw,connection_cache = on, one configured PostgreSQL node.Description
Without an explicit
BEGIN, a pipeline that creates a temporary table withON COMMIT DROPand then queries it succeeds on direct PostgreSQL. Through Pgpool, an extraSynccommits the implicit transaction before the later query, soON COMMIT DROPremoves the table and the query fails withUndefinedTable. The client sends only oneSync, after the later query; Pgpool inserts another one before forwarding that query'sParse.In
Parse(), Pgpool sendsSyncwhenever the backend is not already in an explicit transaction:The current
Parse()path later forwards the frontendParsethroughpool_extended_send_and_wait(). The injectedSynctherefore ends the transaction containing the preceding temporary-table creation.Reproduce
Start PostgreSQL 16 and Pgpool-II in the configuration above, install
psycopg, and run:Expected behavior
Both endpoints should print
0. The temporary table is empty and remains available until the pipelineSync.Actual behavior
The direct endpoint prints
0. Pgpool raises an undefined-table error while executing the second statement: