Add PublicationTable and PublicationRelInfo structs
authorAlvaro Herrera
Mon, 6 Sep 2021 17:24:50 +0000 (14:24 -0300)
committerAlvaro Herrera
Mon, 6 Sep 2021 17:24:50 +0000 (14:24 -0300)
These encapsulate a relation when referred from replication DDL.
Currently they don't do anything useful (they're just wrappers around
RangeVar and Relation respectively) but in the future they'll be used to
carry column lists.

Extracted from a larger patch by Rahila Syed.

Author: Rahila Syed 
Reviewed-by: Álvaro Herrera
Reviewed-by: Tomas Vondra
Reviewed-by: Amit Kapila
Discussion: https://postgr.es/m/CAH2L28vddB_NFdRVpuyRBJEBWjz4BSyTB=_ektNRH8NJ1jf95g@mail.gmail.com

src/backend/catalog/pg_publication.c
src/backend/commands/publicationcmds.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/include/catalog/pg_publication.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/tools/pgindent/typedefs.list

index 2a2fe03c13fe05c28123c71c86755760aa1ba048..d6fddd6efe7641d1c9aa4c58f1779988fe6e1994 100644 (file)
@@ -141,14 +141,14 @@ pg_relation_is_publishable(PG_FUNCTION_ARGS)
  * Insert new publication / relation mapping.
  */
 ObjectAddress
-publication_add_relation(Oid pubid, Relation targetrel,
+publication_add_relation(Oid pubid, PublicationRelInfo *targetrel,
                         bool if_not_exists)
 {
    Relation    rel;
    HeapTuple   tup;
    Datum       values[Natts_pg_publication_rel];
    bool        nulls[Natts_pg_publication_rel];
-   Oid         relid = RelationGetRelid(targetrel);
+   Oid         relid = RelationGetRelid(targetrel->relation);
    Oid         prrelid;
    Publication *pub = GetPublication(pubid);
    ObjectAddress myself,
@@ -172,10 +172,10 @@ publication_add_relation(Oid pubid, Relation targetrel,
        ereport(ERROR,
                (errcode(ERRCODE_DUPLICATE_OBJECT),
                 errmsg("relation \"%s\" is already member of publication \"%s\"",
-                       RelationGetRelationName(targetrel), pub->name)));
+                       RelationGetRelationName(targetrel->relation), pub->name)));
    }
 
-   check_publication_add_relation(targetrel);
+   check_publication_add_relation(targetrel->relation);
 
    /* Form a tuple. */
    memset(values, 0, sizeof(values));
@@ -209,7 +209,7 @@ publication_add_relation(Oid pubid, Relation targetrel,
    table_close(rel, RowExclusiveLock);
 
    /* Invalidate relcache so that publication info is rebuilt. */
-   CacheInvalidateRelcache(targetrel);
+   CacheInvalidateRelcache(targetrel->relation);
 
    return myself;
 }
index 8487eeb7e6907a8a3e4dd3577c999be8a922aff7..179a0ef9822847142b0d36c34dd14a870de56bf0 100644 (file)
@@ -393,21 +393,28 @@ AlterPublicationTables(AlterPublicationStmt *stmt, Relation rel,
 
            foreach(newlc, rels)
            {
-               Relation    newrel = (Relation) lfirst(newlc);
+               PublicationRelInfo *newpubrel;
 
-               if (RelationGetRelid(newrel) == oldrelid)
+               newpubrel = (PublicationRelInfo *) lfirst(newlc);
+               if (RelationGetRelid(newpubrel->relation) == oldrelid)
                {
                    found = true;
                    break;
                }
            }
-
+           /* Not yet in the list, open it and add to the list */
            if (!found)
            {
-               Relation    oldrel = table_open(oldrelid,
-                                               ShareUpdateExclusiveLock);
+               Relation    oldrel;
+               PublicationRelInfo *pubrel;
+
+               /* Wrap relation into PublicationRelInfo */
+               oldrel = table_open(oldrelid, ShareUpdateExclusiveLock);
+
+               pubrel = palloc(sizeof(PublicationRelInfo));
+               pubrel->relation = oldrel;
 
-               delrels = lappend(delrels, oldrel);
+               delrels = lappend(delrels, pubrel);
            }
        }
 
@@ -498,9 +505,9 @@ RemovePublicationRelById(Oid proid)
 }
 
 /*
- * Open relations specified by a RangeVar list.
- * The returned tables are locked in ShareUpdateExclusiveLock mode in order to
- * add them to a publication.
+ * Open relations specified by a PublicationTable list.
+ * In the returned list of PublicationRelInfo, tables are locked
+ * in ShareUpdateExclusiveLock mode in order to add them to a publication.
  */
 static List *
 OpenTableList(List *tables)
@@ -514,15 +521,16 @@ OpenTableList(List *tables)
     */
    foreach(lc, tables)
    {
-       RangeVar   *rv = lfirst_node(RangeVar, lc);
-       bool        recurse = rv->inh;
+       PublicationTable *t = lfirst_node(PublicationTable, lc);
+       bool        recurse = t->relation->inh;
        Relation    rel;
        Oid         myrelid;
+       PublicationRelInfo *pub_rel;
 
        /* Allow query cancel in case this takes a long time */
        CHECK_FOR_INTERRUPTS();
 
-       rel = table_openrv(rv, ShareUpdateExclusiveLock);
+       rel = table_openrv(t->relation, ShareUpdateExclusiveLock);
        myrelid = RelationGetRelid(rel);
 
        /*
@@ -538,7 +546,9 @@ OpenTableList(List *tables)
            continue;
        }
 
-       rels = lappend(rels, rel);
+       pub_rel = palloc(sizeof(PublicationRelInfo));
+       pub_rel->relation = rel;
+       rels = lappend(rels, pub_rel);
        relids = lappend_oid(relids, myrelid);
 
        /*
@@ -571,7 +581,9 @@ OpenTableList(List *tables)
 
                /* find_all_inheritors already got lock */
                rel = table_open(childrelid, NoLock);
-               rels = lappend(rels, rel);
+               pub_rel = palloc(sizeof(PublicationRelInfo));
+               pub_rel->relation = rel;
+               rels = lappend(rels, pub_rel);
                relids = lappend_oid(relids, childrelid);
            }
        }
@@ -592,9 +604,10 @@ CloseTableList(List *rels)
 
    foreach(lc, rels)
    {
-       Relation    rel = (Relation) lfirst(lc);
+       PublicationRelInfo *pub_rel;
 
-       table_close(rel, NoLock);
+       pub_rel = (PublicationRelInfo *) lfirst(lc);
+       table_close(pub_rel->relation, NoLock);
    }
 }
 
@@ -611,7 +624,8 @@ PublicationAddTables(Oid pubid, List *rels, bool if_not_exists,
 
    foreach(lc, rels)
    {
-       Relation    rel = (Relation) lfirst(lc);
+       PublicationRelInfo *pub_rel = (PublicationRelInfo *) lfirst(lc);
+       Relation    rel = pub_rel->relation;
        ObjectAddress obj;
 
        /* Must be owner of the table or superuser. */
@@ -619,7 +633,7 @@ PublicationAddTables(Oid pubid, List *rels, bool if_not_exists,
            aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind),
                           RelationGetRelationName(rel));
 
-       obj = publication_add_relation(pubid, rel, if_not_exists);
+       obj = publication_add_relation(pubid, pub_rel, if_not_exists);
        if (stmt)
        {
            EventTriggerCollectSimpleCommand(obj, InvalidObjectAddress,
@@ -643,7 +657,8 @@ PublicationDropTables(Oid pubid, List *rels, bool missing_ok)
 
    foreach(lc, rels)
    {
-       Relation    rel = (Relation) lfirst(lc);
+       PublicationRelInfo *pubrel = (PublicationRelInfo *) lfirst(lc);
+       Relation    rel = pubrel->relation;
        Oid         relid = RelationGetRelid(rel);
 
        prid = GetSysCacheOid2(PUBLICATIONRELMAP, Anum_pg_publication_rel_oid,
index 38251c2b8e2b756d0399adeceadacd2593afca5e..e308de170e922f8dc509071958f9d59cdba57468 100644 (file)
@@ -4939,6 +4939,15 @@ _copyForeignKeyCacheInfo(const ForeignKeyCacheInfo *from)
    return newnode;
 }
 
+static PublicationTable *
+_copyPublicationTable(const PublicationTable *from)
+{
+   PublicationTable *newnode = makeNode(PublicationTable);
+
+   COPY_NODE_FIELD(relation);
+
+   return newnode;
+}
 
 /*
  * copyObjectImpl -- implementation of copyObject(); see nodes/nodes.h
@@ -5854,6 +5863,9 @@ copyObjectImpl(const void *from)
        case T_PartitionCmd:
            retval = _copyPartitionCmd(from);
            break;
+       case T_PublicationTable:
+           retval = _copyPublicationTable(from);
+           break;
 
            /*
             * MISCELLANEOUS NODES
index 8a1762000c3b8f75982a710a0d79a4f903ff7ad4..99440b40be042ac9e1a09988383256f096dc5581 100644 (file)
@@ -3114,6 +3114,14 @@ _equalValue(const Value *a, const Value *b)
    return true;
 }
 
+static bool
+_equalPublicationTable(const PublicationTable *a, const PublicationTable *b)
+{
+   COMPARE_NODE_FIELD(relation);
+
+   return true;
+}
+
 /*
  * equal
  *   returns whether two nodes are equal
@@ -3862,6 +3870,9 @@ equal(const void *a, const void *b)
        case T_PartitionCmd:
            retval = _equalPartitionCmd(a, b);
            break;
+       case T_PublicationTable:
+           retval = _equalPublicationTable(a, b);
+           break;
 
        default:
            elog(ERROR, "unrecognized node type: %d",
index ee52036a21e0a8725c8f3af61b9545f642203fa1..6a0f46505c5c875c7b4d18c9fd54c95f13590c1f 100644 (file)
@@ -426,14 +426,14 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
                transform_element_list transform_type_list
                TriggerTransitions TriggerReferencing
                vacuum_relation_list opt_vacuum_relation_list
-               drop_option_list
+               drop_option_list publication_table_list
 
 %type    opt_routine_body
 %type  group_clause
 %type    group_by_list
 %type    group_by_item empty_grouping_set rollup_clause cube_clause
 %type    grouping_sets_clause
-%type    opt_publication_for_tables publication_for_tables
+%type    opt_publication_for_tables publication_for_tables publication_table
 
 %type    opt_fdw_options fdw_options
 %type  fdw_option
@@ -9620,7 +9620,7 @@ opt_publication_for_tables:
        ;
 
 publication_for_tables:
-           FOR TABLE relation_expr_list
+           FOR TABLE publication_table_list
                {
                    $$ = (Node *) $3;
                }
@@ -9630,6 +9630,20 @@ publication_for_tables:
                }
        ;
 
+publication_table_list:
+           publication_table
+                   { $$ = list_make1($1); }
+       | publication_table_list ',' publication_table
+               { $$ = lappend($1, $3); }
+       ;
+
+publication_table: relation_expr
+       {
+           PublicationTable *n = makeNode(PublicationTable);
+           n->relation = $1;
+           $$ = (Node *) n;
+       }
+   ;
 
 /*****************************************************************************
  *
@@ -9651,7 +9665,7 @@ AlterPublicationStmt:
                    n->options = $5;
                    $$ = (Node *)n;
                }
-           | ALTER PUBLICATION name ADD_P TABLE relation_expr_list
+           | ALTER PUBLICATION name ADD_P TABLE publication_table_list
                {
                    AlterPublicationStmt *n = makeNode(AlterPublicationStmt);
                    n->pubname = $3;
@@ -9659,7 +9673,7 @@ AlterPublicationStmt:
                    n->tableAction = DEFELEM_ADD;
                    $$ = (Node *)n;
                }
-           | ALTER PUBLICATION name SET TABLE relation_expr_list
+           | ALTER PUBLICATION name SET TABLE publication_table_list
                {
                    AlterPublicationStmt *n = makeNode(AlterPublicationStmt);
                    n->pubname = $3;
@@ -9667,7 +9681,7 @@ AlterPublicationStmt:
                    n->tableAction = DEFELEM_SET;
                    $$ = (Node *)n;
                }
-           | ALTER PUBLICATION name DROP TABLE relation_expr_list
+           | ALTER PUBLICATION name DROP TABLE publication_table_list
                {
                    AlterPublicationStmt *n = makeNode(AlterPublicationStmt);
                    n->pubname = $3;
index f332bad4d41044121265faea449c24a7570f4d68..561266aa3eedf26f6bb2e5c57143b10fe2c8cb35 100644 (file)
@@ -83,6 +83,11 @@ typedef struct Publication
    PublicationActions pubactions;
 } Publication;
 
+typedef struct PublicationRelInfo
+{
+   Relation    relation;
+} PublicationRelInfo;
+
 extern Publication *GetPublication(Oid pubid);
 extern Publication *GetPublicationByName(const char *pubname, bool missing_ok);
 extern List *GetRelationPublications(Oid relid);
@@ -108,7 +113,7 @@ extern List *GetAllTablesPublications(void);
 extern List *GetAllTablesPublicationRelations(bool pubviaroot);
 
 extern bool is_publishable_relation(Relation rel);
-extern ObjectAddress publication_add_relation(Oid pubid, Relation targetrel,
+extern ObjectAddress publication_add_relation(Oid pubid, PublicationRelInfo *targetrel,
                                              bool if_not_exists);
 
 extern Oid get_publication_oid(const char *pubname, bool missing_ok);
index 6a4d82f0a837c9c8ee9a550a5b1d03dc064b18a2..56d13ff0229ea294b7c8724d6641d09cef1cc4ae 100644 (file)
@@ -490,6 +490,7 @@ typedef enum NodeTag
    T_PartitionRangeDatum,
    T_PartitionCmd,
    T_VacuumRelation,
+   T_PublicationTable,
 
    /*
     * TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h)
index 7af13dee43b4f53c9ffc6d4f6eb136f644cbe3a2..743e5aa4f34bbf72cd835e8fb66de7178854dc59 100644 (file)
@@ -3624,6 +3624,11 @@ typedef struct AlterTSConfigurationStmt
    bool        missing_ok;     /* for DROP - skip error if missing? */
 } AlterTSConfigurationStmt;
 
+typedef struct PublicationTable
+{
+   NodeTag     type;
+   RangeVar   *relation;       /* relation to be published */
+} PublicationTable;
 
 typedef struct CreatePublicationStmt
 {
index f31a1e4e1ecaa27dc487e15c58bba942e0a209ee..423780652fbef5f05e0cd3a4a6e36b28118c9b1b 100644 (file)
@@ -2047,6 +2047,7 @@ PublicationActions
 PublicationInfo
 PublicationPartOpt
 PublicationRelInfo
+PublicationTable
 PullFilter
 PullFilterOps
 PushFilter