1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Add more tests for utility commands in pipelines

This commit checks interactions with pipelines and implicit transaction
blocks for the following commands that have their own behaviors when
used in pipelines depending on their order in a pipeline and sync
requests:
- SET LOCAL
- REINDEX CONCURRENTLY
- VACUUM
- Subtransactions (SAVEPOINT, ROLLBACK TO SAVEPOINT)

These scenarios could be tested only with pgbench previously.  The
meta-commands of psql controlling pipelines make these easier to
implement, debug, and they can be run in a SQL script.

Author: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Discussion: https://postgr.es/m/CAO6_XqroE7JuMEm1sWz55rp9fAYX2JwmcP_3m_v51vnOFdsLiQ@mail.gmail.com
This commit is contained in:
Michael Paquier
2025-02-23 16:43:07 +09:00
parent f98765f0ce
commit a4e986ef5a
2 changed files with 184 additions and 0 deletions

View File

@ -585,5 +585,117 @@ PQsendQuery not allowed in pipeline mode
1
(1 row)
--
-- Pipelines and transaction blocks
--
-- SET LOCAL will issue a warning when modifying a GUC outside of a
-- transaction block. The change will still be valid as a pipeline
-- runs within an implicit transaction block. Sending a sync will
-- commit the implicit transaction block. The first command after a
-- sync will not be seen as belonging to a pipeline.
\startpipeline
SET LOCAL statement_timeout='1h' \bind \g
SHOW statement_timeout \bind \g
\syncpipeline
SHOW statement_timeout \bind \g
SET LOCAL statement_timeout='2h' \bind \g
SHOW statement_timeout \bind \g
\endpipeline
WARNING: SET LOCAL can only be used in transaction blocks
statement_timeout
-------------------
1h
(1 row)
statement_timeout
-------------------
0
(1 row)
statement_timeout
-------------------
2h
(1 row)
-- REINDEX CONCURRENTLY fails if not the first command in a pipeline.
\startpipeline
SELECT $1 \bind 1 \g
REINDEX TABLE CONCURRENTLY psql_pipeline \bind \g
SELECT $1 \bind 2 \g
\endpipeline
?column?
----------
1
(1 row)
ERROR: REINDEX CONCURRENTLY cannot run inside a transaction block
-- REINDEX CONCURRENTLY works if it is the first command in a pipeline.
\startpipeline
REINDEX TABLE CONCURRENTLY psql_pipeline \bind \g
SELECT $1 \bind 2 \g
\endpipeline
?column?
----------
2
(1 row)
-- Subtransactions are not allowed in a pipeline.
\startpipeline
SAVEPOINT a \bind \g
SELECT $1 \bind 1 \g
ROLLBACK TO SAVEPOINT a \bind \g
SELECT $1 \bind 2 \g
\endpipeline
ERROR: SAVEPOINT can only be used in transaction blocks
-- LOCK fails as the first command in a pipeline, as not seen in an
-- implicit transaction block.
\startpipeline
LOCK psql_pipeline \bind \g
SELECT $1 \bind 2 \g
\endpipeline
ERROR: LOCK TABLE can only be used in transaction blocks
-- LOCK succeeds as it is not the first command in a pipeline,
-- seen in an implicit transaction block.
\startpipeline
SELECT $1 \bind 1 \g
LOCK psql_pipeline \bind \g
SELECT $1 \bind 2 \g
\endpipeline
?column?
----------
1
(1 row)
?column?
----------
2
(1 row)
-- VACUUM works as the first command in a pipeline.
\startpipeline
VACUUM psql_pipeline \bind \g
\endpipeline
-- VACUUM fails when not the first command in a pipeline.
\startpipeline
SELECT 1 \bind \g
VACUUM psql_pipeline \bind \g
\endpipeline
?column?
----------
1
(1 row)
ERROR: VACUUM cannot run inside a transaction block
-- VACUUM works after a \syncpipeline.
\startpipeline
SELECT 1 \bind \g
\syncpipeline
VACUUM psql_pipeline \bind \g
\endpipeline
?column?
----------
1
(1 row)
-- Clean up
DROP TABLE psql_pipeline;

View File

@ -350,5 +350,77 @@ SELECT 1;
SELECT 1;
\endpipeline
--
-- Pipelines and transaction blocks
--
-- SET LOCAL will issue a warning when modifying a GUC outside of a
-- transaction block. The change will still be valid as a pipeline
-- runs within an implicit transaction block. Sending a sync will
-- commit the implicit transaction block. The first command after a
-- sync will not be seen as belonging to a pipeline.
\startpipeline
SET LOCAL statement_timeout='1h' \bind \g
SHOW statement_timeout \bind \g
\syncpipeline
SHOW statement_timeout \bind \g
SET LOCAL statement_timeout='2h' \bind \g
SHOW statement_timeout \bind \g
\endpipeline
-- REINDEX CONCURRENTLY fails if not the first command in a pipeline.
\startpipeline
SELECT $1 \bind 1 \g
REINDEX TABLE CONCURRENTLY psql_pipeline \bind \g
SELECT $1 \bind 2 \g
\endpipeline
-- REINDEX CONCURRENTLY works if it is the first command in a pipeline.
\startpipeline
REINDEX TABLE CONCURRENTLY psql_pipeline \bind \g
SELECT $1 \bind 2 \g
\endpipeline
-- Subtransactions are not allowed in a pipeline.
\startpipeline
SAVEPOINT a \bind \g
SELECT $1 \bind 1 \g
ROLLBACK TO SAVEPOINT a \bind \g
SELECT $1 \bind 2 \g
\endpipeline
-- LOCK fails as the first command in a pipeline, as not seen in an
-- implicit transaction block.
\startpipeline
LOCK psql_pipeline \bind \g
SELECT $1 \bind 2 \g
\endpipeline
-- LOCK succeeds as it is not the first command in a pipeline,
-- seen in an implicit transaction block.
\startpipeline
SELECT $1 \bind 1 \g
LOCK psql_pipeline \bind \g
SELECT $1 \bind 2 \g
\endpipeline
-- VACUUM works as the first command in a pipeline.
\startpipeline
VACUUM psql_pipeline \bind \g
\endpipeline
-- VACUUM fails when not the first command in a pipeline.
\startpipeline
SELECT 1 \bind \g
VACUUM psql_pipeline \bind \g
\endpipeline
-- VACUUM works after a \syncpipeline.
\startpipeline
SELECT 1 \bind \g
\syncpipeline
VACUUM psql_pipeline \bind \g
\endpipeline
-- Clean up
DROP TABLE psql_pipeline;