public inbox for [email protected]  
help / color / mirror / Atom feed
repack: fix a bug to reject deferrable primary key fallback for concurrent mode
10+ messages / 6 participants
[nested] [flat]

* repack: fix a bug to reject deferrable primary key fallback for concurrent mode
@ 2026-04-17 03:35  Chao Li <[email protected]>
  0 siblings, 2 replies; 10+ messages in thread

From: Chao Li @ 2026-04-17 03:35 UTC (permalink / raw)
  To: pgsql-hackers

Hi,

I am continuing to test REPACK, and I found another issue.

In check_concurrent_repack_requirements(), if a table has no replica identity index, the code falls back to using the primary key if one exists. The problem is that a deferrable primary key cannot be used for this purpose. WAL generation does not consider a deferrable primary key to be a replica identity, so concurrent mode may not receive enough old tuple information to replay concurrent changes.

I tested this with the following procedure.

1 - Create a table
```
create table t (id int,  v text, primary key (id) deferrable initially deferred);
insert into t values (1, 'a');
```

2 -  Attach a debugger to session 1's backend process. I used vscode. Add a breakpoint at the first process_concurrent_changes() call. This blocks the REPACK process and gives session 2 time to issue a DELETE.

3 - In session 1, issue a repack, it will stop at the breakpoint
```
repack (concurrently) t;
```

4 - In session 2
```
delete from t where id=1;
```

5 - Detach session 1 from the debugger, so that repack continues and tries to re-apply the delete from session 2.

6 - repack fails with:
```
evantest=# repack (concurrently) t;
ERROR:  incomplete delete info
CONTEXT:  slot "repack_96468", output plugin "pgrepack", in the change callback, associated LSN 0/2A5717F0
REPACK decoding worker
```

The error comes from this code in pgrepack.c:
```
		case REORDER_BUFFER_CHANGE_DELETE:
			{
				HeapTuple	oldtuple;

				oldtuple = change->data.tp.oldtuple;

				if (oldtuple == NULL)
					elog(ERROR, "incomplete delete info");

				repack_store_change(ctx, relation, CHANGE_DELETE, oldtuple);
			}
			break;
```

The root cause is that repack.c assumes rel->rd_pkindex is usable as an identity index, but logical decoding does not treat a deferrable primary key as replica identity. As a result, the decoding worker may not get the old tuple needed to re-apply the delete.

To fix the problem, I think we should just not fall back to deferrable primary key in the first place. See the attached patch.

With this patch, repack will quickly for the test:
```
evantest=# repack (concurrently) t;
ERROR:  cannot process relation "t"
HINT:  Relation "t" has a deferrable primary key.
```

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/






Attachments:

  [application/octet-stream] v1-0001-Reject-deferrable-primary-key-fallback-in-REPACK-.patch (2.1K, 2-v1-0001-Reject-deferrable-primary-key-fallback-in-REPACK-.patch)
  download | inline diff:
From d67bb43755896909663daa62fb0ae19b32b9d75e Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <[email protected]>
Date: Fri, 17 Apr 2026 11:12:36 +0800
Subject: [PATCH v1] Reject deferrable primary key fallback in REPACK
 CONCURRENTLY

REPACK CONCURRENTLY uses logical decoding to collect concurrent
changes and then replays them on the new heap. To locate rows for
UPDATE and DELETE replay, it requires an identity index.

When RelationGetReplicaIndex() returned InvalidOid, the code fell
back to rel->rd_pkindex if a primary key existed. That is not safe for
deferrable primary keys. Such indexes are not considered replica
identity indexes by WAL generation, so logical decoding may not provide
the old tuple needed by the repack output plugin.

This can make replay fail later with errors such as "incomplete delete
info" from the decoding worker.

Prevent the fallback when the primary key is deferrable, and report the
problem during the initial REPACK CONCURRENTLY checks instead.

Author: Chao Li <[email protected]>
Reviewed-by:
Discussion: https://postgr.es/m/
---
 src/backend/commands/repack.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c
index 67364cc60e3..2c89cd17db4 100644
--- a/src/backend/commands/repack.c
+++ b/src/backend/commands/repack.c
@@ -926,7 +926,21 @@ check_concurrent_repack_requirements(Relation rel, Oid *ident_idx_p)
 	 */
 	ident_idx = RelationGetReplicaIndex(rel);
 	if (!OidIsValid(ident_idx) && OidIsValid(rel->rd_pkindex))
+	{
+		/*
+		 * A deferrable primary key is not considered a replica identity
+		 * index, so WAL may not contain the old tuple needed for replay.
+		 */
+		if (rel->rd_ispkdeferrable)
+			ereport(ERROR,
+					errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+					errmsg("cannot process relation \"%s\"",
+						   RelationGetRelationName(rel)),
+					errhint("Relation \"%s\" has a deferrable primary key.",
+							RelationGetRelationName(rel)));
+
 		ident_idx = rel->rd_pkindex;
+	}
 	if (!OidIsValid(ident_idx))
 		ereport(ERROR,
 				errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
-- 
2.50.1 (Apple Git-155)



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* RE: repack: fix a bug to reject deferrable primary key fallback for concurrent mode
@ 2026-04-17 03:46  Zhijie Hou (Fujitsu) <[email protected]>
  parent: Chao Li <[email protected]>
  1 sibling, 1 reply; 10+ messages in thread

From: Zhijie Hou (Fujitsu) @ 2026-04-17 03:46 UTC (permalink / raw)
  To: Chao Li <[email protected]>; pgsql-hackers

On Friday, April 17, 2026 11:35 AM Chao Li <[email protected]> wrote:
> I am continuing to test REPACK, and I found another issue.
> 
> In check_concurrent_repack_requirements(), if a table has no replica identity
> index, the code falls back to using the primary key if one exists. The problem is
> that a deferrable primary key cannot be used for this purpose. WAL
> generation does not consider a deferrable primary key to be a replica identity,
> so concurrent mode may not receive enough old tuple information to replay
> concurrent changes.
> 
> I tested this with the following procedure.
> 
...
> With this patch, repack will quickly for the test:
> ```
> evantest=# repack (concurrently) t;
> ERROR:  cannot process relation "t"
> HINT:  Relation "t" has a deferrable primary key.
> ```

Good catch!

I think we can use the existing API to identify the index, for example:

diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c
index 67364cc60e3..cc30236f493 100644
--- a/src/backend/commands/repack.c
+++ b/src/backend/commands/repack.c
@@ -62,6 +62,7 @@
 #include "miscadmin.h"
 #include "optimizer/optimizer.h"
 #include "pgstat.h"
+#include "replication/logicalrelation.h"
 #include "storage/bufmgr.h"
 #include "storage/lmgr.h"
 #include "storage/predicate.h"
@@ -924,9 +925,7 @@ check_concurrent_repack_requirements(Relation rel, Oid *ident_idx_p)
 	 * repack work with a FULL replica identity; however that requires more
 	 * work and is not implemented yet.
 	 */
-	ident_idx = RelationGetReplicaIndex(rel);
-	if (!OidIsValid(ident_idx) && OidIsValid(rel->rd_pkindex))
-		ident_idx = rel->rd_pkindex;
+	ident_idx = GetRelationIdentityOrPK();
 	if (!OidIsValid(ident_idx))
 		ereport(ERROR,
 				errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

And it would be better to add a test for this.

Best Regards,
Hou zj





^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: repack: fix a bug to reject deferrable primary key fallback for concurrent mode
@ 2026-04-17 06:17  Chao Li <[email protected]>
  parent: Zhijie Hou (Fujitsu) <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Chao Li @ 2026-04-17 06:17 UTC (permalink / raw)
  To: Zhijie Hou (Fujitsu) <[email protected]>; +Cc: pgsql-hackers



> On Apr 17, 2026, at 11:46, Zhijie Hou (Fujitsu) <[email protected]> wrote:
> 
> On Friday, April 17, 2026 11:35 AM Chao Li <[email protected]> wrote:
>> I am continuing to test REPACK, and I found another issue.
>> 
>> In check_concurrent_repack_requirements(), if a table has no replica identity
>> index, the code falls back to using the primary key if one exists. The problem is
>> that a deferrable primary key cannot be used for this purpose. WAL
>> generation does not consider a deferrable primary key to be a replica identity,
>> so concurrent mode may not receive enough old tuple information to replay
>> concurrent changes.
>> 
>> I tested this with the following procedure.
>> 
> ...
>> With this patch, repack will quickly for the test:
>> ```
>> evantest=# repack (concurrently) t;
>> ERROR:  cannot process relation "t"
>> HINT:  Relation "t" has a deferrable primary key.
>> ```
> 
> Good catch!
> 
> I think we can use the existing API to identify the index, for example:
> 
> diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c
> index 67364cc60e3..cc30236f493 100644
> --- a/src/backend/commands/repack.c
> +++ b/src/backend/commands/repack.c
> @@ -62,6 +62,7 @@
> #include "miscadmin.h"
> #include "optimizer/optimizer.h"
> #include "pgstat.h"
> +#include "replication/logicalrelation.h"
> #include "storage/bufmgr.h"
> #include "storage/lmgr.h"
> #include "storage/predicate.h"
> @@ -924,9 +925,7 @@ check_concurrent_repack_requirements(Relation rel, Oid *ident_idx_p)
> * repack work with a FULL replica identity; however that requires more
> * work and is not implemented yet.
> */
> - ident_idx = RelationGetReplicaIndex(rel);
> - if (!OidIsValid(ident_idx) && OidIsValid(rel->rd_pkindex))
> - ident_idx = rel->rd_pkindex;
> + ident_idx = GetRelationIdentityOrPK();
> if (!OidIsValid(ident_idx))
> ereport(ERROR,
> errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

Thanks for pointing out GetRelationIdentityOrPK(). Looks like it wraps RelationGetReplicaIndex and excludes deferrable primary key.

Switched to use GetRelationIdentityOrPK() in v2.

> 
> And it would be better to add a test for this.
> 

I didn’t add the test because I saw there was only 1 test case of checking catalog table in cluster.sql for repack(concurrently). As you asked, I added tests for all checks of check_concurrent_repack_requirements().

PFA v2.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/






Attachments:

  [application/octet-stream] v2-0001-Reject-deferrable-primary-key-fallback-in-REPACK-.patch (7.0K, 2-v2-0001-Reject-deferrable-primary-key-fallback-in-REPACK-.patch)
  download | inline diff:
From 6ced3f3010d778dd18dd962b48dbebd0ecebbda3 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <[email protected]>
Date: Fri, 17 Apr 2026 11:12:36 +0800
Subject: [PATCH v2] Reject deferrable primary key fallback in REPACK
 CONCURRENTLY

REPACK CONCURRENTLY uses logical decoding to collect concurrent
changes and then replays them on the new heap. To locate rows for
UPDATE and DELETE replay, it requires an identity index.

When RelationGetReplicaIndex() returned InvalidOid, the code fell
back to rel->rd_pkindex if a primary key existed. That is not safe for
deferrable primary keys. Such indexes are not considered replica
identity indexes by WAL generation, so logical decoding may not provide
the old tuple needed by the repack output plugin.

This can make replay fail later with errors such as "incomplete delete
info" from the decoding worker.

This change switches to use GetRelationIdentityOrPK() that excludes
deferrable primary key.

Author: Chao Li <[email protected]>
Reviewed-by: Zhijie Hou <[email protected]>
Discussion: https://postgr.es/m/[email protected]
---
 src/backend/commands/repack.c         | 15 +++++----
 src/test/regress/expected/cluster.out | 44 ++++++++++++++++++++++++++-
 src/test/regress/sql/cluster.sql      | 39 +++++++++++++++++++++++-
 3 files changed, 88 insertions(+), 10 deletions(-)

diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c
index 67364cc60e3..76d84180acc 100644
--- a/src/backend/commands/repack.c
+++ b/src/backend/commands/repack.c
@@ -62,6 +62,7 @@
 #include "miscadmin.h"
 #include "optimizer/optimizer.h"
 #include "pgstat.h"
+#include "replication/logicalrelation.h"
 #include "storage/bufmgr.h"
 #include "storage/lmgr.h"
 #include "storage/predicate.h"
@@ -919,14 +920,12 @@ check_concurrent_repack_requirements(Relation rel, Oid *ident_idx_p)
 
 	/*
 	 * Obtain the replica identity index -- either one that has been set
-	 * explicitly, or the primary key.  If none of these cases apply, the
-	 * table cannot be repacked concurrently.  It might be possible to have
-	 * repack work with a FULL replica identity; however that requires more
-	 * work and is not implemented yet.
-	 */
-	ident_idx = RelationGetReplicaIndex(rel);
-	if (!OidIsValid(ident_idx) && OidIsValid(rel->rd_pkindex))
-		ident_idx = rel->rd_pkindex;
+	 * explicitly, or a non-deferrable primary key.  If none of these cases
+	 * apply, the table cannot be repacked concurrently.  It might be possible
+	 * to have repack work with a FULL replica identity; however that requires
+	 * more work and is not implemented yet.
+	 */
+	ident_idx = GetRelationIdentityOrPK(rel);
 	if (!OidIsValid(ident_idx))
 		ereport(ERROR,
 				errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 6127b215a86..0ba87972712 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -806,10 +806,52 @@ ORDER BY o.relname;
  clstr_3
 (2 rows)
 
--- concurrently
+--
+-- Check concurrent mode requirements
+--
+-- Doesn't support catalog tables
 REPACK (CONCURRENTLY) pg_class;
 ERROR:  cannot repack relation "pg_class"
 HINT:  REPACK CONCURRENTLY is not supported for catalog relations.
+-- Only support permanent tables, temp and unlogged tables are not supported
+CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_temp;
+ERROR:  cannot repack relation "repack_conc_temp"
+HINT:  REPACK CONCURRENTLY is only allowed for permanent relations.
+DROP TABLE repack_conc_temp;
+CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_unlogged;
+ERROR:  cannot repack relation "repack_conc_unlogged"
+HINT:  REPACK CONCURRENTLY is only allowed for permanent relations.
+DROP TABLE repack_conc_unlogged;
+-- Doesn't support tables without a primary key or replica identity index
+CREATE TABLE repack_conc_noident (i int);
+REPACK (CONCURRENTLY) repack_conc_noident;
+ERROR:  cannot process relation "repack_conc_noident"
+HINT:  Relation "repack_conc_noident" has no identity index.
+DROP TABLE repack_conc_noident;
+-- Doesn't support TOAST tables directly
+CREATE TABLE repack_conc_toast (t text);
+SELECT reltoastrelid::regclass AS toast_rel
+FROM pg_class WHERE oid = 'repack_conc_toast'::regclass \gset
+\set VERBOSITY sqlstate
+REPACK (CONCURRENTLY) :toast_rel;
+ERROR:  0A000
+\set VERBOSITY default
+DROP TABLE repack_conc_toast;
+-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
+CREATE TABLE repack_conc_nothing (i int PRIMARY KEY);
+ALTER TABLE repack_conc_nothing REPLICA IDENTITY NOTHING;
+REPACK (CONCURRENTLY) repack_conc_nothing;
+ERROR:  cannot repack relation "repack_conc_nothing"
+HINT:  Relation "repack_conc_nothing" has insufficient replication identity.
+DROP TABLE repack_conc_nothing;
+-- Doesn't support tables with deferrable primary keys
+CREATE TABLE repack_conc_deferrable (i int PRIMARY KEY DEFERRABLE);
+REPACK (CONCURRENTLY) repack_conc_deferrable;
+ERROR:  cannot process relation "repack_conc_deferrable"
+HINT:  Relation "repack_conc_deferrable" has no identity index.
+DROP TABLE repack_conc_deferrable;
 -- clean up
 DROP TABLE clustertest;
 DROP TABLE clstr_1;
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index d14063a9683..99ff3739c60 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -386,9 +386,46 @@ JOIN relnodes_new n ON o.relname = n.relname
 WHERE o.relfilenode <> n.relfilenode
 ORDER BY o.relname;
 
--- concurrently
+--
+-- Check concurrent mode requirements
+--
+
+-- Doesn't support catalog tables
 REPACK (CONCURRENTLY) pg_class;
 
+-- Only support permanent tables, temp and unlogged tables are not supported
+CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_temp;
+DROP TABLE repack_conc_temp;
+CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_unlogged;
+DROP TABLE repack_conc_unlogged;
+
+-- Doesn't support tables without a primary key or replica identity index
+CREATE TABLE repack_conc_noident (i int);
+REPACK (CONCURRENTLY) repack_conc_noident;
+DROP TABLE repack_conc_noident;
+
+-- Doesn't support TOAST tables directly
+CREATE TABLE repack_conc_toast (t text);
+SELECT reltoastrelid::regclass AS toast_rel
+FROM pg_class WHERE oid = 'repack_conc_toast'::regclass \gset
+\set VERBOSITY sqlstate
+REPACK (CONCURRENTLY) :toast_rel;
+\set VERBOSITY default
+DROP TABLE repack_conc_toast;
+
+-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
+CREATE TABLE repack_conc_nothing (i int PRIMARY KEY);
+ALTER TABLE repack_conc_nothing REPLICA IDENTITY NOTHING;
+REPACK (CONCURRENTLY) repack_conc_nothing;
+DROP TABLE repack_conc_nothing;
+
+-- Doesn't support tables with deferrable primary keys
+CREATE TABLE repack_conc_deferrable (i int PRIMARY KEY DEFERRABLE);
+REPACK (CONCURRENTLY) repack_conc_deferrable;
+DROP TABLE repack_conc_deferrable;
+
 -- clean up
 DROP TABLE clustertest;
 DROP TABLE clstr_1;
-- 
2.50.1 (Apple Git-155)



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: repack: fix a bug to reject deferrable primary key fallback for concurrent mode
@ 2026-04-20 14:52  Antonin Houska <[email protected]>
  parent: Chao Li <[email protected]>
  1 sibling, 1 reply; 10+ messages in thread

From: Antonin Houska @ 2026-04-20 14:52 UTC (permalink / raw)
  To: Chao Li <[email protected]>; +Cc: pgsql-hackers

Chao Li <[email protected]> wrote:

> I am continuing to test REPACK, and I found another issue.
> 
> In check_concurrent_repack_requirements(), if a table has no replica identity index, the code falls back to using the primary key if one exists. The problem is that a deferrable primary key cannot be used for this purpose. WAL generation does not consider a deferrable primary key to be a replica identity, so concurrent mode may not receive enough old tuple information to replay concurrent changes.

Thanks for finding it, this is certainly a problem.

I'm just thinking if it's worth a separate error message.
RelationGetIndexList() just ignores the deferrable PK

	if (replident == REPLICA_IDENTITY_DEFAULT && OidIsValid(pkeyIndex) && !pkdeferrable)
		relation->rd_replidindex = pkeyIndex;

and if there's no other suitable index, the result is that there is no
identity index for the table. So the change attached here should be consistent
with this approach.

-- 
Antonin Houska
Web: https://www.cybertec-postgresql.com



Attachments:

  [text/x-diff] fix_identity_check.diff (594B, 2-fix_identity_check.diff)
  download | inline diff:
diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c
index 67364cc60e3..8cfc3fde5c7 100644
--- a/src/backend/commands/repack.c
+++ b/src/backend/commands/repack.c
@@ -925,7 +925,8 @@ check_concurrent_repack_requirements(Relation rel, Oid *ident_idx_p)
 	 * work and is not implemented yet.
 	 */
 	ident_idx = RelationGetReplicaIndex(rel);
-	if (!OidIsValid(ident_idx) && OidIsValid(rel->rd_pkindex))
+	if (!OidIsValid(ident_idx) && OidIsValid(rel->rd_pkindex) &&
+		!rel->rd_ispkdeferrable)
 		ident_idx = rel->rd_pkindex;
 	if (!OidIsValid(ident_idx))
 		ereport(ERROR,


^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: repack: fix a bug to reject deferrable primary key fallback for concurrent mode
@ 2026-04-21 02:38  Chao Li <[email protected]>
  parent: Antonin Houska <[email protected]>
  0 siblings, 1 reply; 10+ messages in thread

From: Chao Li @ 2026-04-21 02:38 UTC (permalink / raw)
  To: Antonin Houska <[email protected]>; +Cc: pgsql-hackers; Zhijie Hou (Fujitsu) <[email protected]>; Alvaro Herrera <[email protected]>



> On Apr 20, 2026, at 22:52, Antonin Houska <[email protected]> wrote:
> 
> Chao Li <[email protected]> wrote:
> 
>> I am continuing to test REPACK, and I found another issue.
>> 
>> In check_concurrent_repack_requirements(), if a table has no replica identity index, the code falls back to using the primary key if one exists. The problem is that a deferrable primary key cannot be used for this purpose. WAL generation does not consider a deferrable primary key to be a replica identity, so concurrent mode may not receive enough old tuple information to replay concurrent changes.
> 
> Thanks for finding it, this is certainly a problem.
> 
> I'm just thinking if it's worth a separate error message.
> RelationGetIndexList() just ignores the deferrable PK
> 
> if (replident == REPLICA_IDENTITY_DEFAULT && OidIsValid(pkeyIndex) && !pkdeferrable)
> relation->rd_replidindex = pkeyIndex;
> 
> and if there's no other suitable index, the result is that there is no
> identity index for the table. So the change attached here should be consistent
> with this approach.
> 
> -- 
> Antonin Houska
> Web: https://www.cybertec-postgresql.com
> 

Hi Antonin,

Thanks for your review. I guess you read the v1 patch. In v2, I have switched to use GetRelationIdentityOrPK() that Zhijie suggested, which has covered RelationGetIndexList() and all checks, so that code is simplified, and there is no longer a separate error message.

As CFBot asked for, rebased to v3, nothing changed from v2. Can you please take a look at v3 again?

BTW, could you please also take a look at [1] that is a comment-only change for repack.

[1] https://postgr.es/m/[email protected]

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/






Attachments:

  [application/octet-stream] v3-0001-Reject-deferrable-primary-key-fallback-in-REPACK-.patch (7.1K, 2-v3-0001-Reject-deferrable-primary-key-fallback-in-REPACK-.patch)
  download | inline diff:
From fdca43ea733a269a5fdb7621b26d16841eddb0c2 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <[email protected]>
Date: Fri, 17 Apr 2026 11:12:36 +0800
Subject: [PATCH v3] Reject deferrable primary key fallback in REPACK
 CONCURRENTLY

REPACK CONCURRENTLY uses logical decoding to collect concurrent
changes and then replays them on the new heap. To locate rows for
UPDATE and DELETE replay, it requires an identity index.

When RelationGetReplicaIndex() returned InvalidOid, the code fell
back to rel->rd_pkindex if a primary key existed. That is not safe for
deferrable primary keys. Such indexes are not considered replica
identity indexes by WAL generation, so logical decoding may not provide
the old tuple needed by the repack output plugin.

This can make replay fail later with errors such as "incomplete delete
info" from the decoding worker.

This change switches to use GetRelationIdentityOrPK() that excludes
deferrable primary key.

Author: Chao Li <[email protected]>
Reviewed-by: Zhijie Hou <[email protected]>
Reviewed-by: Antonin Houska <[email protected]>
Discussion: https://postgr.es/m/[email protected]
---
 src/backend/commands/repack.c         | 15 +++++----
 src/test/regress/expected/cluster.out | 44 ++++++++++++++++++++++++++-
 src/test/regress/sql/cluster.sql      | 39 +++++++++++++++++++++++-
 3 files changed, 88 insertions(+), 10 deletions(-)

diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c
index 67364cc60e3..76d84180acc 100644
--- a/src/backend/commands/repack.c
+++ b/src/backend/commands/repack.c
@@ -62,6 +62,7 @@
 #include "miscadmin.h"
 #include "optimizer/optimizer.h"
 #include "pgstat.h"
+#include "replication/logicalrelation.h"
 #include "storage/bufmgr.h"
 #include "storage/lmgr.h"
 #include "storage/predicate.h"
@@ -919,14 +920,12 @@ check_concurrent_repack_requirements(Relation rel, Oid *ident_idx_p)
 
 	/*
 	 * Obtain the replica identity index -- either one that has been set
-	 * explicitly, or the primary key.  If none of these cases apply, the
-	 * table cannot be repacked concurrently.  It might be possible to have
-	 * repack work with a FULL replica identity; however that requires more
-	 * work and is not implemented yet.
-	 */
-	ident_idx = RelationGetReplicaIndex(rel);
-	if (!OidIsValid(ident_idx) && OidIsValid(rel->rd_pkindex))
-		ident_idx = rel->rd_pkindex;
+	 * explicitly, or a non-deferrable primary key.  If none of these cases
+	 * apply, the table cannot be repacked concurrently.  It might be possible
+	 * to have repack work with a FULL replica identity; however that requires
+	 * more work and is not implemented yet.
+	 */
+	ident_idx = GetRelationIdentityOrPK(rel);
 	if (!OidIsValid(ident_idx))
 		ereport(ERROR,
 				errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 71270134985..e7cb89c5298 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -822,10 +822,52 @@ ORDER BY o.relname;
  clstr_3
 (2 rows)
 
--- concurrently
+--
+-- Check concurrent mode requirements
+--
+-- Doesn't support catalog tables
 REPACK (CONCURRENTLY) pg_class;
 ERROR:  cannot repack relation "pg_class"
 HINT:  REPACK CONCURRENTLY is not supported for catalog relations.
+-- Only support permanent tables, temp and unlogged tables are not supported
+CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_temp;
+ERROR:  cannot repack relation "repack_conc_temp"
+HINT:  REPACK CONCURRENTLY is only allowed for permanent relations.
+DROP TABLE repack_conc_temp;
+CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_unlogged;
+ERROR:  cannot repack relation "repack_conc_unlogged"
+HINT:  REPACK CONCURRENTLY is only allowed for permanent relations.
+DROP TABLE repack_conc_unlogged;
+-- Doesn't support tables without a primary key or replica identity index
+CREATE TABLE repack_conc_noident (i int);
+REPACK (CONCURRENTLY) repack_conc_noident;
+ERROR:  cannot process relation "repack_conc_noident"
+HINT:  Relation "repack_conc_noident" has no identity index.
+DROP TABLE repack_conc_noident;
+-- Doesn't support TOAST tables directly
+CREATE TABLE repack_conc_toast (t text);
+SELECT reltoastrelid::regclass AS toast_rel
+FROM pg_class WHERE oid = 'repack_conc_toast'::regclass \gset
+\set VERBOSITY sqlstate
+REPACK (CONCURRENTLY) :toast_rel;
+ERROR:  0A000
+\set VERBOSITY default
+DROP TABLE repack_conc_toast;
+-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
+CREATE TABLE repack_conc_nothing (i int PRIMARY KEY);
+ALTER TABLE repack_conc_nothing REPLICA IDENTITY NOTHING;
+REPACK (CONCURRENTLY) repack_conc_nothing;
+ERROR:  cannot repack relation "repack_conc_nothing"
+HINT:  Relation "repack_conc_nothing" has insufficient replication identity.
+DROP TABLE repack_conc_nothing;
+-- Doesn't support tables with deferrable primary keys
+CREATE TABLE repack_conc_deferrable (i int PRIMARY KEY DEFERRABLE);
+REPACK (CONCURRENTLY) repack_conc_deferrable;
+ERROR:  cannot process relation "repack_conc_deferrable"
+HINT:  Relation "repack_conc_deferrable" has no identity index.
+DROP TABLE repack_conc_deferrable;
 -- clean up
 DROP TABLE clustertest;
 DROP TABLE clstr_1;
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6746236ffec..e5e369050bb 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -393,9 +393,46 @@ JOIN relnodes_new n ON o.relname = n.relname
 WHERE o.relfilenode <> n.relfilenode
 ORDER BY o.relname;
 
--- concurrently
+--
+-- Check concurrent mode requirements
+--
+
+-- Doesn't support catalog tables
 REPACK (CONCURRENTLY) pg_class;
 
+-- Only support permanent tables, temp and unlogged tables are not supported
+CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_temp;
+DROP TABLE repack_conc_temp;
+CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_unlogged;
+DROP TABLE repack_conc_unlogged;
+
+-- Doesn't support tables without a primary key or replica identity index
+CREATE TABLE repack_conc_noident (i int);
+REPACK (CONCURRENTLY) repack_conc_noident;
+DROP TABLE repack_conc_noident;
+
+-- Doesn't support TOAST tables directly
+CREATE TABLE repack_conc_toast (t text);
+SELECT reltoastrelid::regclass AS toast_rel
+FROM pg_class WHERE oid = 'repack_conc_toast'::regclass \gset
+\set VERBOSITY sqlstate
+REPACK (CONCURRENTLY) :toast_rel;
+\set VERBOSITY default
+DROP TABLE repack_conc_toast;
+
+-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
+CREATE TABLE repack_conc_nothing (i int PRIMARY KEY);
+ALTER TABLE repack_conc_nothing REPLICA IDENTITY NOTHING;
+REPACK (CONCURRENTLY) repack_conc_nothing;
+DROP TABLE repack_conc_nothing;
+
+-- Doesn't support tables with deferrable primary keys
+CREATE TABLE repack_conc_deferrable (i int PRIMARY KEY DEFERRABLE);
+REPACK (CONCURRENTLY) repack_conc_deferrable;
+DROP TABLE repack_conc_deferrable;
+
 -- clean up
 DROP TABLE clustertest;
 DROP TABLE clstr_1;
-- 
2.50.1 (Apple Git-155)



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: repack: fix a bug to reject deferrable primary key fallback for concurrent mode
@ 2026-04-21 06:09  Antonin Houska <[email protected]>
  parent: Chao Li <[email protected]>
  0 siblings, 2 replies; 10+ messages in thread

From: Antonin Houska @ 2026-04-21 06:09 UTC (permalink / raw)
  To: Chao Li <[email protected]>; +Cc: pgsql-hackers; Zhijie Hou (Fujitsu) <[email protected]>; Alvaro Herrera <[email protected]>

Chao Li <[email protected]> wrote:

> > On Apr 20, 2026, at 22:52, Antonin Houska <[email protected]> wrote:
> > 
> > I'm just thinking if it's worth a separate error message.
> > RelationGetIndexList() just ignores the deferrable PK
> > 
> > if (replident == REPLICA_IDENTITY_DEFAULT && OidIsValid(pkeyIndex) && !pkdeferrable)
> > relation->rd_replidindex = pkeyIndex;
> > 
> > and if there's no other suitable index, the result is that there is no
> > identity index for the table. So the change attached here should be consistent
> > with this approach.

> Thanks for your review. I guess you read the v1 patch. In v2, I have switched to use GetRelationIdentityOrPK() that Zhijie suggested, which has covered RelationGetIndexList() and all checks, so that code is simplified, and there is no longer a separate error message.

Yes, this looks like the best approach. Sorry for missing v2.

-- 
Antonin Houska
Web: https://www.cybertec-postgresql.com





^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: repack: fix a bug to reject deferrable primary key fallback for concurrent mode
@ 2026-04-21 07:03  Yuchen Li <[email protected]>
  parent: Antonin Houska <[email protected]>
  1 sibling, 0 replies; 10+ messages in thread

From: Yuchen Li @ 2026-04-21 07:03 UTC (permalink / raw)
  To: Antonin Houska <[email protected]>; Chao Li <[email protected]>; +Cc: pgsql-hackers; Zhijie Hou (Fujitsu) <[email protected]>; Alvaro Herrera <[email protected]>

On 4/21/2026 2:09 PM, Antonin Houska wrote:
> Chao Li <[email protected]> wrote:
>
>>> On Apr 20, 2026, at 22:52, Antonin Houska <[email protected]> wrote:
>>>
>>> I'm just thinking if it's worth a separate error message.
>>> RelationGetIndexList() just ignores the deferrable PK
>>>
>>> if (replident == REPLICA_IDENTITY_DEFAULT && OidIsValid(pkeyIndex) && !pkdeferrable)
>>> relation->rd_replidindex = pkeyIndex;
>>>
>>> and if there's no other suitable index, the result is that there is no
>>> identity index for the table. So the change attached here should be consistent
>>> with this approach.
>> Thanks for your review. I guess you read the v1 patch. In v2, I have switched to use GetRelationIdentityOrPK() that Zhijie suggested, which has covered RelationGetIndexList() and all checks, so that code is simplified, and there is no longer a separate error message.
> Yes, this looks like the best approach. Sorry for missing v2.
>
The patch looks good to me. Using GetRelationIdentityOrPK() makes the 
check match the intended replica identity semantics more closely, and 
the added regression coverage looks useful.

Regards,
Yuchen Li






^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: repack: fix a bug to reject deferrable primary key fallback for concurrent mode
@ 2026-04-26 07:35  Chao Li <[email protected]>
  parent: Antonin Houska <[email protected]>
  1 sibling, 1 reply; 10+ messages in thread

From: Chao Li @ 2026-04-26 07:35 UTC (permalink / raw)
  To: Antonin Houska <[email protected]>; +Cc: pgsql-hackers; Zhijie Hou (Fujitsu) <[email protected]>; Alvaro Herrera <[email protected]>



> On Apr 21, 2026, at 14:09, Antonin Houska <[email protected]> wrote:
> 
> Chao Li <[email protected]> wrote:
> 
>>> On Apr 20, 2026, at 22:52, Antonin Houska <[email protected]> wrote:
>>> 
>>> I'm just thinking if it's worth a separate error message.
>>> RelationGetIndexList() just ignores the deferrable PK
>>> 
>>> if (replident == REPLICA_IDENTITY_DEFAULT && OidIsValid(pkeyIndex) && !pkdeferrable)
>>> relation->rd_replidindex = pkeyIndex;
>>> 
>>> and if there's no other suitable index, the result is that there is no
>>> identity index for the table. So the change attached here should be consistent
>>> with this approach.
> 
>> Thanks for your review. I guess you read the v1 patch. In v2, I have switched to use GetRelationIdentityOrPK() that Zhijie suggested, which has covered RelationGetIndexList() and all checks, so that code is simplified, and there is no longer a separate error message.
> 
> Yes, this looks like the best approach. Sorry for missing v2.
> 

Thanks for your reviewing and confirming.

Rebased to v4 as the CF reported a conflict.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/






Attachments:

  [application/octet-stream] v4-0001-Reject-deferrable-primary-key-fallback-in-REPACK-.patch (7.7K, 2-v4-0001-Reject-deferrable-primary-key-fallback-in-REPACK-.patch)
  download | inline diff:
From 36f1fd2c8f31899d08e0b291d49030c200ad7e32 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <[email protected]>
Date: Sun, 26 Apr 2026 15:31:24 +0800
Subject: [PATCH v4] Reject deferrable primary key fallback in REPACK
 CONCURRENTLY

REPACK CONCURRENTLY uses logical decoding to collect concurrent
changes and then replays them on the new heap. To locate rows for
UPDATE and DELETE replay, it requires an identity index.

When RelationGetReplicaIndex() returned InvalidOid, the code fell
back to rel->rd_pkindex if a primary key existed. That is not safe for
deferrable primary keys. Such indexes are not considered replica
identity indexes by WAL generation, so logical decoding may not provide
the old tuple needed by the repack output plugin.

This can make replay fail later with errors such as "incomplete delete
info" from the decoding worker.

This change switches to use GetRelationIdentityOrPK() that excludes
deferrable primary key.

Author: Chao Li <[email protected]>
Reviewed-by: Zhijie Hou <[email protected]>
Reviewed-by: Antonin Houska <[email protected]>
Discussion: https://postgr.es/m/[email protected]
---
 src/backend/commands/repack.c         | 15 ++++----
 src/test/regress/expected/cluster.out | 50 +++++++++++++++++++++++++--
 src/test/regress/sql/cluster.sql      | 44 +++++++++++++++++++++--
 3 files changed, 97 insertions(+), 12 deletions(-)

diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c
index bafdca80810..ce5b99c38b1 100644
--- a/src/backend/commands/repack.c
+++ b/src/backend/commands/repack.c
@@ -62,6 +62,7 @@
 #include "miscadmin.h"
 #include "optimizer/optimizer.h"
 #include "pgstat.h"
+#include "replication/logicalrelation.h"
 #include "storage/bufmgr.h"
 #include "storage/lmgr.h"
 #include "storage/predicate.h"
@@ -919,14 +920,12 @@ check_concurrent_repack_requirements(Relation rel, Oid *ident_idx_p)
 
 	/*
 	 * Obtain the replica identity index -- either one that has been set
-	 * explicitly, or the primary key.  If none of these cases apply, the
-	 * table cannot be repacked concurrently.  It might be possible to have
-	 * repack work with a FULL replica identity; however that requires more
-	 * work and is not implemented yet.
-	 */
-	ident_idx = RelationGetReplicaIndex(rel);
-	if (!OidIsValid(ident_idx) && OidIsValid(rel->rd_pkindex))
-		ident_idx = rel->rd_pkindex;
+	 * explicitly, or a non-deferrable primary key.  If none of these cases
+	 * apply, the table cannot be repacked concurrently.  It might be possible
+	 * to have repack work with a FULL replica identity; however that requires
+	 * more work and is not implemented yet.
+	 */
+	ident_idx = GetRelationIdentityOrPK(rel);
 	if (!OidIsValid(ident_idx))
 		ereport(ERROR,
 				errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index 96089bb0fa2..031664b95f6 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -796,14 +796,60 @@ ORDER BY o.relname;
  clstr_3
 (2 rows)
 
--- concurrently disallowed in catalogs
+--
+-- Check concurrent mode requirements
+--
+-- Disallowed in catalogs
 REPACK (CONCURRENTLY) pg_class;
 ERROR:  cannot repack relation "pg_class"
 HINT:  REPACK CONCURRENTLY is not supported for catalog relations.
--- CONCURRENTLY doesn't like partitioned tables
+-- Doesn't like partitioned tables
 REPACK (CONCURRENTLY) clstrpart;
 ERROR:  REPACK (CONCURRENTLY) is not supported for partitioned tables
 HINT:  Consider running the command on individual partitions.
+-- Doesn't support catalog tables
+REPACK (CONCURRENTLY) pg_class;
+ERROR:  cannot repack relation "pg_class"
+HINT:  REPACK CONCURRENTLY is not supported for catalog relations.
+-- Only support permanent tables, temp and unlogged tables are not supported
+CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_temp;
+ERROR:  cannot repack relation "repack_conc_temp"
+HINT:  REPACK CONCURRENTLY is only allowed for permanent relations.
+DROP TABLE repack_conc_temp;
+CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_unlogged;
+ERROR:  cannot repack relation "repack_conc_unlogged"
+HINT:  REPACK CONCURRENTLY is only allowed for permanent relations.
+DROP TABLE repack_conc_unlogged;
+-- Doesn't support tables without a primary key or replica identity index
+CREATE TABLE repack_conc_noident (i int);
+REPACK (CONCURRENTLY) repack_conc_noident;
+ERROR:  cannot process relation "repack_conc_noident"
+HINT:  Relation "repack_conc_noident" has no identity index.
+DROP TABLE repack_conc_noident;
+-- Doesn't support TOAST tables directly
+CREATE TABLE repack_conc_toast (t text);
+SELECT reltoastrelid::regclass AS toast_rel
+FROM pg_class WHERE oid = 'repack_conc_toast'::regclass \gset
+\set VERBOSITY sqlstate
+REPACK (CONCURRENTLY) :toast_rel;
+ERROR:  0A000
+\set VERBOSITY default
+DROP TABLE repack_conc_toast;
+-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
+CREATE TABLE repack_conc_nothing (i int PRIMARY KEY);
+ALTER TABLE repack_conc_nothing REPLICA IDENTITY NOTHING;
+REPACK (CONCURRENTLY) repack_conc_nothing;
+ERROR:  cannot repack relation "repack_conc_nothing"
+HINT:  Relation "repack_conc_nothing" has insufficient replication identity.
+DROP TABLE repack_conc_nothing;
+-- Doesn't support tables with deferrable primary keys
+CREATE TABLE repack_conc_deferrable (i int PRIMARY KEY DEFERRABLE);
+REPACK (CONCURRENTLY) repack_conc_deferrable;
+ERROR:  cannot process relation "repack_conc_deferrable"
+HINT:  Relation "repack_conc_deferrable" has no identity index.
+DROP TABLE repack_conc_deferrable;
 -- clean up
 DROP TABLE clustertest;
 DROP TABLE clstr_1;
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6b3219bab94..640b3691f44 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -383,12 +383,52 @@ JOIN relnodes_new n ON o.relname = n.relname
 WHERE o.relfilenode <> n.relfilenode
 ORDER BY o.relname;
 
--- concurrently disallowed in catalogs
+--
+-- Check concurrent mode requirements
+--
+
+-- Disallowed in catalogs
 REPACK (CONCURRENTLY) pg_class;
 
--- CONCURRENTLY doesn't like partitioned tables
+-- Doesn't like partitioned tables
 REPACK (CONCURRENTLY) clstrpart;
 
+-- Doesn't support catalog tables
+REPACK (CONCURRENTLY) pg_class;
+
+-- Only support permanent tables, temp and unlogged tables are not supported
+CREATE TEMP TABLE repack_conc_temp (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_temp;
+DROP TABLE repack_conc_temp;
+CREATE UNLOGGED TABLE repack_conc_unlogged (i int PRIMARY KEY);
+REPACK (CONCURRENTLY) repack_conc_unlogged;
+DROP TABLE repack_conc_unlogged;
+
+-- Doesn't support tables without a primary key or replica identity index
+CREATE TABLE repack_conc_noident (i int);
+REPACK (CONCURRENTLY) repack_conc_noident;
+DROP TABLE repack_conc_noident;
+
+-- Doesn't support TOAST tables directly
+CREATE TABLE repack_conc_toast (t text);
+SELECT reltoastrelid::regclass AS toast_rel
+FROM pg_class WHERE oid = 'repack_conc_toast'::regclass \gset
+\set VERBOSITY sqlstate
+REPACK (CONCURRENTLY) :toast_rel;
+\set VERBOSITY default
+DROP TABLE repack_conc_toast;
+
+-- Doesn't support tables with REPLICA IDENTITY NOTHING, even if they have a primary key
+CREATE TABLE repack_conc_nothing (i int PRIMARY KEY);
+ALTER TABLE repack_conc_nothing REPLICA IDENTITY NOTHING;
+REPACK (CONCURRENTLY) repack_conc_nothing;
+DROP TABLE repack_conc_nothing;
+
+-- Doesn't support tables with deferrable primary keys
+CREATE TABLE repack_conc_deferrable (i int PRIMARY KEY DEFERRABLE);
+REPACK (CONCURRENTLY) repack_conc_deferrable;
+DROP TABLE repack_conc_deferrable;
+
 -- clean up
 DROP TABLE clustertest;
 DROP TABLE clstr_1;
-- 
2.50.1 (Apple Git-155)



^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: repack: fix a bug to reject deferrable primary key fallback for concurrent mode
@ 2026-04-27 16:24  Alvaro Herrera <[email protected]>
  parent: Chao Li <[email protected]>
  0 siblings, 1 reply; 10+ messages in thread

From: Alvaro Herrera @ 2026-04-27 16:24 UTC (permalink / raw)
  To: Chao Li <[email protected]>; +Cc: Antonin Houska <[email protected]>; pgsql-hackers; Zhijie Hou (Fujitsu) <[email protected]>

On 2026-Apr-26, Chao Li wrote:

> Thanks for your reviewing and confirming.
> 
> Rebased to v4 as the CF reported a conflict.

Thanks, pushed it now.

-- 
Álvaro Herrera        Breisgau, Deutschland  —  https://www.EnterpriseDB.com/
"La grandeza es una experiencia transitoria.  Nunca es consistente.
Depende en gran parte de la imaginación humana creadora de mitos"
(Irulan)





^ permalink  raw  reply  [nested|flat] 10+ messages in thread

* Re: repack: fix a bug to reject deferrable primary key fallback for concurrent mode
@ 2026-04-30 18:54  Tom Lane <[email protected]>
  parent: Alvaro Herrera <[email protected]>
  0 siblings, 0 replies; 10+ messages in thread

From: Tom Lane @ 2026-04-30 18:54 UTC (permalink / raw)
  To: Alvaro Herrera <[email protected]>; +Cc: Chao Li <[email protected]>; Antonin Houska <[email protected]>; pgsql-hackers; Zhijie Hou (Fujitsu) <[email protected]>

Alvaro Herrera <[email protected]> writes:
> Thanks, pushed it now.

So, no sooner had 4b2aa4b39 removed tests of REPACK CONCURRENTLY
from the core regression tests than 832e220d9 put one back.
BF member thorntail is broken again.

			regards, tom lane





^ permalink  raw  reply  [nested|flat] 10+ messages in thread


end of thread, other threads:[~2026-04-30 18:54 UTC | newest]

Thread overview: 10+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-04-17 03:35 repack: fix a bug to reject deferrable primary key fallback for concurrent mode Chao Li <[email protected]>
2026-04-17 03:46 ` Zhijie Hou (Fujitsu) <[email protected]>
2026-04-17 06:17   ` Chao Li <[email protected]>
2026-04-20 14:52 ` Antonin Houska <[email protected]>
2026-04-21 02:38   ` Chao Li <[email protected]>
2026-04-21 06:09     ` Antonin Houska <[email protected]>
2026-04-21 07:03       ` Yuchen Li <[email protected]>
2026-04-26 07:35       ` Chao Li <[email protected]>
2026-04-27 16:24         ` Alvaro Herrera <[email protected]>
2026-04-30 18:54           ` Tom Lane <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox