]> git.ipfire.org Git - thirdparty/psycopg.git/commit
Add pipeline_communicate() generator
authorDenis Laxalde <denis.laxalde@dalibo.com>
Mon, 11 Oct 2021 09:35:06 +0000 (11:35 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sat, 2 Apr 2022 23:17:57 +0000 (01:17 +0200)
commit6ba95ce8f57462412e9c94162c555e3cbdb08cca
tree672a4b03b386015bc705013e45a2286c5175d849
parent68c377d90d945cd2647b9e2a69682df8146b0bc2
Add pipeline_communicate() generator

This generator will be used as the send operations during execute()
step when the connection is in pipeline mode. It can consume results or
send queries depending on socket read/write ready state. Queries to be
sent are in a queue of Callable[[], None] which are built from partial
application of pgconn.send_query() and similar functions.

We add a couple of unit tests, in test_generators.py along with a test
script is taken from PostgreSQL sources. It demonstrates the use of
pipeline mode where query-send and results-fetch steps are interleaved
without any sync point emitted. (In this test, this works because the
output buffer gets full.) The test writes data to logs. Typically, we'd
get:

    enter pipeline
    sent BEGIN TRANSACTION
    sent DROP TABLE IF EXISTS pq_pipeline_demo
    sent CREATE UNLOGGED TABLE pq_pipeline_demo( id serial primary key, itemno integer, int8filler int8)
    prepare INSERT INTO pq_pipeline_demo(itemno, int8filler) VALUES ($1, $2) as 'prepare'
    sent prepared 'prepare' with [b'10000', b'4611686018427387904']
    sent prepared 'prepare' with [b'9999', b'4611686018427387904']
    sent prepared 'prepare' with [b'9998', b'4611686018427387904']
    sent prepared 'prepare' with [b'9997', b'4611686018427387904']
    sent prepared 'prepare' with [b'9996', b'4611686018427387904']
    sent prepared 'prepare' with [b'9995', b'4611686018427387904']
    sent prepared 'prepare' with [b'9994', b'4611686018427387904']
    sent prepared 'prepare' with [b'9993', b'4611686018427387904']
    sent prepared 'prepare' with [b'9992', b'4611686018427387904']
    ...
    sent prepared 'prepare' with [b'9690', b'4611686018427387904']
    sent prepared 'prepare' with [b'9689', b'4611686018427387904']
    sent prepared 'prepare' with [b'9688', b'4611686018427387904']
    got COMMAND_OK results
    got COMMAND_OK results
    got COMMAND_OK results
    got COMMAND_OK results
    got COMMAND_OK results
    got COMMAND_OK results
    got COMMAND_OK results
    got COMMAND_OK results
    got COMMAND_OK results
    ...
    got COMMAND_OK results
    got COMMAND_OK results
    sent prepared 'prepare' with [b'9687', b'4611686018427387904']
    sent prepared 'prepare' with [b'9686', b'4611686018427387904']
    sent prepared 'prepare' with [b'9685', b'4611686018427387904']
    sent prepared 'prepare' with [b'9684', b'4611686018427387904']
    sent prepared 'prepare' with [b'9683', b'4611686018427387904']
    ...
    sent prepared 'prepare' with [b'2', b'4611686018427387904']
    sent prepared 'prepare' with [b'1', b'4611686018427387904']
    sent COMMIT
    pipeline sync sent
    got COMMAND_OK results
    got COMMAND_OK results
    got COMMAND_OK results
    got COMMAND_OK results
    ...
    got COMMAND_OK results
    got COMMAND_OK results
    got PIPELINE_SYNC results
    exit pipeline

We can see that commands are sent, until the output buffer is full (the
connection is then Read-ready only), then results are fetched, until
more commands can be sent, and the cycle repeat.
psycopg/psycopg/abc.py
psycopg/psycopg/generators.py
psycopg_c/psycopg_c/_psycopg.pyi
psycopg_c/psycopg_c/_psycopg/generators.pyx
tests/fix_psycopg.py
tests/scripts/pipeline-demo.py [new file with mode: 0644]
tests/test_generators.py [new file with mode: 0644]