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

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