Обсуждение: BUG #19013: When creating a table with the "...LIKE...INCLUDING ALL" construct, REPLICA IDENTITY output is wrong

Поиск
Список
Период
Сортировка

BUG #19013: When creating a table with the "...LIKE...INCLUDING ALL" construct, REPLICA IDENTITY output is wrong

От
PG Bug reporting form
Дата:
The following bug has been logged on the website:

Bug reference:      19013
Logged by:          Michael Vitale
Email address:      dbman@sqlexec.com
PostgreSQL version: 17.5
Operating system:   CentOS 8 Streams
Description:

Here is a simple schema to test with:
DROP SCHEMA IF EXISTS testing CASCADE;
CREATE SCHEMA testing;
CREATE TABLE testing.notifications
(
    id uuid NOT NULL DEFAULT uuid_generate_v4(),
    employee_id uuid NOT NULL,
    seen_at timestamp with time zone,
    created_at timestamp with time zone DEFAULT now(),
    last_changed timestamp with time zone NOT NULL DEFAULT now(),
    file_id uuid NOT NULL,
    conversation_id uuid,
    document_id uuid,
    message_id uuid,
    CONSTRAINT notifications_pkey PRIMARY KEY (id)
) TABLESPACE pg_default;
ALTER TABLE ONLY testing.notifications REPLICA IDENTITY FULL;
ALTER TABLE IF EXISTS testing.notifications OWNER to postgres;

-- Validate table is defined with REPLICA IDENTITY FULL
SELECT n.nspname AS schema_name, c.oid, c.relname AS table_name,
c.relreplident, i.indisreplident,  idx_c.relname AS
replica_identity_index_name,
CASE c.relreplident WHEN 'd' THEN 'DEFAULT' WHEN 'n' THEN 'NOTHING' WHEN 'f'
THEN 'FULL' WHEN 'i' THEN 'INDEX' END AS replica_identity_setting
FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace LEFT JOIN
pg_index i ON i.indrelid = c.oid AND i.indisreplident = TRUE LEFT JOIN
pg_class idx_c ON idx_c.oid = i.indexrelid
WHERE n.nspname = 'testing' AND c.relkind = 'r';
 schema_name |  oid  |  table_name   | relreplident | indisreplident |
replica_identity_index_name | replica_identity_setting

-------------+-------+---------------+--------------+----------------+-----------------------------+--------------------------
 testing     | 58431 | notifications | f            |                |
| FULL

-- Create another table using the LIKE construct
CREATE TABLE testing.notifications2 (LIKE testing.notifications INCLUDING
ALL);

-- Run the query again:
SELECT n.nspname AS schema_name, c.oid, c.relname AS table_name,
c.relreplident, i.indisreplident,  idx_c.relname AS
replica_identity_index_name,
CASE c.relreplident WHEN 'd' THEN 'DEFAULT' WHEN 'n' THEN 'NOTHING' WHEN 'f'
THEN 'FULL' WHEN 'i' THEN 'INDEX' END AS replica_identity_setting
FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace LEFT JOIN
pg_index i ON i.indrelid = c.oid AND i.indisreplident = TRUE LEFT JOIN
pg_class idx_c ON idx_c.oid = i.indexrelid
WHERE n.nspname = 'testing' AND c.relkind = 'r';
 schema_name |  oid  |   table_name   | relreplident | indisreplident |
replica_identity_index_name | replica_identity_setting

-------------+-------+----------------+--------------+----------------+-----------------------------+--------------------------
 testing     | 58431 | notifications  | f            |                |
| FULL
 testing     | 58439 | notifications2 | d            |                |
| DEFAULT
(2 rows)


On Tue, Aug 5, 2025 at 2:43 PM PG Bug reporting form <noreply@postgresql.org> wrote:
The following bug has been logged on the website:

Bug reference:      19013
Logged by:          Michael Vitale
Email address:      dbman@sqlexec.com
PostgreSQL version: 17.5
Operating system:   CentOS 8 Streams
Description:       


We don't document that the replica identity attribute of a table is something that can be copied.  'ALL' only covers those things which are documented as being copy-able.

David J.

On 8/5/2025 7:01 PM, David G. Johnston wrote:
On Tue, Aug 5, 2025 at 2:43 PM PG Bug reporting form <noreply@postgresql.org> wrote:
The following bug has been logged on the website:

Bug reference:      19013
Logged by:          Michael Vitale
Email address:      dbman@sqlexec.com
PostgreSQL version: 17.5
Operating system:   CentOS 8 Streams
Description:       


We don't document that the replica identity attribute of a table is something that can be copied.  'ALL' only covers those things which are documented as being copy-able.

David J.

I understand your logic about not everything is copy-able, just what is documented, but this is a different case.  I am not complaining that it is not copying the REPLICA IDENTITY, but rather that it is copying it in a WRONG WAY, changing its property from FULL to DEFAULT.  I think that is a reasonable complaint.  If you are going to attempt to copy it erroneously, then I think you should consider that a bug and fix it.  Otherwise, remove it and don't try to copy it.  Does that seem reasonable?

On Wednesday, August 6, 2025, dbman@sqlexec.com <dbman@sqlexec.com> wrote:
On 8/5/2025 7:01 PM, David G. Johnston wrote:
On Tue, Aug 5, 2025 at 2:43 PM PG Bug reporting form <noreply@postgresql.org> wrote:
The following bug has been logged on the website:

Bug reference:      19013
Logged by:          Michael Vitale
Email address:      dbman@sqlexec.com
PostgreSQL version: 17.5
Operating system:   CentOS 8 Streams
Description:       


We don't document that the replica identity attribute of a table is something that can be copied.  'ALL' only covers those things which are documented as being copy-able.

David J.

I understand your logic about not everything is copy-able, just what is documented, but this is a different case.  I am not complaining that it is not copying the REPLICA IDENTITY, but rather that it is copying it in a WRONG WAY, changing its property from FULL to DEFAULT.  I think that is a reasonable complaint.  If you are going to attempt to copy it erroneously, then I think you should consider that a bug and fix it.  Otherwise, remove it and don't try to copy it.  Does that seem reasonable?


Reading the docs, if you just perform a create table (no like) you’ll find pg_class.relreplident is set to “d”.  That field is never null.  There is no concept of “remove it”.

David J.

On 8/6/2025 10:53 AM, David G. Johnston wrote:
On Wednesday, August 6, 2025, dbman@sqlexec.com <dbman@sqlexec.com> wrote:
On 8/5/2025 7:01 PM, David G. Johnston wrote:
On Tue, Aug 5, 2025 at 2:43 PM PG Bug reporting form <noreply@postgresql.org> wrote:
The following bug has been logged on the website:

Bug reference:      19013
Logged by:          Michael Vitale
Email address:      dbman@sqlexec.com
PostgreSQL version: 17.5
Operating system:   CentOS 8 Streams
Description:       


We don't document that the replica identity attribute of a table is something that can be copied.  'ALL' only covers those things which are documented as being copy-able.

David J.

I understand your logic about not everything is copy-able, just what is documented, but this is a different case.  I am not complaining that it is not copying the REPLICA IDENTITY, but rather that it is copying it in a WRONG WAY, changing its property from FULL to DEFAULT.  I think that is a reasonable complaint.  If you are going to attempt to copy it erroneously, then I think you should consider that a bug and fix it.  Otherwise, remove it and don't try to copy it.  Does that seem reasonable?


Reading the docs, if you just perform a create table (no like) you’ll find pg_class.relreplident is set to “d”.  That field is never null.  There is no concept of “remove it”.

David J.

Good point aboutg the default value for pg_class.relreplident is always "d", but maybe it should be "n" which indicates there is no REPLICA IDENTITY.  Otherwise the way it is now, whenever there is a REPLICA IDENTITY on a table and you use the CREATE LIKE construct, it will always overwrite the "f" and "i" values with "d", thereby actually changing the state of the REPLICA IDENTITY from FULL or INDEX to DEFAULT.  It just seems that something should be done to prevent a change to the REPLICA IDENTIY if one exists that is not DEFAULT in the source table.  Othewise you have an unintended DDL change consequence to this action.  Perhaps add a warning about this in the description for CREATE...LIKE in the docs, or even mention it in the section that describes REPLICA IDENTITY, or both.

Michael V

Hi!

On Wed, 6 Aug 2025 at 20:42, dbman@sqlexec.com <dbman@sqlexec.com> wrote:
> Good point aboutg the default value for pg_class.relreplident is always "d", but maybe it should be "n" which
indicatesthere is no REPLICA IDENTITY.
 
So, in other words, you propose to change the default behaviour?

> Othewise you have an unintended DDL change consequence to this action.

It's hard (to me, at least) to say what is `intended` DDL here.

> Perhaps add a warning about this in the description for CREATE...LIKE in the docs, or even mention it in the section
thatdescribes REPLICA IDENTITY, or both.
 

Perhaps, rewording docs to indicate something like this does not sound
horribly to me.

-- 
Best regards,
Kirill Reshke



On 8/6/2025 12:32 PM, Kirill Reshke wrote:
> It's hard (to me, at least) to say what is `intended` DDL here.

Why is it hard?  If the pg_dump output or /d schema.tablename output
indicates a REPLICA IDENTITY of either FULL or INDEX, then it seems it
should be obvious that the CREATE TABLE ... LIKE output should be
similar, but instead it will show REPLICA IDENTITY DEFAULT.

Regards,

Michael V





On 2025-Aug-06, dbman@sqlexec.com wrote:

> Good point aboutg the default value for pg_class.relreplident is always "d",
> but maybe it should be "n" which indicates there is no REPLICA IDENTITY. 

I think this behavior is just an oversight made when replica identity
was introduced.  Commit 07cacba983ef didn't touch the CREATE TABLE LIKE
code.

To me, it makes sense to copy the replica identity definition if
INCLUDING INDEXES or INCLUDING CONSTRAINTS is given.

Patching released branches seems out of the question (it might disrupt
working workflows), but for 19 it isn't, if we agree on an ideal
behavior.

-- 
Álvaro Herrera        Breisgau, Deutschland  —  https://www.EnterpriseDB.com/
"Siempre hay que alimentar a los dioses, aunque la tierra esté seca" (Orual)



On Wed, Aug 6, 2025 at 8:42 AM dbman@sqlexec.com <dbman@sqlexec.com> wrote:

thereby actually changing the state of the REPLICA IDENTITY from FULL or INDEX to DEFAULT.

Nothing is "changed".  The newly created table never existed and as soon as it did the value of replica identity was default.  It was never anything else.

Sure, maybe we should implement a LIKE option to cover replica identity, but given that it doesn't exist the current behavior is valid - assign what the value would be after a normal create table.  I'd add maybe there should be a way to specify replica identity during create table, not just alter table, but that too is a new feature.

  It just seems that something should be done to prevent a change to the REPLICA IDENTIY if one exists that is not DEFAULT in the source table.

If you don't want the default, PK, replica identity on the new table you are compelled to alter the table after you create it to specify what it should be.  Sure, we don't actually say those words, but since there is nothing in create table that deals with replica identity, that is the conclusion one must draw.  We tend to only document affirmatives - I'm not all that convinced this is going to be an exception.

David J.