public inbox for [email protected]
help / color / mirror / Atom feedFrom: Michael Paquier <[email protected]>
To: Alexander Lakhin <[email protected]>
Cc: [email protected]
Subject: Re: BUG #19494: Error on transaction commit inside pipeline triggers psql's Assert
Date: Fri, 29 May 2026 14:00:20 +0900
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
On Fri, May 29, 2026 at 07:00:01AM +0300, Alexander Lakhin wrote:
> it's happening upon/after postgres process termination, so PQgetResult()
> returns NULL, pset.piped_syncs == 1. I need more time to look deeper and
> to come with a reproducer, but maybe you can already see what's wrong.
Yeah, I do. Nice catch. See this sequence to reproduce the problem:
\startpipeline
INSERT INTO psql_pipeline_defer VALUES (1), (1) \bind \sendpipeline
\syncpipeline
SELECT pg_terminate_backend(pg_backend_pid()) \bind \sendpipeline
SELECT 1 \bind \sendpipeline
\endpipeline
When ending the pipeline the loop consuming the results is stuck, so
we could check the connection state. We are going to enter in a
freeze of the branches due to beta1 next week, so let's take our time.
Please feel to use the v2 attached for your tests. I am also testing
it more on my side.
--
Michael
From c7e13a8826f25b3c99fe554f7e2c52a56bbea626 Mon Sep 17 00:00:00 2001
From: Michael Paquier <[email protected]>
Date: Fri, 29 May 2026 13:58:29 +0900
Subject: [PATCH v2] psql: Fix issues with deferred errors in pipelines
When an error is raised while processing a Sync message in a pipeline, e
like a deferred constraint violation, the error was not associated with
the piped command and was not counted in available_results. This caused
assertion failures in discardAbortedPipelineResults(), keeping an
incorrect state at pipeline exit, because the code assumed that
the number of available and requested results would always be positive,
expecting all the counters to be 0 at the end of a pipeline.
This commit switches discardAbortedPipelineResults() and
ExecQueryAndProcessResults() to take a softer approach when consuming
and draining the results after an error since the error generated by a
Sync are not tracked in the result counters (well, we could perhaps do
that, but I am not convinced that this is worth the complication).
The reporter has shown one problematic assertion failure. While
investigating more this issue I have bumped into two more. All these
cases are covered by the regression tests added in this commit, plus
some bonuses.
Reported-by: Alexander Lakhin <[email protected]>
Author: Michael Paquier <[email protected]>
Discussion: https://postgr.es/m/[email protected]
Backpatch-through: 18
---
src/bin/psql/common.c | 51 ++++++--
src/test/regress/expected/psql_pipeline.out | 124 ++++++++++++++++++++
src/test/regress/sql/psql_pipeline.sql | 63 ++++++++++
3 files changed, 227 insertions(+), 11 deletions(-)
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index 1a4e2ea0da82..c021eb97552a 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -1499,11 +1499,19 @@ discardAbortedPipelineResults(void)
}
else if (res == NULL)
{
- /* A query was processed, decrement the counters */
- Assert(pset.available_results > 0);
- Assert(pset.requested_results > 0);
- pset.available_results--;
- pset.requested_results--;
+ /*
+ * A query was processed, decrement the counters.
+ *
+ * It is possible to get here with available_results == 0 when an
+ * error is generated by the Sync message processing itself. Such
+ * errors are not counted in available_results because they are
+ * not associated with a piped command. In that case, skip the
+ * counter decrements and continue to find the Sync result.
+ */
+ if (pset.available_results > 0)
+ pset.available_results--;
+ if (pset.requested_results > 0)
+ pset.requested_results--;
}
if (pset.requested_results == 0)
@@ -2175,14 +2183,35 @@ ExecQueryAndProcessResults(const char *query,
if (end_pipeline)
{
- /* after a pipeline is processed, pipeline piped_syncs should be 0 */
- Assert(pset.piped_syncs == 0);
- /* all commands have been processed */
- Assert(pset.piped_commands == 0);
- /* all results were read */
- Assert(pset.available_results == 0);
+ /*
+ * Reset available/requested results. Normally these are already 0,
+ * but an error generated by a Sync processing itself can leave some
+ * of them behind. Consume them before exiting pipeline mode.
+ */
+ while (pset.piped_syncs > 0)
+ {
+ PGresult *remaining = PQgetResult(pset.db);
+
+ if (remaining == NULL)
+ {
+ if (!ConnectionUp())
+ break;
+ continue;
+ }
+ if (PQresultStatus(remaining) == PGRES_PIPELINE_SYNC)
+ pset.piped_syncs--;
+ PQclear(remaining);
+ }
+ pset.piped_syncs = 0;
+ pset.piped_commands = 0;
+ pset.available_results = 0;
+ pset.requested_results = 0;
+
+ if (PQpipelineStatus(pset.db) != PQ_PIPELINE_OFF)
+ PQexitPipelineMode(pset.db);
}
Assert(pset.requested_results == 0);
+
SetPipelineVariables();
/* may need this to recover from conn loss during COPY */
diff --git a/src/test/regress/expected/psql_pipeline.out b/src/test/regress/expected/psql_pipeline.out
index a0816fb10b68..a931d63cafe7 100644
--- a/src/test/regress/expected/psql_pipeline.out
+++ b/src/test/regress/expected/psql_pipeline.out
@@ -764,5 +764,129 @@ VACUUM psql_pipeline \bind \sendpipeline
1
(1 row)
+-- Deferred constraint violation at commit time in a pipeline.
+CREATE TABLE psql_pipeline_defer (a INTEGER PRIMARY KEY DEFERRABLE INITIALLY DEFERRED);
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) RETURNING * \bind 1 \sendpipeline
+\endpipeline
+ a
+---
+ 1
+ 1
+(2 rows)
+
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+-- Same with \syncpipeline and commands after the failing sync.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\endpipeline
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+ ?column?
+--------------
+ after_sync_1
+(1 row)
+
+-- More patterns with more \syncpipeline, more commands and \getresults
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\getresults
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+SELECT $1 \bind 'after_sync_2' \sendpipeline
+\endpipeline
+ ?column?
+--------------
+ after_sync_1
+(1 row)
+
+ ?column?
+--------------
+ after_sync_2
+(1 row)
+
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+\getresults
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\getresults
+SELECT $1 \bind 'after_sync_2' \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+SELECT $1 \bind 'after_sync_3' \sendpipeline
+SELECT $1 \bind 'after_sync_4' \sendpipeline
+SELECT $1 \bind 'after_sync_5' \sendpipeline
+\endpipeline
+ ?column?
+--------------
+ after_sync_1
+(1 row)
+
+ ?column?
+--------------
+ after_sync_2
+(1 row)
+
+ ?column?
+--------------
+ after_sync_3
+(1 row)
+
+ ?column?
+--------------
+ after_sync_4
+(1 row)
+
+ ?column?
+--------------
+ after_sync_5
+(1 row)
+
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+-- Deferred error combined with a regular command error after the sync.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind \sendpipeline
+SELECT $1 \bind 'after_error' \sendpipeline
+\endpipeline
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+ERROR: bind message supplies 0 parameters, but prepared statement "" requires 1
+-- Empty sync segment followed by a deferred error.
+\startpipeline
+\syncpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\endpipeline
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+-- Deferred error with \getresults reading results one at a time.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+SELECT $1 \bind 'partial' \sendpipeline
+\syncpipeline
+\getresults 1
+\getresults 1
+ ?column?
+----------
+ partial
+(1 row)
+
+\getresults
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+\endpipeline
+DROP TABLE psql_pipeline_defer;
-- Clean up
DROP TABLE psql_pipeline;
diff --git a/src/test/regress/sql/psql_pipeline.sql b/src/test/regress/sql/psql_pipeline.sql
index 6788dceee2e9..468ef1d090b6 100644
--- a/src/test/regress/sql/psql_pipeline.sql
+++ b/src/test/regress/sql/psql_pipeline.sql
@@ -438,5 +438,68 @@ SELECT 1 \bind \sendpipeline
VACUUM psql_pipeline \bind \sendpipeline
\endpipeline
+-- Deferred constraint violation at commit time in a pipeline.
+CREATE TABLE psql_pipeline_defer (a INTEGER PRIMARY KEY DEFERRABLE INITIALLY DEFERRED);
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) RETURNING * \bind 1 \sendpipeline
+\endpipeline
+
+-- Same with \syncpipeline and commands after the failing sync.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\endpipeline
+
+-- More patterns with more \syncpipeline, more commands and \getresults
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\getresults
+SELECT $1 \bind 'after_sync_2' \sendpipeline
+\endpipeline
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+\getresults
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\getresults
+SELECT $1 \bind 'after_sync_2' \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+SELECT $1 \bind 'after_sync_3' \sendpipeline
+SELECT $1 \bind 'after_sync_4' \sendpipeline
+SELECT $1 \bind 'after_sync_5' \sendpipeline
+\endpipeline
+
+-- Deferred error combined with a regular command error after the sync.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind \sendpipeline
+SELECT $1 \bind 'after_error' \sendpipeline
+\endpipeline
+
+-- Empty sync segment followed by a deferred error.
+\startpipeline
+\syncpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\endpipeline
+
+-- Deferred error with \getresults reading results one at a time.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+SELECT $1 \bind 'partial' \sendpipeline
+\syncpipeline
+\getresults 1
+\getresults 1
+\getresults
+\endpipeline
+
+DROP TABLE psql_pipeline_defer;
+
-- Clean up
DROP TABLE psql_pipeline;
--
2.54.0
Attachments:
[text/plain] v2-0001-psql-Fix-issues-with-deferred-errors-in-pipelines.patch (10.5K, 2-v2-0001-psql-Fix-issues-with-deferred-errors-in-pipelines.patch)
download | inline diff:
From c7e13a8826f25b3c99fe554f7e2c52a56bbea626 Mon Sep 17 00:00:00 2001
From: Michael Paquier <[email protected]>
Date: Fri, 29 May 2026 13:58:29 +0900
Subject: [PATCH v2] psql: Fix issues with deferred errors in pipelines
When an error is raised while processing a Sync message in a pipeline, e
like a deferred constraint violation, the error was not associated with
the piped command and was not counted in available_results. This caused
assertion failures in discardAbortedPipelineResults(), keeping an
incorrect state at pipeline exit, because the code assumed that
the number of available and requested results would always be positive,
expecting all the counters to be 0 at the end of a pipeline.
This commit switches discardAbortedPipelineResults() and
ExecQueryAndProcessResults() to take a softer approach when consuming
and draining the results after an error since the error generated by a
Sync are not tracked in the result counters (well, we could perhaps do
that, but I am not convinced that this is worth the complication).
The reporter has shown one problematic assertion failure. While
investigating more this issue I have bumped into two more. All these
cases are covered by the regression tests added in this commit, plus
some bonuses.
Reported-by: Alexander Lakhin <[email protected]>
Author: Michael Paquier <[email protected]>
Discussion: https://postgr.es/m/[email protected]
Backpatch-through: 18
---
src/bin/psql/common.c | 51 ++++++--
src/test/regress/expected/psql_pipeline.out | 124 ++++++++++++++++++++
src/test/regress/sql/psql_pipeline.sql | 63 ++++++++++
3 files changed, 227 insertions(+), 11 deletions(-)
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index 1a4e2ea0da82..c021eb97552a 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -1499,11 +1499,19 @@ discardAbortedPipelineResults(void)
}
else if (res == NULL)
{
- /* A query was processed, decrement the counters */
- Assert(pset.available_results > 0);
- Assert(pset.requested_results > 0);
- pset.available_results--;
- pset.requested_results--;
+ /*
+ * A query was processed, decrement the counters.
+ *
+ * It is possible to get here with available_results == 0 when an
+ * error is generated by the Sync message processing itself. Such
+ * errors are not counted in available_results because they are
+ * not associated with a piped command. In that case, skip the
+ * counter decrements and continue to find the Sync result.
+ */
+ if (pset.available_results > 0)
+ pset.available_results--;
+ if (pset.requested_results > 0)
+ pset.requested_results--;
}
if (pset.requested_results == 0)
@@ -2175,14 +2183,35 @@ ExecQueryAndProcessResults(const char *query,
if (end_pipeline)
{
- /* after a pipeline is processed, pipeline piped_syncs should be 0 */
- Assert(pset.piped_syncs == 0);
- /* all commands have been processed */
- Assert(pset.piped_commands == 0);
- /* all results were read */
- Assert(pset.available_results == 0);
+ /*
+ * Reset available/requested results. Normally these are already 0,
+ * but an error generated by a Sync processing itself can leave some
+ * of them behind. Consume them before exiting pipeline mode.
+ */
+ while (pset.piped_syncs > 0)
+ {
+ PGresult *remaining = PQgetResult(pset.db);
+
+ if (remaining == NULL)
+ {
+ if (!ConnectionUp())
+ break;
+ continue;
+ }
+ if (PQresultStatus(remaining) == PGRES_PIPELINE_SYNC)
+ pset.piped_syncs--;
+ PQclear(remaining);
+ }
+ pset.piped_syncs = 0;
+ pset.piped_commands = 0;
+ pset.available_results = 0;
+ pset.requested_results = 0;
+
+ if (PQpipelineStatus(pset.db) != PQ_PIPELINE_OFF)
+ PQexitPipelineMode(pset.db);
}
Assert(pset.requested_results == 0);
+
SetPipelineVariables();
/* may need this to recover from conn loss during COPY */
diff --git a/src/test/regress/expected/psql_pipeline.out b/src/test/regress/expected/psql_pipeline.out
index a0816fb10b68..a931d63cafe7 100644
--- a/src/test/regress/expected/psql_pipeline.out
+++ b/src/test/regress/expected/psql_pipeline.out
@@ -764,5 +764,129 @@ VACUUM psql_pipeline \bind \sendpipeline
1
(1 row)
+-- Deferred constraint violation at commit time in a pipeline.
+CREATE TABLE psql_pipeline_defer (a INTEGER PRIMARY KEY DEFERRABLE INITIALLY DEFERRED);
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) RETURNING * \bind 1 \sendpipeline
+\endpipeline
+ a
+---
+ 1
+ 1
+(2 rows)
+
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+-- Same with \syncpipeline and commands after the failing sync.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\endpipeline
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+ ?column?
+--------------
+ after_sync_1
+(1 row)
+
+-- More patterns with more \syncpipeline, more commands and \getresults
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\getresults
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+SELECT $1 \bind 'after_sync_2' \sendpipeline
+\endpipeline
+ ?column?
+--------------
+ after_sync_1
+(1 row)
+
+ ?column?
+--------------
+ after_sync_2
+(1 row)
+
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+\getresults
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\getresults
+SELECT $1 \bind 'after_sync_2' \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+SELECT $1 \bind 'after_sync_3' \sendpipeline
+SELECT $1 \bind 'after_sync_4' \sendpipeline
+SELECT $1 \bind 'after_sync_5' \sendpipeline
+\endpipeline
+ ?column?
+--------------
+ after_sync_1
+(1 row)
+
+ ?column?
+--------------
+ after_sync_2
+(1 row)
+
+ ?column?
+--------------
+ after_sync_3
+(1 row)
+
+ ?column?
+--------------
+ after_sync_4
+(1 row)
+
+ ?column?
+--------------
+ after_sync_5
+(1 row)
+
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+-- Deferred error combined with a regular command error after the sync.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind \sendpipeline
+SELECT $1 \bind 'after_error' \sendpipeline
+\endpipeline
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+ERROR: bind message supplies 0 parameters, but prepared statement "" requires 1
+-- Empty sync segment followed by a deferred error.
+\startpipeline
+\syncpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\endpipeline
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+-- Deferred error with \getresults reading results one at a time.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+SELECT $1 \bind 'partial' \sendpipeline
+\syncpipeline
+\getresults 1
+\getresults 1
+ ?column?
+----------
+ partial
+(1 row)
+
+\getresults
+ERROR: duplicate key value violates unique constraint "psql_pipeline_defer_pkey"
+DETAIL: Key (a)=(1) already exists.
+\endpipeline
+DROP TABLE psql_pipeline_defer;
-- Clean up
DROP TABLE psql_pipeline;
diff --git a/src/test/regress/sql/psql_pipeline.sql b/src/test/regress/sql/psql_pipeline.sql
index 6788dceee2e9..468ef1d090b6 100644
--- a/src/test/regress/sql/psql_pipeline.sql
+++ b/src/test/regress/sql/psql_pipeline.sql
@@ -438,5 +438,68 @@ SELECT 1 \bind \sendpipeline
VACUUM psql_pipeline \bind \sendpipeline
\endpipeline
+-- Deferred constraint violation at commit time in a pipeline.
+CREATE TABLE psql_pipeline_defer (a INTEGER PRIMARY KEY DEFERRABLE INITIALLY DEFERRED);
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) RETURNING * \bind 1 \sendpipeline
+\endpipeline
+
+-- Same with \syncpipeline and commands after the failing sync.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\endpipeline
+
+-- More patterns with more \syncpipeline, more commands and \getresults
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\getresults
+SELECT $1 \bind 'after_sync_2' \sendpipeline
+\endpipeline
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+\getresults
+SELECT $1 \bind 'after_sync_1' \sendpipeline
+\getresults
+SELECT $1 \bind 'after_sync_2' \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+SELECT $1 \bind 'after_sync_3' \sendpipeline
+SELECT $1 \bind 'after_sync_4' \sendpipeline
+SELECT $1 \bind 'after_sync_5' \sendpipeline
+\endpipeline
+
+-- Deferred error combined with a regular command error after the sync.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\syncpipeline
+SELECT $1 \bind \sendpipeline
+SELECT $1 \bind 'after_error' \sendpipeline
+\endpipeline
+
+-- Empty sync segment followed by a deferred error.
+\startpipeline
+\syncpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+\endpipeline
+
+-- Deferred error with \getresults reading results one at a time.
+\startpipeline
+INSERT INTO psql_pipeline_defer VALUES ($1), ($1) \bind 1 \sendpipeline
+SELECT $1 \bind 'partial' \sendpipeline
+\syncpipeline
+\getresults 1
+\getresults 1
+\getresults
+\endpipeline
+
+DROP TABLE psql_pipeline_defer;
+
-- Clean up
DROP TABLE psql_pipeline;
--
2.54.0
[application/pgp-signature] signature.asc (833B, 3-signature.asc)
download
view thread (10+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected]
Subject: Re: BUG #19494: Error on transaction commit inside pipeline triggers psql's Assert
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox