Version
v0.1.57 (main 7594279, transaction pool mode with pub/sub enabled; pub_sub_channel_size = 100)
Description
A LISTEN followed by another command in one psycopg pipeline succeeds against PostgreSQL, but the transaction-pool endpoint reports an unexpected pipeline synchronization result instead of completing the pipeline. In the extended query protocol, ReadyForQuery terminates a Sync response, not an individual command (PostgreSQL protocol flow).
Transaction mode routes Command::Listen to the local listen() path. That path calls command_complete(), which sends both CommandComplete and ReadyForQuery before the client Sync (pub_sub.rs). Session mode instead forwards LISTEN through execute().
Reproduce
Run with psycopg 3 against a direct PostgreSQL endpoint and a PgDog transaction-pool endpoint. DIRECT_DSN and PGDOG_DSN refer to those endpoints.
import logging
import psycopg
logging.getLogger("psycopg").setLevel(logging.ERROR)
def run(label, dsn):
conn = psycopg.connect(dsn, autocommit=True)
try:
with conn.pipeline() as pipeline:
with conn.cursor() as cur:
cur.execute("LISTEN pgdog_pipeline_listen")
cur.execute("SELECT 1")
pipeline.sync()
print(f"{label}: {conn.execute('SELECT 42').fetchone()}")
except Exception as exc:
print(f"{label}: {type(exc).__name__}: {exc}")
finally:
conn.close()
run("direct", DIRECT_DSN)
run("pgdog", PGDOG_DSN)
Expected behavior
Both endpoints complete the pipeline and print:
direct: (42,)
pgdog: (42,)
Actual behavior
7594279 prints:
direct: (42,)
pgdog: InternalError: unexpected result status from query: PIPELINE_SYNC
Version
v0.1.57(main7594279, transaction pool mode with pub/sub enabled;pub_sub_channel_size = 100)Description
A
LISTENfollowed by another command in one psycopg pipeline succeeds against PostgreSQL, but the transaction-pool endpoint reports an unexpected pipeline synchronization result instead of completing the pipeline. In the extended query protocol,ReadyForQueryterminates aSyncresponse, not an individual command (PostgreSQL protocol flow).Transaction mode routes
Command::Listento the locallisten()path. That path callscommand_complete(), which sends bothCommandCompleteandReadyForQuerybefore the clientSync(pub_sub.rs). Session mode instead forwardsLISTENthroughexecute().Reproduce
Run with psycopg 3 against a direct PostgreSQL endpoint and a PgDog transaction-pool endpoint.
DIRECT_DSNandPGDOG_DSNrefer to those endpoints.Expected behavior
Both endpoints complete the pipeline and print:
Actual behavior
7594279prints: