PostgreSQL Source Code  git master
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 pubid, Oid newOwnerId)
 
void InvalidatePublicationRels (List *relids)
 
bool pub_rf_contains_invalid_column (Oid pubid, Relation relation, List *ancestors, bool pubviaroot)
 
bool pub_collist_contains_invalid_column (Oid pubid, Relation relation, List *ancestors, bool pubviaroot)
 

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 1393 of file publicationcmds.c.

1394 {
1395  Relation rel;
1396  HeapTuple tup;
1397  Form_pg_publication pubform;
1398 
1399  rel = table_open(PublicationRelationId, RowExclusiveLock);
1400 
1402  CStringGetDatum(stmt->pubname));
1403 
1404  if (!HeapTupleIsValid(tup))
1405  ereport(ERROR,
1406  (errcode(ERRCODE_UNDEFINED_OBJECT),
1407  errmsg("publication \"%s\" does not exist",
1408  stmt->pubname)));
1409 
1410  pubform = (Form_pg_publication) GETSTRUCT(tup);
1411 
1412  /* must be owner */
1413  if (!pg_publication_ownercheck(pubform->oid, GetUserId()))
1415  stmt->pubname);
1416 
1417  if (stmt->options)
1418  AlterPublicationOptions(pstate, stmt, rel, tup);
1419  else
1420  {
1421  List *relations = NIL;
1422  List *schemaidlist = NIL;
1423  Oid pubid = pubform->oid;
1424 
1425  ObjectsInPublicationToOids(stmt->pubobjects, pstate, &relations,
1426  &schemaidlist);
1427 
1428  CheckAlterPublication(stmt, tup, relations, schemaidlist);
1429 
1430  heap_freetuple(tup);
1431 
1432  /*
1433  * Lock the publication so nobody else can do anything with it. This
1434  * prevents concurrent alter to add table(s) that were already going
1435  * to become part of the publication by adding corresponding schema(s)
1436  * via this command and similarly it will prevent the concurrent
1437  * addition of schema(s) for which there is any corresponding table
1438  * being added by this command.
1439  */
1440  LockDatabaseObject(PublicationRelationId, pubid, 0,
1442 
1443  /*
1444  * It is possible that by the time we acquire the lock on publication,
1445  * concurrent DDL has removed it. We can test this by checking the
1446  * existence of publication. We get the tuple again to avoid the risk
1447  * of any publication option getting changed.
1448  */
1450  if (!HeapTupleIsValid(tup))
1451  ereport(ERROR,
1452  errcode(ERRCODE_UNDEFINED_OBJECT),
1453  errmsg("publication \"%s\" does not exist",
1454  stmt->pubname));
1455 
1456  AlterPublicationTables(stmt, tup, relations, schemaidlist,
1457  pstate->p_sourcetext);
1458  AlterPublicationSchemas(stmt, tup, schemaidlist);
1459  }
1460 
1461  /* Cleanup. */
1462  heap_freetuple(tup);
1464 }
@ ACLCHECK_NOT_OWNER
Definition: acl.h:184
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3512
bool pg_publication_ownercheck(Oid pub_oid, Oid roleid)
Definition: aclchk.c:5709
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:143
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:649
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1005
#define AccessExclusiveLock
Definition: lockdefs.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid GetUserId(void)
Definition: miscinit.c:491
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2165
#define NIL
Definition: pg_list.h:66
FormData_pg_publication * Form_pg_publication
#define CStringGetDatum(X)
Definition: postgres.h:622
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
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 AlterPublicationTables(AlterPublicationStmt *stmt, HeapTuple tup, List *tables, List *schemaidlist, const char *queryString)
static void AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt, Relation rel, HeapTuple tup)
Definition: pg_list.h:52
const char * p_sourcetext
Definition: parse_node.h:182
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:179
@ PUBLICATIONOID
Definition: syscache.h:83
@ PUBLICATIONNAME
Definition: syscache.h:80
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

References AccessExclusiveLock, aclcheck_error(), ACLCHECK_NOT_OWNER, AlterPublicationOptions(), AlterPublicationSchemas(), AlterPublicationTables(), CheckAlterPublication(), CStringGetDatum, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, GetUserId(), heap_freetuple(), HeapTupleIsValid, LockDatabaseObject(), NIL, OBJECT_PUBLICATION, ObjectIdGetDatum, ObjectsInPublicationToOids(), AlterPublicationStmt::options, ParseState::p_sourcetext, pg_publication_ownercheck(), PUBLICATIONNAME, PUBLICATIONOID, AlterPublicationStmt::pubname, AlterPublicationStmt::pubobjects, RowExclusiveLock, SearchSysCacheCopy1, table_close(), and table_open().

Referenced by ProcessUtilitySlow().

◆ AlterPublicationOwner()

ObjectAddress AlterPublicationOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 2001 of file publicationcmds.c.

2002 {
2003  Oid subid;
2004  HeapTuple tup;
2005  Relation rel;
2006  ObjectAddress address;
2007  Form_pg_publication pubform;
2008 
2009  rel = table_open(PublicationRelationId, RowExclusiveLock);
2010 
2012 
2013  if (!HeapTupleIsValid(tup))
2014  ereport(ERROR,
2015  (errcode(ERRCODE_UNDEFINED_OBJECT),
2016  errmsg("publication \"%s\" does not exist", name)));
2017 
2018  pubform = (Form_pg_publication) GETSTRUCT(tup);
2019  subid = pubform->oid;
2020 
2021  AlterPublicationOwner_internal(rel, tup, newOwnerId);
2022 
2023  ObjectAddressSet(address, PublicationRelationId, subid);
2024 
2025  heap_freetuple(tup);
2026 
2028 
2029  return address;
2030 }
const char * name
Definition: encode.c:561
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
static void AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)

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

Referenced by ExecAlterOwnerStmt().

◆ AlterPublicationOwner_oid()

void AlterPublicationOwner_oid ( Oid  pubid,
Oid  newOwnerId 
)

Definition at line 2036 of file publicationcmds.c.

2037 {
2038  HeapTuple tup;
2039  Relation rel;
2040 
2041  rel = table_open(PublicationRelationId, RowExclusiveLock);
2042 
2044 
2045  if (!HeapTupleIsValid(tup))
2046  ereport(ERROR,
2047  (errcode(ERRCODE_UNDEFINED_OBJECT),
2048  errmsg("publication with OID %u does not exist", subid)));
2049 
2050  AlterPublicationOwner_internal(rel, tup, newOwnerId);
2051 
2052  heap_freetuple(tup);
2053 
2055 }

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

Referenced by shdepReassignOwned().

◆ CreatePublication()

ObjectAddress CreatePublication ( ParseState pstate,
CreatePublicationStmt stmt 
)

Definition at line 755 of file publicationcmds.c.

756 {
757  Relation rel;
758  ObjectAddress myself;
759  Oid puboid;
760  bool nulls[Natts_pg_publication];
761  Datum values[Natts_pg_publication];
762  HeapTuple tup;
763  bool publish_given;
764  PublicationActions pubactions;
765  bool publish_via_partition_root_given;
766  bool publish_via_partition_root;
767  AclResult aclresult;
768  List *relations = NIL;
769  List *schemaidlist = NIL;
770 
771  /* must have CREATE privilege on database */
773  if (aclresult != ACLCHECK_OK)
774  aclcheck_error(aclresult, OBJECT_DATABASE,
776 
777  /* FOR ALL TABLES requires superuser */
778  if (stmt->for_all_tables && !superuser())
779  ereport(ERROR,
780  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
781  errmsg("must be superuser to create FOR ALL TABLES publication")));
782 
783  rel = table_open(PublicationRelationId, RowExclusiveLock);
784 
785  /* Check if name is used */
786  puboid = GetSysCacheOid1(PUBLICATIONNAME, Anum_pg_publication_oid,
787  CStringGetDatum(stmt->pubname));
788  if (OidIsValid(puboid))
789  {
790  ereport(ERROR,
792  errmsg("publication \"%s\" already exists",
793  stmt->pubname)));
794  }
795 
796  /* Form a tuple. */
797  memset(values, 0, sizeof(values));
798  memset(nulls, false, sizeof(nulls));
799 
800  values[Anum_pg_publication_pubname - 1] =
802  values[Anum_pg_publication_pubowner - 1] = ObjectIdGetDatum(GetUserId());
803 
805  stmt->options,
806  &publish_given, &pubactions,
807  &publish_via_partition_root_given,
808  &publish_via_partition_root);
809 
810  puboid = GetNewOidWithIndex(rel, PublicationObjectIndexId,
811  Anum_pg_publication_oid);
812  values[Anum_pg_publication_oid - 1] = ObjectIdGetDatum(puboid);
813  values[Anum_pg_publication_puballtables - 1] =
815  values[Anum_pg_publication_pubinsert - 1] =
816  BoolGetDatum(pubactions.pubinsert);
817  values[Anum_pg_publication_pubupdate - 1] =
818  BoolGetDatum(pubactions.pubupdate);
819  values[Anum_pg_publication_pubdelete - 1] =
820  BoolGetDatum(pubactions.pubdelete);
821  values[Anum_pg_publication_pubtruncate - 1] =
822  BoolGetDatum(pubactions.pubtruncate);
823  values[Anum_pg_publication_pubviaroot - 1] =
824  BoolGetDatum(publish_via_partition_root);
825 
826  tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
827 
828  /* Insert tuple into catalog. */
829  CatalogTupleInsert(rel, tup);
830  heap_freetuple(tup);
831 
832  recordDependencyOnOwner(PublicationRelationId, puboid, GetUserId());
833 
834  ObjectAddressSet(myself, PublicationRelationId, puboid);
835 
836  /* Make the changes visible. */
838 
839  /* Associate objects with the publication. */
840  if (stmt->for_all_tables)
841  {
842  /* Invalidate relcache so that publication info is rebuilt. */
844  }
845  else
846  {
847  ObjectsInPublicationToOids(stmt->pubobjects, pstate, &relations,
848  &schemaidlist);
849 
850  /* FOR ALL TABLES IN SCHEMA requires superuser */
851  if (list_length(schemaidlist) > 0 && !superuser())
852  ereport(ERROR,
853  errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
854  errmsg("must be superuser to create FOR ALL TABLES IN SCHEMA publication"));
855 
856  if (list_length(relations) > 0)
857  {
858  List *rels;
859 
860  rels = OpenTableList(relations);
861  CheckObjSchemaNotAlreadyInPublication(rels, schemaidlist,
863 
865  publish_via_partition_root);
866 
868  publish_via_partition_root);
869 
870  PublicationAddTables(puboid, rels, true, NULL);
871  CloseTableList(rels);
872  }
873 
874  if (list_length(schemaidlist) > 0)
875  {
876  /*
877  * Schema lock is held until the publication is created to prevent
878  * concurrent schema deletion.
879  */
880  LockSchemaList(schemaidlist);
881  PublicationAddSchemas(puboid, schemaidlist, true, NULL);
882  }
883  }
884 
886 
887  InvokeObjectPostCreateHook(PublicationRelationId, puboid, 0);
888 
890  {
892  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
893  errmsg("wal_level is insufficient to publish logical changes"),
894  errhint("Set wal_level to logical before creating subscriptions.")));
895  }
896 
897  return myself;
898 }
AclResult
Definition: acl.h:181
@ ACLCHECK_OK
Definition: acl.h:182
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:5033
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define OidIsValid(objectId)
Definition: c.h:721
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:391
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2994
int errhint(const char *fmt,...)
Definition: elog.c:1151
#define WARNING
Definition: elog.h:30
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:631
Oid MyDatabaseId
Definition: globals.c:89
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:221
void CacheInvalidateRelcacheAll(void)
Definition: inval.c:1387
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:48
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:171
@ PUBLICATIONOBJ_TABLE
Definition: parsenodes.h:4009
@ OBJECT_DATABASE
Definition: parsenodes.h:2144
#define ACL_CREATE
Definition: parsenodes.h:91
static int list_length(const List *l)
Definition: pg_list.h:150
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:164
uintptr_t Datum
Definition: postgres.h:411
#define BoolGetDatum(X)
Definition: postgres.h:446
static void CheckPubRelationColumnList(List *tables, const char *queryString, bool pubviaroot)
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)
static void CheckObjSchemaNotAlreadyInPublication(List *rels, List *schemaidlist, PublicationObjSpecType checkobjtype)
static List * OpenTableList(List *tables)
static void LockSchemaList(List *schemalist)
#define RelationGetDescr(relation)
Definition: rel.h:514
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32
bool superuser(void)
Definition: superuser.c:46
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:197
void CommandCounterIncrement(void)
Definition: xact.c:1074
int wal_level
Definition: xlog.c:132
@ WAL_LEVEL_LOGICAL
Definition: xlog.h:71

References ACL_CREATE, aclcheck_error(), ACLCHECK_OK, BoolGetDatum, CacheInvalidateRelcacheAll(), CatalogTupleInsert(), CheckObjSchemaNotAlreadyInPublication(), CheckPubRelationColumnList(), CloseTableList(), CommandCounterIncrement(), CStringGetDatum, DirectFunctionCall1, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errhint(), errmsg(), ERROR, CreatePublicationStmt::for_all_tables, get_database_name(), GetNewOidWithIndex(), GetSysCacheOid1, GetUserId(), heap_form_tuple(), heap_freetuple(), InvokeObjectPostCreateHook, list_length(), LockSchemaList(), MyDatabaseId, namein(), NIL, OBJECT_DATABASE, ObjectAddressSet, ObjectIdGetDatum, ObjectsInPublicationToOids(), OidIsValid, OpenTableList(), CreatePublicationStmt::options, ParseState::p_sourcetext, parse_publication_options(), pg_database_aclcheck(), PublicationActions::pubdelete, PublicationActions::pubinsert, PublicationAddSchemas(), PublicationAddTables(), PUBLICATIONNAME, PUBLICATIONOBJ_TABLE, CreatePublicationStmt::pubname, CreatePublicationStmt::pubobjects, PublicationActions::pubtruncate, PublicationActions::pubupdate, recordDependencyOnOwner(), RelationGetDescr, RowExclusiveLock, 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 1091 of file publicationcmds.c.

1092 {
1093  /*
1094  * We don't want to send too many individual messages, at some point it's
1095  * cheaper to just reset whole relcache.
1096  */
1097  if (list_length(relids) < MAX_RELCACHE_INVAL_MSGS)
1098  {
1099  ListCell *lc;
1100 
1101  foreach(lc, relids)
1103  }
1104  else
1106 }
void CacheInvalidateRelcacheByRelid(Oid relid)
Definition: inval.c:1422
#define lfirst_oid(lc)
Definition: pg_list.h:172
#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_collist_contains_invalid_column()

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

Definition at line 375 of file publicationcmds.c.

377 {
378  HeapTuple tuple;
379  Oid relid = RelationGetRelid(relation);
380  Oid publish_as_relid = RelationGetRelid(relation);
381  bool result = false;
382  Datum datum;
383  bool isnull;
384 
385  /*
386  * For a partition, if pubviaroot is true, find the topmost ancestor that
387  * is published via this publication as we need to use its column list for
388  * the changes.
389  *
390  * Note that even though the column list used is for an ancestor, the
391  * REPLICA IDENTITY used will be for the actual child table.
392  */
393  if (pubviaroot && relation->rd_rel->relispartition)
394  {
395  publish_as_relid = GetTopMostAncestorInPublication(pubid, ancestors, NULL);
396 
397  if (!OidIsValid(publish_as_relid))
398  publish_as_relid = relid;
399  }
400 
402  ObjectIdGetDatum(publish_as_relid),
403  ObjectIdGetDatum(pubid));
404 
405  if (!HeapTupleIsValid(tuple))
406  return false;
407 
408  datum = SysCacheGetAttr(PUBLICATIONRELMAP, tuple,
409  Anum_pg_publication_rel_prattrs,
410  &isnull);
411 
412  if (!isnull)
413  {
414  int x;
415  Bitmapset *idattrs;
416  Bitmapset *columns = NULL;
417 
418  /* With REPLICA IDENTITY FULL, no column list is allowed. */
419  if (relation->rd_rel->relreplident == REPLICA_IDENTITY_FULL)
420  result = true;
421 
422  /* Transform the column list datum to a bitmapset. */
423  columns = pub_collist_to_bitmapset(NULL, datum, NULL);
424 
425  /* Remember columns that are part of the REPLICA IDENTITY */
426  idattrs = RelationGetIndexAttrBitmap(relation,
428 
429  /*
430  * Attnums in the bitmap returned by RelationGetIndexAttrBitmap are
431  * offset (to handle system columns the usual way), while column list
432  * does not use offset, so we can't do bms_is_subset(). Instead, we
433  * have to loop over the idattrs and check all of them are in the
434  * list.
435  */
436  x = -1;
437  while ((x = bms_next_member(idattrs, x)) >= 0)
438  {
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
445  * not match, so translate them to the parent - get the attname
446  * from the 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
455  * are 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  if (!bms_is_member(attnum, columns))
462  {
463  result = true;
464  break;
465  }
466  }
467 
468  bms_free(idattrs);
469  bms_free(columns);
470  }
471 
472  ReleaseSysCache(tuple);
473 
474  return result;
475 }
int16 AttrNumber
Definition: attnum.h:21
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1045
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:427
int x
Definition: isn.c:71
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:856
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition: lsyscache.c:825
int16 attnum
Definition: pg_attribute.h:83
Oid GetTopMostAncestorInPublication(Oid puboid, List *ancestors, int *ancestor_level)
Bitmapset * pub_collist_to_bitmapset(Bitmapset *columns, Datum pubcols, MemoryContext mcxt)
#define RelationGetRelid(relation)
Definition: rel.h:488
Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
Definition: relcache.c:5105
@ INDEX_ATTR_BITMAP_IDENTITY_KEY
Definition: relcache.h:61
Form_pg_class rd_rel
Definition: rel.h:109
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1221
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1434
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1184
@ PUBLICATIONRELMAP
Definition: syscache.h:85

References attnum, bms_free(), bms_is_member(), bms_next_member(), FirstLowInvalidHeapAttributeNumber, get_attname(), get_attnum(), GetTopMostAncestorInPublication(), HeapTupleIsValid, INDEX_ATTR_BITMAP_IDENTITY_KEY, ObjectIdGetDatum, OidIsValid, pub_collist_to_bitmapset(), PUBLICATIONRELMAP, RelationData::rd_rel, RelationGetIndexAttrBitmap(), RelationGetRelid, ReleaseSysCache(), SearchSysCache2(), SysCacheGetAttr(), 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 299 of file publicationcmds.c.

301 {
302  HeapTuple rftuple;
303  Oid relid = RelationGetRelid(relation);
304  Oid publish_as_relid = RelationGetRelid(relation);
305  bool result = false;
306  Datum rfdatum;
307  bool rfisnull;
308 
309  /*
310  * FULL means all columns are in the REPLICA IDENTITY, so all columns are
311  * allowed in the row filter and we can skip the validation.
312  */
313  if (relation->rd_rel->relreplident == REPLICA_IDENTITY_FULL)
314  return false;
315 
316  /*
317  * For a partition, if pubviaroot is true, find the topmost ancestor that
318  * is published via this publication as we need to use its row filter
319  * expression to filter the partition's changes.
320  *
321  * Note that even though the row filter used is for an ancestor, the
322  * REPLICA IDENTITY used will be for the actual child table.
323  */
324  if (pubviaroot && relation->rd_rel->relispartition)
325  {
326  publish_as_relid
327  = GetTopMostAncestorInPublication(pubid, ancestors, NULL);
328 
329  if (!OidIsValid(publish_as_relid))
330  publish_as_relid = relid;
331  }
332 
334  ObjectIdGetDatum(publish_as_relid),
335  ObjectIdGetDatum(pubid));
336 
337  if (!HeapTupleIsValid(rftuple))
338  return false;
339 
340  rfdatum = SysCacheGetAttr(PUBLICATIONRELMAP, rftuple,
341  Anum_pg_publication_rel_prqual,
342  &rfisnull);
343 
344  if (!rfisnull)
345  {
346  rf_context context = {0};
347  Node *rfnode;
348  Bitmapset *bms = NULL;
349 
350  context.pubviaroot = pubviaroot;
351  context.parentid = publish_as_relid;
352  context.relid = relid;
353 
354  /* Remember columns that are part of the REPLICA IDENTITY */
355  bms = RelationGetIndexAttrBitmap(relation,
357 
358  context.bms_replident = bms;
359  rfnode = stringToNode(TextDatumGetCString(rfdatum));
360  result = contain_invalid_rfcolumn_walker(rfnode, &context);
361  }
362 
363  ReleaseSysCache(rftuple);
364 
365  return result;
366 }
#define TextDatumGetCString(d)
Definition: builtins.h:86
static bool contain_invalid_rfcolumn_walker(Node *node, rf_context *context)
void * stringToNode(const char *str)
Definition: read.c:89
Definition: nodes.h:575
Bitmapset * bms_replident

References rf_context::bms_replident, contain_invalid_rfcolumn_walker(), GetTopMostAncestorInPublication(), HeapTupleIsValid, INDEX_ATTR_BITMAP_IDENTITY_KEY, ObjectIdGetDatum, OidIsValid, rf_context::parentid, PUBLICATIONRELMAP, 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 1511 of file publicationcmds.c.

1512 {
1513  Relation rel;
1514  HeapTuple tup;
1515  Form_pg_publication pubform;
1516 
1517  rel = table_open(PublicationRelationId, RowExclusiveLock);
1518 
1520  if (!HeapTupleIsValid(tup))
1521  elog(ERROR, "cache lookup failed for publication %u", pubid);
1522 
1523  pubform = (Form_pg_publication) GETSTRUCT(tup);
1524 
1525  /* Invalidate relcache so that publication info is rebuilt. */
1526  if (pubform->puballtables)
1528 
1529  CatalogTupleDelete(rel, &tup->t_self);
1530 
1531  ReleaseSysCache(tup);
1532 
1534 }
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
ItemPointerData t_self
Definition: htup.h:65
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1173

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

Referenced by doDeletion().

◆ RemovePublicationRelById()

void RemovePublicationRelById ( Oid  proid)

Definition at line 1470 of file publicationcmds.c.

1471 {
1472  Relation rel;
1473  HeapTuple tup;
1474  Form_pg_publication_rel pubrel;
1475  List *relids = NIL;
1476 
1477  rel = table_open(PublicationRelRelationId, RowExclusiveLock);
1478 
1480 
1481  if (!HeapTupleIsValid(tup))
1482  elog(ERROR, "cache lookup failed for publication table %u",
1483  proid);
1484 
1485  pubrel = (Form_pg_publication_rel) GETSTRUCT(tup);
1486 
1487  /*
1488  * Invalidate relcache so that publication info is rebuilt.
1489  *
1490  * For the partitioned tables, we must invalidate all partitions contained
1491  * in the respective partition hierarchies, not just the one explicitly
1492  * mentioned in the publication. This is required because we implicitly
1493  * publish the child tables when the parent table is published.
1494  */
1496  pubrel->prrelid);
1497 
1498  InvalidatePublicationRels(relids);
1499 
1500  CatalogTupleDelete(rel, &tup->t_self);
1501 
1502  ReleaseSysCache(tup);
1503 
1505 }
List * GetPubPartitionOptionRelations(List *result, PublicationPartOpt pub_partopt, Oid relid)
@ PUBLICATION_PART_ALL
FormData_pg_publication_rel * Form_pg_publication_rel
void InvalidatePublicationRels(List *relids)
@ PUBLICATIONREL
Definition: syscache.h:84

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

Referenced by doDeletion().

◆ RemovePublicationSchemaById()

void RemovePublicationSchemaById ( Oid  psoid)

Definition at line 1540 of file publicationcmds.c.

1541 {
1542  Relation rel;
1543  HeapTuple tup;
1544  List *schemaRels = NIL;
1546 
1547  rel = table_open(PublicationNamespaceRelationId, RowExclusiveLock);
1548 
1550 
1551  if (!HeapTupleIsValid(tup))
1552  elog(ERROR, "cache lookup failed for publication schema %u", psoid);
1553 
1554  pubsch = (Form_pg_publication_namespace) GETSTRUCT(tup);
1555 
1556  /*
1557  * Invalidate relcache so that publication info is rebuilt. See
1558  * RemovePublicationRelById for why we need to consider all the
1559  * partitions.
1560  */
1561  schemaRels = GetSchemaPublicationRelations(pubsch->pnnspid,
1563  InvalidatePublicationRels(schemaRels);
1564 
1565  CatalogTupleDelete(rel, &tup->t_self);
1566 
1567  ReleaseSysCache(tup);
1568 
1570 }
List * GetSchemaPublicationRelations(Oid schemaid, PublicationPartOpt pub_partopt)
FormData_pg_publication_namespace * Form_pg_publication_namespace
@ PUBLICATIONNAMESPACE
Definition: syscache.h:81

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

Referenced by doDeletion().