Visitar URL original
Pgpool injects `Sync` before a pipelined `Parse` and drops temporary tables · Issue #174 · pgpool/pgpool2 · GitHub
Skip to content

Pgpool injects Sync before a pipelined Parse and drops temporary tables #174

Description

@apkipa

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
                             ^

Activity

  1. self-assigned this
    on Sep 2, 2026
  2. koshino-235 commented on Sep 9, 2026

    @koshino-235
    Collaborator

    Thank you for the detailed report and reproducer.
    I’ve prepared the attached patch to address this issue. It tracks whether Pgpool-II is waiting for the frontend’s Sync and prevents subsequent Parse messages in the same pipeline from triggering an internal Sync. This keeps the implicit transaction open until the client sends Sync.
    The patch also handles transaction consistency when a pipeline involves multiple backend nodes, so that an error causes the preceding changes to be rolled back.

    Could you please apply the patch and check whether it resolves the issue in your environment?

    v8-0001-Fix-premature-Sync-during-extended-query-pipeline.patch

  3. apkipa commented on Sep 9, 2026

    @apkipa
    Author

    Thanks again for the patch, it works well for my single backend setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions