PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
publicationcmds.h File Reference
Include dependency graph for publicationcmds.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MAX_RELCACHE_INVAL_MSGS   4096
 

Functions

ObjectAddress CreatePublication (ParseState *pstate, CreatePublicationStmt *stmt)
 
void AlterPublication (ParseState *pstate, AlterPublicationStmt *stmt)
 
void RemovePublicationById (Oid pubid)
 
void RemovePublicationRelById (Oid proid)
 
void RemovePublicationSchemaById (Oid psoid)
 
ObjectAddress AlterPublicationOwner (const char *name, Oid newOwnerId)
 
void AlterPublicationOwner_oid (Oid subid, Oid newOwnerId)
 
void InvalidatePublicationRels (List *relids)
 
bool pub_rf_contains_invalid_column (Oid pubid, Relation relation, List *ancestors, bool pubviaroot)
 
bool pub_contains_invalid_column (Oid pubid, Relation relation, List *ancestors, bool pubviaroot, bool pubgencols, bool *invalid_column_list, bool *invalid_gen_col)
 

Macro Definition Documentation

◆ MAX_RELCACHE_INVAL_MSGS

#define MAX_RELCACHE_INVAL_MSGS   4096

Definition at line 23 of file publicationcmds.h.

Function Documentation

◆ AlterPublication()

void AlterPublication ( ParseState pstate,
AlterPublicationStmt stmt 
)

Definition at line 1416 of file publicationcmds.c.

1417{
1418 Relation rel;
1419 HeapTuple tup;
1420 Form_pg_publication pubform;
1421
1422 rel = table_open(PublicationRelationId, RowExclusiveLock);
1423
1424 tup = SearchSysCacheCopy1(PUBLICATIONNAME,
1425 CStringGetDatum(stmt->pubname));
1426
1427 if (!HeapTupleIsValid(tup))
1428 ereport(ERROR,
1429 (errcode(ERRCODE_UNDEFINED_OBJECT),
1430 errmsg("publication \"%s\" does not exist",
1431 stmt->pubname)));
1432
1433 pubform = (Form_pg_publication) GETSTRUCT(tup);
1434
1435 /* must be owner */
1436 if (!object_ownercheck(PublicationRelationId, pubform->oid, GetUserId()))
1438 stmt->pubname);
1439
1440 if (stmt->options)
1441 AlterPublicationOptions(pstate, stmt, rel, tup);
1442 else
1443 {
1444 List *relations = NIL;
1445 List *schemaidlist = NIL;
1446 Oid pubid = pubform->oid;
1447
1448 ObjectsInPublicationToOids(stmt->pubobjects, pstate, &relations,
1449 &schemaidlist);
1450
1451 CheckAlterPublication(stmt, tup, relations, schemaidlist);
1452
1453 heap_freetuple(tup);
1454
1455 /* Lock the publication so nobody else can do anything with it. */
1456 LockDatabaseObject(PublicationRelationId, pubid, 0,
1458
1459 /*
1460 * It is possible that by the time we acquire the lock on publication,
1461 * concurrent DDL has removed it. We can test this by checking the
1462 * existence of publication. We get the tuple again to avoid the risk
1463 * of any publication option getting changed.
1464 */
1465 tup = SearchSysCacheCopy1(PUBLICATIONOID, ObjectIdGetDatum(pubid));
1466 if (!HeapTupleIsValid(tup))
1467 ereport(ERROR,
1468 errcode(ERRCODE_UNDEFINED_OBJECT),
1469 errmsg("publication \"%s\" does not exist",
1470 stmt->pubname));
1471
1472 AlterPublicationTables(stmt, tup, relations, pstate->p_sourcetext,
1473 schemaidlist != NIL);
1474 AlterPublicationSchemas(stmt, tup, schemaidlist);
1475 }
1476
1477 /* Cleanup. */
1478 heap_freetuple(tup);
1480}
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2622
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:4064
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1435
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
#define stmt
Definition: indent_codes.h:59
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:993
#define AccessExclusiveLock
Definition: lockdefs.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid GetUserId(void)
Definition: miscinit.c:517
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2298
#define NIL
Definition: pg_list.h:68
FormData_pg_publication * Form_pg_publication
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
unsigned int Oid
Definition: postgres_ext.h:31
static void AlterPublicationSchemas(AlterPublicationStmt *stmt, HeapTuple tup, List *schemaidlist)
static void ObjectsInPublicationToOids(List *pubobjspec_list, ParseState *pstate, List **rels, List **schemas)
static void CheckAlterPublication(AlterPublicationStmt *stmt, HeapTuple tup, List *tables, List *schemaidlist)
static void AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, Relation rel, HeapTuple tup)
static void AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup, List *tables, const char *queryString, bool publish_schema)
Definition: pg_list.h:54
const char * p_sourcetext
Definition: parse_node.h:209
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:91
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References AccessExclusiveLock, aclcheck_error(), ACLCHECK_NOT_OWNER, AlterPublicationOptions(), AlterPublicationSchemas(), AlterPublicationTables(), CheckAlterPublication(), CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, GETSTRUCT, GetUserId(), heap_freetuple(), HeapTupleIsValid, LockDatabaseObject(), NIL, object_ownercheck(), OBJECT_PUBLICATION, ObjectIdGetDatum(), ObjectsInPublicationToOids(), ParseState::p_sourcetext, RowExclusiveLock, SearchSysCacheCopy1, stmt, table_close(), and table_open().

Referenced by ProcessUtilitySlow().

◆ AlterPublicationOwner()

ObjectAddress AlterPublicationOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 1991 of file publicationcmds.c.

1992{
1993 Oid subid;
1994 HeapTuple tup;
1995 Relation rel;
1996 ObjectAddress address;
1997 Form_pg_publication pubform;
1998
1999 rel = table_open(PublicationRelationId, RowExclusiveLock);
2000
2001 tup = SearchSysCacheCopy1(PUBLICATIONNAME, CStringGetDatum(name));
2002
2003 if (!HeapTupleIsValid(tup))
2004 ereport(ERROR,
2005 (errcode(ERRCODE_UNDEFINED_OBJECT),
2006 errmsg("publication \"%s\" does not exist", name)));
2007
2008 pubform = (Form_pg_publication) GETSTRUCT(tup);
2009 subid = pubform->oid;
2010
2011 AlterPublicationOwner_internal(rel, tup, newOwnerId);
2012
2013 ObjectAddressSet(address, PublicationRelationId, subid);
2014
2015 heap_freetuple(tup);
2016
2018
2019 return address;
2020}
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
static void AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
const char * name

References AlterPublicationOwner_internal(), CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, GETSTRUCT, heap_freetuple(), HeapTupleIsValid, name, ObjectAddressSet, RowExclusiveLock, SearchSysCacheCopy1, table_close(), and table_open().

Referenced by ExecAlterOwnerStmt().

◆ AlterPublicationOwner_oid()

void AlterPublicationOwner_oid ( Oid  subid,
Oid  newOwnerId 
)

Definition at line 2026 of file publicationcmds.c.

2027{
2028 HeapTuple tup;
2029 Relation rel;
2030
2031 rel = table_open(PublicationRelationId, RowExclusiveLock);
2032
2033 tup = SearchSysCacheCopy1(PUBLICATIONOID, ObjectIdGetDatum(subid));
2034
2035 if (!HeapTupleIsValid(tup))
2036 ereport(ERROR,
2037 (errcode(ERRCODE_UNDEFINED_OBJECT),
2038 errmsg("publication with OID %u does not exist", subid)));
2039
2040 AlterPublicationOwner_internal(rel, tup, newOwnerId);
2041
2042 heap_freetuple(tup);
2043
2045}

References AlterPublicationOwner_internal(), ereport, errcode(), errmsg(), ERROR, heap_freetuple(), HeapTupleIsValid, ObjectIdGetDatum(), RowExclusiveLock, SearchSysCacheCopy1, table_close(), and table_open().

Referenced by shdepReassignOwned_Owner().

◆ CreatePublication()

ObjectAddress CreatePublication ( ParseState pstate,
CreatePublicationStmt stmt 
)

Definition at line 765 of file publicationcmds.c.

766{
767 Relation rel;
768 ObjectAddress myself;
769 Oid puboid;
770 bool nulls[Natts_pg_publication];
771 Datum values[Natts_pg_publication];
772 HeapTuple tup;
773 bool publish_given;
774 PublicationActions pubactions;
775 bool publish_via_partition_root_given;
776 bool publish_via_partition_root;
777 bool publish_generated_columns_given;
778 bool publish_generated_columns;
779 AclResult aclresult;
780 List *relations = NIL;
781 List *schemaidlist = NIL;
782
783 /* must have CREATE privilege on database */
784 aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(), ACL_CREATE);
785 if (aclresult != ACLCHECK_OK)
788
789 /* FOR ALL TABLES requires superuser */
790 if (stmt->for_all_tables && !superuser())
792 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
793 errmsg("must be superuser to create FOR ALL TABLES publication")));
794
795 rel = table_open(PublicationRelationId, RowExclusiveLock);
796
797 /* Check if name is used */
798 puboid = GetSysCacheOid1(PUBLICATIONNAME, Anum_pg_publication_oid,
799 CStringGetDatum(stmt->pubname));
800 if (OidIsValid(puboid))
803 errmsg("publication \"%s\" already exists",
804 stmt->pubname)));
805
806 /* Form a tuple. */
807 memset(values, 0, sizeof(values));
808 memset(nulls, false, sizeof(nulls));
809
810 values[Anum_pg_publication_pubname - 1] =
812 values[Anum_pg_publication_pubowner - 1] = ObjectIdGetDatum(GetUserId());
813
815 stmt->options,
816 &publish_given, &pubactions,
817 &publish_via_partition_root_given,
818 &publish_via_partition_root,
819 &publish_generated_columns_given,
820 &publish_generated_columns);
821
822 puboid = GetNewOidWithIndex(rel, PublicationObjectIndexId,
823 Anum_pg_publication_oid);
824 values[Anum_pg_publication_oid - 1] = ObjectIdGetDatum(puboid);
825 values[Anum_pg_publication_puballtables - 1] =
826 BoolGetDatum(stmt->for_all_tables);
827 values[Anum_pg_publication_pubinsert - 1] =
828 BoolGetDatum(pubactions.pubinsert);
829 values[Anum_pg_publication_pubupdate - 1] =
830 BoolGetDatum(pubactions.pubupdate);
831 values[Anum_pg_publication_pubdelete - 1] =
832 BoolGetDatum(pubactions.pubdelete);
833 values[Anum_pg_publication_pubtruncate - 1] =
834 BoolGetDatum(pubactions.pubtruncate);
835 values[Anum_pg_publication_pubviaroot - 1] =
836 BoolGetDatum(publish_via_partition_root);
837 values[Anum_pg_publication_pubgencols - 1] =
838 BoolGetDatum(publish_generated_columns);
839
840 tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
841
842 /* Insert tuple into catalog. */
843 CatalogTupleInsert(rel, tup);
844 heap_freetuple(tup);
845
846 recordDependencyOnOwner(PublicationRelationId, puboid, GetUserId());
847
848 ObjectAddressSet(myself, PublicationRelationId, puboid);
849
850 /* Make the changes visible. */
852
853 /* Associate objects with the publication. */
854 if (stmt->for_all_tables)
855 {
856 /* Invalidate relcache so that publication info is rebuilt. */
858 }
859 else
860 {
861 ObjectsInPublicationToOids(stmt->pubobjects, pstate, &relations,
862 &schemaidlist);
863
864 /* FOR TABLES IN SCHEMA requires superuser */
865 if (schemaidlist != NIL && !superuser())
867 errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
868 errmsg("must be superuser to create FOR TABLES IN SCHEMA publication"));
869
870 if (relations != NIL)
871 {
872 List *rels;
873
874 rels = OpenTableList(relations);
876 publish_via_partition_root);
877
878 CheckPubRelationColumnList(stmt->pubname, rels,
879 schemaidlist != NIL,
880 publish_via_partition_root);
881
882 PublicationAddTables(puboid, rels, true, NULL);
883 CloseTableList(rels);
884 }
885
886 if (schemaidlist != NIL)
887 {
888 /*
889 * Schema lock is held until the publication is created to prevent
890 * concurrent schema deletion.
891 */
892 LockSchemaList(schemaidlist);
893 PublicationAddSchemas(puboid, schemaidlist, true, NULL);
894 }
895 }
896
898
899 InvokeObjectPostCreateHook(PublicationRelationId, puboid, 0);
900
903 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
904 errmsg("\"wal_level\" is insufficient to publish logical changes"),
905 errhint("Set \"wal_level\" to \"logical\" before creating subscriptions.")));
906
907 return myself;
908}
AclResult
Definition: acl.h:182
@ ACLCHECK_OK
Definition: acl.h:183
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3810
static Datum values[MAXATTR]
Definition: bootstrap.c:151
#define OidIsValid(objectId)
Definition: c.h:729
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:419
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3187
int errhint(const char *fmt,...)
Definition: elog.c:1317
#define WARNING
Definition: elog.h:36
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:641
Oid MyDatabaseId
Definition: globals.c:93
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:233
void CacheInvalidateRelcacheAll(void)
Definition: inval.c:1576
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:48
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:173
@ OBJECT_DATABASE
Definition: parsenodes.h:2277
#define ACL_CREATE
Definition: parsenodes.h:85
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:168
uintptr_t Datum
Definition: postgres.h:64
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static void PublicationAddSchemas(Oid pubid, List *schemas, bool if_not_exists, AlterPublicationStmt *stmt)
static void PublicationAddTables(Oid pubid, List *rels, bool if_not_exists, AlterPublicationStmt *stmt)
static void CloseTableList(List *rels)
static void TransformPubWhereClauses(List *tables, const char *queryString, bool pubviaroot)
static void parse_publication_options(ParseState *pstate, List *options, bool *publish_given, PublicationActions *pubactions, bool *publish_via_partition_root_given, bool *publish_via_partition_root, bool *publish_generated_columns_given, bool *publish_generated_columns)
static List * OpenTableList(List *tables)
static void CheckPubRelationColumnList(char *pubname, List *tables, bool publish_schema, bool pubviaroot)
static void LockSchemaList(List *schemalist)
#define RelationGetDescr(relation)
Definition: rel.h:531
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:30
bool superuser(void)
Definition: superuser.c:46
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:109
void CommandCounterIncrement(void)
Definition: xact.c:1099
int wal_level
Definition: xlog.c:131
@ WAL_LEVEL_LOGICAL
Definition: xlog.h:76

References ACL_CREATE, aclcheck_error(), ACLCHECK_OK, BoolGetDatum(), CacheInvalidateRelcacheAll(), CatalogTupleInsert(), CheckPubRelationColumnList(), CloseTableList(), CommandCounterIncrement(), CStringGetDatum(), DirectFunctionCall1, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errhint(), errmsg(), ERROR, get_database_name(), GetNewOidWithIndex(), GetSysCacheOid1, GetUserId(), heap_form_tuple(), heap_freetuple(), InvokeObjectPostCreateHook, LockSchemaList(), MyDatabaseId, namein(), NIL, object_aclcheck(), OBJECT_DATABASE, ObjectAddressSet, ObjectIdGetDatum(), ObjectsInPublicationToOids(), OidIsValid, OpenTableList(), ParseState::p_sourcetext, parse_publication_options(), PublicationActions::pubdelete, PublicationActions::pubinsert, PublicationAddSchemas(), PublicationAddTables(), PublicationActions::pubtruncate, PublicationActions::pubupdate, recordDependencyOnOwner(), RelationGetDescr, RowExclusiveLock, stmt, superuser(), table_close(), table_open(), TransformPubWhereClauses(), values, wal_level, WAL_LEVEL_LOGICAL, and WARNING.

Referenced by ProcessUtilitySlow().

◆ InvalidatePublicationRels()

void InvalidatePublicationRels ( List relids)

Definition at line 1111 of file publicationcmds.c.

1112{
1113 /*
1114 * We don't want to send too many individual messages, at some point it's
1115 * cheaper to just reset whole relcache.
1116 */
1118 {
1119 ListCell *lc;
1120
1121 foreach(lc, relids)
1123 }
1124 else
1126}
void CacheInvalidateRelcacheByRelid(Oid relid)
Definition: inval.c:1609
static int list_length(const List *l)
Definition: pg_list.h:152
#define lfirst_oid(lc)
Definition: pg_list.h:174
#define MAX_RELCACHE_INVAL_MSGS

References CacheInvalidateRelcacheAll(), CacheInvalidateRelcacheByRelid(), lfirst_oid, list_length(), and MAX_RELCACHE_INVAL_MSGS.

Referenced by AlterPublicationOptions(), publication_add_relation(), publication_add_schema(), RemovePublicationRelById(), and RemovePublicationSchemaById().

◆ pub_contains_invalid_column()

bool pub_contains_invalid_column ( Oid  pubid,
Relation  relation,
List ancestors,
bool  pubviaroot,
bool  pubgencols,
bool *  invalid_column_list,
bool *  invalid_gen_col 
)

Definition at line 354 of file publicationcmds.c.

358{
359 Oid relid = RelationGetRelid(relation);
360 Oid publish_as_relid = RelationGetRelid(relation);
361 Bitmapset *idattrs;
362 Bitmapset *columns = NULL;
363 TupleDesc desc = RelationGetDescr(relation);
364 Publication *pub;
365 int x;
366
367 *invalid_column_list = false;
368 *invalid_gen_col = false;
369
370 /*
371 * For a partition, if pubviaroot is true, find the topmost ancestor that
372 * is published via this publication as we need to use its column list for
373 * the changes.
374 *
375 * Note that even though the column list used is for an ancestor, the
376 * REPLICA IDENTITY used will be for the actual child table.
377 */
378 if (pubviaroot && relation->rd_rel->relispartition)
379 {
380 publish_as_relid = GetTopMostAncestorInPublication(pubid, ancestors, NULL);
381
382 if (!OidIsValid(publish_as_relid))
383 publish_as_relid = relid;
384 }
385
386 /* Fetch the column list */
387 pub = GetPublication(pubid);
388 check_and_fetch_column_list(pub, publish_as_relid, NULL, &columns);
389
390 if (relation->rd_rel->relreplident == REPLICA_IDENTITY_FULL)
391 {
392 /* With REPLICA IDENTITY FULL, no column list is allowed. */
393 *invalid_column_list = (columns != NULL);
394
395 /*
396 * As we don't allow a column list with REPLICA IDENTITY FULL, the
397 * publish_generated_columns option must be set to true if the table
398 * has any stored generated columns.
399 */
400 if (!pubgencols &&
401 relation->rd_att->constr &&
403 *invalid_gen_col = true;
404
405 if (*invalid_gen_col && *invalid_column_list)
406 return true;
407 }
408
409 /* Remember columns that are part of the REPLICA IDENTITY */
410 idattrs = RelationGetIndexAttrBitmap(relation,
412
413 /*
414 * Attnums in the bitmap returned by RelationGetIndexAttrBitmap are offset
415 * (to handle system columns the usual way), while column list does not
416 * use offset, so we can't do bms_is_subset(). Instead, we have to loop
417 * over the idattrs and check all of them are in the list.
418 */
419 x = -1;
420 while ((x = bms_next_member(idattrs, x)) >= 0)
421 {
423 Form_pg_attribute att = TupleDescAttr(desc, attnum - 1);
424
425 if (columns == NULL)
426 {
427 /*
428 * The publish_generated_columns option must be set to true if the
429 * REPLICA IDENTITY contains any stored generated column.
430 */
431 if (!pubgencols && att->attgenerated)
432 {
433 *invalid_gen_col = true;
434 break;
435 }
436
437 /* Skip validating the column list since it is not defined */
438 continue;
439 }
440
441 /*
442 * If pubviaroot is true, we are validating the column list of the
443 * parent table, but the bitmap contains the replica identity
444 * information of the child table. The parent/child attnums may not
445 * match, so translate them to the parent - get the attname from the
446 * child, and look it up in the parent.
447 */
448 if (pubviaroot)
449 {
450 /* attribute name in the child table */
451 char *colname = get_attname(relid, attnum, false);
452
453 /*
454 * Determine the attnum for the attribute name in parent (we are
455 * using the column list defined on the parent).
456 */
457 attnum = get_attnum(publish_as_relid, colname);
458 }
459
460 /* replica identity column, not covered by the column list */
461 *invalid_column_list |= !bms_is_member(attnum, columns);
462
463 if (*invalid_column_list && *invalid_gen_col)
464 break;
465 }
466
467 bms_free(columns);
468 bms_free(idattrs);
469
470 return *invalid_column_list || *invalid_gen_col;
471}
int16 AttrNumber
Definition: attnum.h:21
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1306
void bms_free(Bitmapset *a)
Definition: bitmapset.c:239
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:510
int x
Definition: isn.c:70
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:858
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition: lsyscache.c:827
int16 attnum
Definition: pg_attribute.h:74
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
Oid GetTopMostAncestorInPublication(Oid puboid, List *ancestors, int *ancestor_level)
Publication * GetPublication(Oid pubid)
bool check_and_fetch_column_list(Publication *pub, Oid relid, MemoryContext mcxt, Bitmapset **cols)
#define RelationGetRelid(relation)
Definition: rel.h:505
Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
Definition: relcache.c:5222
@ INDEX_ATTR_BITMAP_IDENTITY_KEY
Definition: relcache.h:63
TupleDesc rd_att
Definition: rel.h:112
Form_pg_class rd_rel
Definition: rel.h:111
bool has_generated_stored
Definition: tupdesc.h:45
TupleConstr * constr
Definition: tupdesc.h:133
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:152

References attnum, bms_free(), bms_is_member(), bms_next_member(), check_and_fetch_column_list(), TupleDescData::constr, FirstLowInvalidHeapAttributeNumber, get_attname(), get_attnum(), GetPublication(), GetTopMostAncestorInPublication(), TupleConstr::has_generated_stored, INDEX_ATTR_BITMAP_IDENTITY_KEY, OidIsValid, RelationData::rd_att, RelationData::rd_rel, RelationGetDescr, RelationGetIndexAttrBitmap(), RelationGetRelid, TupleDescAttr(), and x.

Referenced by RelationBuildPublicationDesc().

◆ pub_rf_contains_invalid_column()

bool pub_rf_contains_invalid_column ( Oid  pubid,
Relation  relation,
List ancestors,
bool  pubviaroot 
)

Definition at line 269 of file publicationcmds.c.

271{
272 HeapTuple rftuple;
273 Oid relid = RelationGetRelid(relation);
274 Oid publish_as_relid = RelationGetRelid(relation);
275 bool result = false;
276 Datum rfdatum;
277 bool rfisnull;
278
279 /*
280 * FULL means all columns are in the REPLICA IDENTITY, so all columns are
281 * allowed in the row filter and we can skip the validation.
282 */
283 if (relation->rd_rel->relreplident == REPLICA_IDENTITY_FULL)
284 return false;
285
286 /*
287 * For a partition, if pubviaroot is true, find the topmost ancestor that
288 * is published via this publication as we need to use its row filter
289 * expression to filter the partition's changes.
290 *
291 * Note that even though the row filter used is for an ancestor, the
292 * REPLICA IDENTITY used will be for the actual child table.
293 */
294 if (pubviaroot && relation->rd_rel->relispartition)
295 {
296 publish_as_relid
297 = GetTopMostAncestorInPublication(pubid, ancestors, NULL);
298
299 if (!OidIsValid(publish_as_relid))
300 publish_as_relid = relid;
301 }
302
303 rftuple = SearchSysCache2(PUBLICATIONRELMAP,
304 ObjectIdGetDatum(publish_as_relid),
305 ObjectIdGetDatum(pubid));
306
307 if (!HeapTupleIsValid(rftuple))
308 return false;
309
310 rfdatum = SysCacheGetAttr(PUBLICATIONRELMAP, rftuple,
311 Anum_pg_publication_rel_prqual,
312 &rfisnull);
313
314 if (!rfisnull)
315 {
316 rf_context context = {0};
317 Node *rfnode;
318 Bitmapset *bms = NULL;
319
320 context.pubviaroot = pubviaroot;
321 context.parentid = publish_as_relid;
322 context.relid = relid;
323
324 /* Remember columns that are part of the REPLICA IDENTITY */
325 bms = RelationGetIndexAttrBitmap(relation,
327
328 context.bms_replident = bms;
329 rfnode = stringToNode(TextDatumGetCString(rfdatum));
330 result = contain_invalid_rfcolumn_walker(rfnode, &context);
331 }
332
333 ReleaseSysCache(rftuple);
334
335 return result;
336}
#define TextDatumGetCString(d)
Definition: builtins.h:98
static bool contain_invalid_rfcolumn_walker(Node *node, rf_context *context)
void * stringToNode(const char *str)
Definition: read.c:90
Definition: nodes.h:129
Bitmapset * bms_replident
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:600
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:232

References rf_context::bms_replident, contain_invalid_rfcolumn_walker(), GetTopMostAncestorInPublication(), HeapTupleIsValid, INDEX_ATTR_BITMAP_IDENTITY_KEY, ObjectIdGetDatum(), OidIsValid, rf_context::parentid, rf_context::pubviaroot, RelationData::rd_rel, RelationGetIndexAttrBitmap(), RelationGetRelid, ReleaseSysCache(), rf_context::relid, SearchSysCache2(), stringToNode(), SysCacheGetAttr(), and TextDatumGetCString.

Referenced by RelationBuildPublicationDesc().

◆ RemovePublicationById()

void RemovePublicationById ( Oid  pubid)

Definition at line 1527 of file publicationcmds.c.

1528{
1529 Relation rel;
1530 HeapTuple tup;
1531 Form_pg_publication pubform;
1532
1533 rel = table_open(PublicationRelationId, RowExclusiveLock);
1534
1535 tup = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pubid));
1536 if (!HeapTupleIsValid(tup))
1537 elog(ERROR, "cache lookup failed for publication %u", pubid);
1538
1539 pubform = (Form_pg_publication) GETSTRUCT(tup);
1540
1541 /* Invalidate relcache so that publication info is rebuilt. */
1542 if (pubform->puballtables)
1544
1545 CatalogTupleDelete(rel, &tup->t_self);
1546
1547 ReleaseSysCache(tup);
1548
1550}
#define elog(elevel,...)
Definition: elog.h:225
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:365
ItemPointerData t_self
Definition: htup.h:65
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221

References CacheInvalidateRelcacheAll(), CatalogTupleDelete(), elog, ERROR, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by doDeletion().

◆ RemovePublicationRelById()

void RemovePublicationRelById ( Oid  proid)

Definition at line 1486 of file publicationcmds.c.

1487{
1488 Relation rel;
1489 HeapTuple tup;
1491 List *relids = NIL;
1492
1493 rel = table_open(PublicationRelRelationId, RowExclusiveLock);
1494
1495 tup = SearchSysCache1(PUBLICATIONREL, ObjectIdGetDatum(proid));
1496
1497 if (!HeapTupleIsValid(tup))
1498 elog(ERROR, "cache lookup failed for publication table %u",
1499 proid);
1500
1501 pubrel = (Form_pg_publication_rel) GETSTRUCT(tup);
1502
1503 /*
1504 * Invalidate relcache so that publication info is rebuilt.
1505 *
1506 * For the partitioned tables, we must invalidate all partitions contained
1507 * in the respective partition hierarchies, not just the one explicitly
1508 * mentioned in the publication. This is required because we implicitly
1509 * publish the child tables when the parent table is published.
1510 */
1512 pubrel->prrelid);
1513
1515
1516 CatalogTupleDelete(rel, &tup->t_self);
1517
1518 ReleaseSysCache(tup);
1519
1521}
List * GetPubPartitionOptionRelations(List *result, PublicationPartOpt pub_partopt, Oid relid)
@ PUBLICATION_PART_ALL
FormData_pg_publication_rel * Form_pg_publication_rel
void InvalidatePublicationRels(List *relids)

References CatalogTupleDelete(), elog, ERROR, GetPubPartitionOptionRelations(), GETSTRUCT, HeapTupleIsValid, InvalidatePublicationRels(), NIL, ObjectIdGetDatum(), PUBLICATION_PART_ALL, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by doDeletion().

◆ RemovePublicationSchemaById()

void RemovePublicationSchemaById ( Oid  psoid)

Definition at line 1556 of file publicationcmds.c.

1557{
1558 Relation rel;
1559 HeapTuple tup;
1560 List *schemaRels = NIL;
1562
1563 rel = table_open(PublicationNamespaceRelationId, RowExclusiveLock);
1564
1565 tup = SearchSysCache1(PUBLICATIONNAMESPACE, ObjectIdGetDatum(psoid));
1566
1567 if (!HeapTupleIsValid(tup))
1568 elog(ERROR, "cache lookup failed for publication schema %u", psoid);
1569
1571
1572 /*
1573 * Invalidate relcache so that publication info is rebuilt. See
1574 * RemovePublicationRelById for why we need to consider all the
1575 * partitions.
1576 */
1577 schemaRels = GetSchemaPublicationRelations(pubsch->pnnspid,
1579 InvalidatePublicationRels(schemaRels);
1580
1581 CatalogTupleDelete(rel, &tup->t_self);
1582
1583 ReleaseSysCache(tup);
1584
1586}
List * GetSchemaPublicationRelations(Oid schemaid, PublicationPartOpt pub_partopt)
FormData_pg_publication_namespace * Form_pg_publication_namespace

References CatalogTupleDelete(), elog, ERROR, GetSchemaPublicationRelations(), GETSTRUCT, HeapTupleIsValid, InvalidatePublicationRels(), NIL, ObjectIdGetDatum(), PUBLICATION_PART_ALL, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by doDeletion().