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

Started by PG Bug reporting form9 months ago9 messagesbugs
Jump to latest
#1PG Bug reporting form
noreply@postgresql.org

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)

#2David G. Johnston
david.g.johnston@gmail.com
In reply to: PG Bug reporting form (#1)
Re: BUG #19013: When creating a table with the "...LIKE...INCLUDING ALL" construct, REPLICA IDENTITY output is wrong

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.

#3dbman@sqlexec.com
dbman@sqlexec.com
In reply to: David G. Johnston (#2)
Re: BUG #19013: When creating a table with the "...LIKE...INCLUDING ALL" construct, REPLICA IDENTITY output is wrong

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?

#4David G. Johnston
david.g.johnston@gmail.com
In reply to: dbman@sqlexec.com (#3)
Re: BUG #19013: When creating a table with the "...LIKE...INCLUDING ALL" construct, REPLICA IDENTITY output is wrong

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.

#5dbman@sqlexec.com
dbman@sqlexec.com
In reply to: David G. Johnston (#4)
Re: BUG #19013: When creating a table with the "...LIKE...INCLUDING ALL" construct, REPLICA IDENTITY output is wrong

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

#6Kirill Reshke
reshkekirill@gmail.com
In reply to: dbman@sqlexec.com (#5)
Re: BUG #19013: When creating a table with the "...LIKE...INCLUDING ALL" construct, REPLICA IDENTITY output is wrong

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 indicates there 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 that describes REPLICA IDENTITY, or both.

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

--
Best regards,
Kirill Reshke

#7dbman@sqlexec.com
dbman@sqlexec.com
In reply to: Kirill Reshke (#6)
Re: BUG #19013: When creating a table with the "...LIKE...INCLUDING ALL" construct, REPLICA IDENTITY output is wrong

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

#8Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: dbman@sqlexec.com (#5)
Re: BUG #19013: When creating a table with the "...LIKE...INCLUDING ALL" construct, REPLICA IDENTITY output is wrong

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)

#9David G. Johnston
david.g.johnston@gmail.com
In reply to: dbman@sqlexec.com (#5)
Re: BUG #19013: When creating a table with the "...LIKE...INCLUDING ALL" construct, REPLICA IDENTITY output is wrong

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.