From aa9435c9c6f4dfc01d23babbfe8ba15fb55ee8cb Mon Sep 17 00:00:00 2001 From: reshke Date: Thu, 7 Aug 2025 12:29:39 +0000 Subject: [PATCH] Allow to explicitly set REPLICA IDENTITY with relation creating. Previously, the only way to define relation's REPLICA IDENTITY was to CREATE relation and then ALTER TABLE ... REPLICA IDENTITY .. with it. This commit allows single-DDL to this. --- src/backend/commands/tablecmds.c | 5 +++ src/backend/parser/gram.y | 63 +++++++++++++++++++------------- src/include/nodes/parsenodes.h | 1 + 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index cb811520c29..282c0fd1110 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -1088,6 +1088,11 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, */ rel = relation_open(relationId, AccessExclusiveLock); + /* Create REPLICA IDENTITY if told to */ + if (stmt->replicaIdentity != NULL) { + ATExecReplicaIdentity(rel, stmt->replicaIdentity, AccessExclusiveLock); + } + /* * Now add any newly specified column default and generation expressions * to the new relation. These are passed to us in the form of raw diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index db43034b9db..f50e936f8c9 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -328,7 +328,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type add_drop opt_asc_desc opt_nulls_order %type alter_table_cmd alter_type_cmd opt_collate_clause - replica_identity partition_cmd index_partition_cmd + replica_identity opt_replica_identity partition_cmd index_partition_cmd %type alter_table_cmds alter_type_cmds %type alter_identity_column_option_list %type alter_identity_column_option @@ -3101,6 +3101,11 @@ replica_identity: } ; + +opt_replica_identity: REPLICA IDENTITY_P replica_identity { $$ = $3; } + | /* EMPTY */ { $$ = NIL; } + ; + reloptions: '(' reloption_list ')' { $$ = $2; } ; @@ -3646,8 +3651,8 @@ copy_generic_opt_arg_list_item: *****************************************************************************/ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' - OptInherit OptPartitionSpec table_access_method_clause OptWith - OnCommitOption OptTableSpace + OptInherit OptPartitionSpec table_access_method_clause opt_replica_identity + OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); @@ -3659,15 +3664,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->ofTypename = NULL; n->constraints = NIL; n->accessMethod = $10; - n->options = $11; - n->oncommit = $12; - n->tablespacename = $13; + n->replicaIdentity = $11; + n->options = $12; + n->oncommit = $13; + n->tablespacename = $14; n->if_not_exists = false; $$ = (Node *) n; } | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name '(' OptTableElementList ')' OptInherit OptPartitionSpec table_access_method_clause - OptWith OnCommitOption OptTableSpace + opt_replica_identity OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); @@ -3679,15 +3685,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->ofTypename = NULL; n->constraints = NIL; n->accessMethod = $13; - n->options = $14; - n->oncommit = $15; - n->tablespacename = $16; + n->replicaIdentity = (ReplicaIdentityStmt *) $14; + n->options = $15; + n->oncommit = $16; + n->tablespacename = $17; n->if_not_exists = true; $$ = (Node *) n; } | CREATE OptTemp TABLE qualified_name OF any_name OptTypedTableElementList OptPartitionSpec table_access_method_clause - OptWith OnCommitOption OptTableSpace + opt_replica_identity OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); @@ -3700,15 +3707,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->ofTypename->location = @6; n->constraints = NIL; n->accessMethod = $9; - n->options = $10; - n->oncommit = $11; - n->tablespacename = $12; + n->replicaIdentity = (ReplicaIdentityStmt *) $10; + n->options = $11; + n->oncommit = $12; + n->tablespacename = $13; n->if_not_exists = false; $$ = (Node *) n; } | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name OF any_name OptTypedTableElementList OptPartitionSpec table_access_method_clause - OptWith OnCommitOption OptTableSpace + opt_replica_identity OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); @@ -3721,15 +3729,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->ofTypename->location = @9; n->constraints = NIL; n->accessMethod = $12; - n->options = $13; - n->oncommit = $14; - n->tablespacename = $15; + n->replicaIdentity = (ReplicaIdentityStmt *) $13; + n->options = $14; + n->oncommit = $15; + n->tablespacename = $16; n->if_not_exists = true; $$ = (Node *) n; } | CREATE OptTemp TABLE qualified_name PARTITION OF qualified_name OptTypedTableElementList PartitionBoundSpec OptPartitionSpec - table_access_method_clause OptWith OnCommitOption OptTableSpace + table_access_method_clause opt_replica_identity OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); @@ -3742,15 +3751,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->ofTypename = NULL; n->constraints = NIL; n->accessMethod = $11; - n->options = $12; - n->oncommit = $13; - n->tablespacename = $14; + n->replicaIdentity = (ReplicaIdentityStmt *) $12; + n->options = $13; + n->oncommit = $14; + n->tablespacename = $15; n->if_not_exists = false; $$ = (Node *) n; } | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name PARTITION OF qualified_name OptTypedTableElementList PartitionBoundSpec OptPartitionSpec - table_access_method_clause OptWith OnCommitOption OptTableSpace + table_access_method_clause opt_replica_identity OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); @@ -3763,9 +3773,10 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->ofTypename = NULL; n->constraints = NIL; n->accessMethod = $14; - n->options = $15; - n->oncommit = $16; - n->tablespacename = $17; + n->replicaIdentity = (ReplicaIdentityStmt *) $15; + n->options = $16; + n->oncommit = $17; + n->tablespacename = $18; n->if_not_exists = true; $$ = (Node *) n; } diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 86a236bd58b..ddb1ff40f41 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2757,6 +2757,7 @@ typedef struct CreateStmt OnCommitAction oncommit; /* what do we do at COMMIT? */ char *tablespacename; /* table space to use, or NULL */ char *accessMethod; /* table access method */ + ReplicaIdentityStmt *replicaIdentity; /* replica identity for relation, or NULL */ bool if_not_exists; /* just do nothing if it already exists? */ } CreateStmt; -- 2.43.0