Alter_publication_set_table_where_clause_check.patch
text/x-patch
Filename: Alter_publication_set_table_where_clause_check.patch
Type: text/x-patch
Part: 0
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: unified
| File | + | − |
|---|---|---|
| src/backend/catalog/pg_publication.c | 27 | 14 |
| src/backend/commands/publicationcmds.c | 32 | 6 |
| src/include/catalog/pg_publication.h | 4 | 1 |
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index b80c21e6ae..ae4a46e44a 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -359,6 +359,32 @@ GetPubPartitionOptionRelations(List *result, PublicationPartOpt pub_partopt,
return result;
}
+Node *
+GetTransformedWhereClause(ParseState *pstate, PublicationRelInfo *pri,
+ bool bfixupcollation)
+{
+ ParseNamespaceItem *nsitem;
+ Node *transformedwhereclause = NULL;
+
+ pstate->p_sourcetext = nodeToString(pri->whereClause);
+
+ nsitem = addRangeTableEntryForRelation(pstate, pri->relation,
+ AccessShareLock,
+ NULL, false, false);
+ addNSItemToQuery(pstate, nsitem, false, true, true);
+
+ transformedwhereclause = transformWhereClause(pstate,
+ copyObject(pri->whereClause),
+ EXPR_KIND_PUBLICATION_WHERE,
+ "PUBLICATION WHERE");
+
+ /* Fix up collation information */
+ if (bfixupcollation)
+ assign_expr_collations(pstate, transformedwhereclause);
+
+ return transformedwhereclause;
+}
+
/*
* Insert new publication / relation mapping.
*/
@@ -377,7 +403,6 @@ publication_add_relation(Oid pubid, PublicationRelInfo *pri,
ObjectAddress myself,
referenced;
ParseState *pstate;
- ParseNamespaceItem *nsitem;
Node *whereclause = NULL;
List *relids = NIL;
@@ -408,20 +433,8 @@ publication_add_relation(Oid pubid, PublicationRelInfo *pri,
{
/* Set up a ParseState to parse with */
pstate = make_parsestate(NULL);
- pstate->p_sourcetext = nodeToString(pri->whereClause);
-
- nsitem = addRangeTableEntryForRelation(pstate, targetrel,
- AccessShareLock,
- NULL, false, false);
- addNSItemToQuery(pstate, nsitem, false, true, true);
-
- whereclause = transformWhereClause(pstate,
- copyObject(pri->whereClause),
- EXPR_KIND_PUBLICATION_WHERE,
- "PUBLICATION WHERE");
- /* Fix up collation information */
- assign_expr_collations(pstate, whereclause);
+ whereclause = GetTransformedWhereClause(pstate, pri, true);
/*
* Walk the parse-tree of this publication row filter expression and
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index 1c792ed9cb..6106ec25d4 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -497,6 +497,7 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup,
List *rels = NIL;
Form_pg_publication pubform = (Form_pg_publication) GETSTRUCT(tup);
Oid pubid = pubform->oid;
+ Node *oldrelwhereclause = NULL;
/*
* It is quite possible that for the SET case user has not specified any
@@ -554,8 +555,13 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup,
ObjectIdGetDatum(pubid));
if (HeapTupleIsValid(rftuple))
{
- SysCacheGetAttr(PUBLICATIONRELMAP, rftuple, Anum_pg_publication_rel_prqual,
- &rfisnull);
+ Datum whereClauseDatum;
+
+ whereClauseDatum = SysCacheGetAttr(PUBLICATIONRELMAP, rftuple, Anum_pg_publication_rel_prqual,
+ &rfisnull);
+ if (!rfisnull)
+ oldrelwhereclause = stringToNode(TextDatumGetCString(whereClauseDatum));
+
ReleaseSysCache(rftuple);
}
@@ -569,11 +575,31 @@ AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup,
* If the new relation or the old relation has a where clause,
* we need to remove it so that it can be added afresh later.
*/
- if (RelationGetRelid(newpubrel->relation) == oldrelid &&
- newpubrel->whereClause == NULL && rfisnull)
+ if (RelationGetRelid(newpubrel->relation) == oldrelid)
{
- found = true;
- break;
+ if (rfisnull && !newpubrel->whereClause)
+ {
+ found = true;
+ break;
+ }
+
+ if (!rfisnull && newpubrel->whereClause)
+ {
+ ParseState *pstate = make_parsestate(NULL);
+ Node *whereclause;
+
+ whereclause = GetTransformedWhereClause(pstate,
+ newpubrel,
+ false);
+ if (equal(oldrelwhereclause, whereclause))
+ {
+ free_parsestate(pstate);
+ found = true;
+ break;
+ }
+
+ free_parsestate(pstate);
+ }
}
}
diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h
index f698049633..8c63dd5f85 100644
--- a/src/include/catalog/pg_publication.h
+++ b/src/include/catalog/pg_publication.h
@@ -20,6 +20,7 @@
#include "catalog/genbki.h"
#include "catalog/objectaddress.h"
#include "catalog/pg_publication_d.h"
+#include "parser/parse_node.h"
/* ----------------
* pg_publication definition. cpp turns this into
@@ -142,7 +143,9 @@ extern ObjectAddress publication_add_schema(Oid pubid, Oid schemaid,
extern Oid get_publication_oid(const char *pubname, bool missing_ok);
extern char *get_publication_name(Oid pubid, bool missing_ok);
-
+extern Node *GetTransformedWhereClause(ParseState *pstate,
+ PublicationRelInfo *pri,
+ bool bfixupcollation);
extern bool check_rowfilter_replident(Node *node, Bitmapset *bms_replident);
#endif /* PG_PUBLICATION_H */