0009-Support-replication-of-DDL-type-T_RenameStmt-table-r.patch
application/octet-stream
Filename: 0009-Support-replication-of-DDL-type-T_RenameStmt-table-r.patch
Type: application/octet-stream
Part: 7
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0009
Subject: Support replication of DDL type T_RenameStmt: table rename is allowed in both database level and table level DDL replication. Rename of other objects are only allowed in database level DDL replication.
| File | + | − |
|---|---|---|
| src/backend/commands/alter.c | 3 | 2 |
| src/backend/commands/tablecmds.c | 14 | 1 |
| src/backend/tcop/utility.c | 16 | 4 |
| src/include/commands/alter.h | 2 | 1 |
| src/include/commands/tablecmds.h | 1 | 1 |
| src/test/subscription/t/030_rep_ddls.pl | 31 | 2 |
From 7e66412f92674dcb1adf29140aac692340491e00 Mon Sep 17 00:00:00 2001
From: PonyboyYbr <94borelyang@gmail.com>
Date: Wed, 11 May 2022 15:46:40 -0700
Subject: [PATCH 09/12] Support replication of DDL type T_RenameStmt: table
rename is allowed in both database level and table level DDL replication.
Rename of other objects are only allowed in database level DDL replication.
Co-authored-by: Borui Yang <boruiyan@amazon.com>
---
src/backend/commands/alter.c | 5 ++--
src/backend/commands/tablecmds.c | 15 ++++++++++-
src/backend/tcop/utility.c | 20 ++++++++++++---
src/include/commands/alter.h | 3 ++-
src/include/commands/tablecmds.h | 2 +-
src/test/subscription/t/030_rep_ddls.pl | 33 +++++++++++++++++++++++--
6 files changed, 67 insertions(+), 11 deletions(-)
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 5456b8222b..1ca8f99e0c 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -328,7 +328,8 @@ AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
* Return value is the address of the renamed object.
*/
ObjectAddress
-ExecRenameStmt(RenameStmt *stmt)
+ExecRenameStmt(ParseState *pstate, RenameStmt *stmt,
+ bool isCompleteQuery)
{
switch (stmt->renameType)
{
@@ -354,7 +355,7 @@ ExecRenameStmt(RenameStmt *stmt)
case OBJECT_MATVIEW:
case OBJECT_INDEX:
case OBJECT_FOREIGN_TABLE:
- return RenameRelation(stmt);
+ return RenameRelation(pstate, stmt, isCompleteQuery);
case OBJECT_COLUMN:
case OBJECT_ATTRIBUTE:
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 3c9b6409ca..65386f2641 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -3820,11 +3820,12 @@ RenameConstraint(RenameStmt *stmt)
* RENAME
*/
ObjectAddress
-RenameRelation(RenameStmt *stmt)
+RenameRelation(ParseState *pstate, RenameStmt *stmt, bool isCompleteQuery)
{
bool is_index_stmt = stmt->renameType == OBJECT_INDEX;
Oid relid;
ObjectAddress address;
+ bool ddlxlog = XLogLogicalInfoActive() && isCompleteQuery;
/*
* Grab an exclusive lock on the target table, index, sequence, view,
@@ -3872,6 +3873,18 @@ RenameRelation(RenameStmt *stmt)
is_index_stmt = obj_is_index;
}
+ if (ddlxlog &&
+ ddl_need_xlog(relid, false))
+ {
+ bool transactional = true;
+ const char* prefix = "";
+ LogLogicalDDLMessage(prefix,
+ GetUserId(),
+ pstate->p_sourcetext,
+ strlen(pstate->p_sourcetext),
+ transactional);
+ }
+
/* Do the work */
RenameRelationInternal(relid, stmt->newname, false, is_index_stmt);
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index e9e7567209..1abd77a60e 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1002,7 +1002,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
context, params, queryEnv,
dest, qc);
else
- ExecRenameStmt(stmt);
+ ExecRenameStmt(pstate, stmt, context != PROCESS_UTILITY_SUBCOMMAND);
}
break;
@@ -1195,8 +1195,20 @@ LogLogicalDDLCommand(Node *parsetree, const char *queryString)
*/
case T_AlterTableStmt:
case T_IndexStmt:
- case T_RenameStmt: /* TODO */
- case T_AlterOwnerStmt: /* TODO */
+ case T_RenameStmt:
+ {
+ RenameStmt *stmt = (RenameStmt *) parsetree;
+ if(!stmt->relation && ddl_need_xlog(InvalidOid, true)){
+ bool transactional = true;
+ const char* prefix = "";
+ LogLogicalDDLMessage(prefix,
+ GetUserId(),
+ queryString,
+ strlen(queryString),
+ transactional);
+ }
+ }
+ case T_AlterOwnerStmt: /* TODO, it is data control case, save for later update */
break;
/* DropStmt depends on the removeType */
@@ -2008,7 +2020,7 @@ ProcessUtilitySlow(ParseState *pstate,
break;
case T_RenameStmt:
- address = ExecRenameStmt((RenameStmt *) parsetree);
+ address = ExecRenameStmt(pstate, (RenameStmt *) parsetree, isCompleteQuery);
break;
case T_AlterObjectDependsStmt:
diff --git a/src/include/commands/alter.h b/src/include/commands/alter.h
index 52f5e6f6d2..df9333eb93 100644
--- a/src/include/commands/alter.h
+++ b/src/include/commands/alter.h
@@ -17,9 +17,10 @@
#include "catalog/dependency.h"
#include "catalog/objectaddress.h"
#include "nodes/parsenodes.h"
+#include "parser/parse_node.h"
#include "utils/relcache.h"
-extern ObjectAddress ExecRenameStmt(RenameStmt *stmt);
+extern ObjectAddress ExecRenameStmt(ParseState *pstate, RenameStmt *stmt, bool isCompleteQuery);
extern ObjectAddress ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt,
ObjectAddress *refAddress);
diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h
index 24106de2e5..f96bb57d56 100644
--- a/src/include/commands/tablecmds.h
+++ b/src/include/commands/tablecmds.h
@@ -74,7 +74,7 @@ extern ObjectAddress renameatt(RenameStmt *stmt);
extern ObjectAddress RenameConstraint(RenameStmt *stmt);
-extern ObjectAddress RenameRelation(RenameStmt *stmt);
+extern ObjectAddress RenameRelation(ParseState *pstate, RenameStmt *stmt, bool isCompleteQuery);
extern void RenameRelationInternal(Oid myrelid,
const char *newrelname, bool is_internal,
diff --git a/src/test/subscription/t/030_rep_ddls.pl b/src/test/subscription/t/030_rep_ddls.pl
index b4df1bfefd..51126b489b 100644
--- a/src/test/subscription/t/030_rep_ddls.pl
+++ b/src/test/subscription/t/030_rep_ddls.pl
@@ -30,7 +30,6 @@ $node_subscriber->safe_psql('postgres', $ddl);
$node_subscriber2->safe_psql('postgres', $ddl);
my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres';
-
# mypub has pubddl_database on
$node_publisher->safe_psql('postgres',
"CREATE PUBLICATION mypub FOR ALL TABLES;");
@@ -269,7 +268,7 @@ $result = $node_subscriber->safe_psql('postgres', "SELECT count(*) from s1.t6;")
is($result, qq(1), 'SELECT INTO s1.t6 is replicated with data');
# TEST Create DomainStmt
-$node_publisher->safe_psql('postgres', "CREATE DOMAIN s1.space_check AS VARCHAR NOT NULL CHECK (value !~ '\s');");
+$node_publisher->safe_psql('postgres', "CREATE DOMAIN s1.space_check AS VARCHAR NOT NULL CHECK (value !~ '\\s');");
$node_publisher->wait_for_catchup('mysub');
@@ -348,6 +347,36 @@ $node_publisher->wait_for_catchup('mysub');
$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM pg_catalog.pg_cast c, pg_catalog.pg_proc p WHERE p.proname='add' AND c.castfunc=p.oid;");
is($result, qq(1), 'CreateCast Stmt is replicated');
+#TEST RenameStmt for FUNCTION
+$node_publisher->safe_psql('postgres', "ALTER FUNCTION add RENAME TO plus;");
+
+$node_publisher->wait_for_catchup('mysub');
+
+$result = $node_subscriber->safe_psql('postgres', "SELECT count(*) from pg_catalog.pg_proc p where p.proname='plus';");
+is($result, qq(1), 'RENAME FUNCTION Stmt is replicated');
+
+#TEST RenameStmt for table
+$node_publisher->safe_psql('postgres', "CREATE DATABASE db1;");
+$node_publisher->safe_psql('db1', "CREATE TABLE t7 (id int primary key, name varchar);");
+$node_publisher->safe_psql('db1', "CREATE TABLE t8 (id int primary key, name varchar);");
+$node_publisher->safe_psql('db1',
+ "CREATE PUBLICATION mypub3 FOR TABLE t7 with (ddl = 'table');");
+my $publisher_connstr_db1 = $node_publisher->connstr . ' dbname=db1';
+$node_subscriber->safe_psql('postgres', "CREATE DATABASE db1;");
+$node_subscriber->safe_psql('db1', "CREATE TABLE t7 (id int primary key, name varchar);");
+$node_subscriber->safe_psql('db1', "CREATE TABLE t8 (id int primary key, name varchar);");
+$node_subscriber->safe_psql('db1',
+ "CREATE SUBSCRIPTION mysub3 CONNECTION '$publisher_connstr_db1' PUBLICATION mypub3;"
+);
+$node_publisher->wait_for_catchup('mysub3');
+$node_publisher->safe_psql('db1', "ALTER TABLE t7 RENAME TO newt7;");
+$node_publisher->safe_psql('db1', "ALTER TABLE t8 RENAME TO newt8;");
+$node_publisher->wait_for_catchup('mysub3');
+$result = $node_subscriber->safe_psql('db1', "SELECT count(*) from pg_tables where tablename = 'newt7';");
+is($result, qq(1), 'Rename t7 to newt7 is replicated');
+$result = $node_subscriber->safe_psql('db1', "SELECT count(*) from pg_tables where tablename = 'newt8';");
+is($result, qq(0), 'Rename t8 to newt8 is not replicated');
+
#TEST DDL in function
$node_publisher->safe_psql('postgres', qq{
CREATE OR REPLACE FUNCTION func_ddl (tname varchar(20))
--
2.32.0