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 subid, 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 1378 of file publicationcmds.c.

1379 {
1380  Relation rel;
1381  HeapTuple tup;
1382  Form_pg_publication pubform;
1383 
1384  rel = table_open(PublicationRelationId, RowExclusiveLock);
1385 
1387  CStringGetDatum(stmt->pubname));
1388 
1389  if (!HeapTupleIsValid(tup))
1390  ereport(ERROR,
1391  (errcode(ERRCODE_UNDEFINED_OBJECT),
1392  errmsg("publication \"%s\" does not exist",
1393  stmt->pubname)));
1394 
1395  pubform = (Form_pg_publication) GETSTRUCT(tup);
1396 
1397  /* must be owner */
1398  if (!object_ownercheck(PublicationRelationId, pubform->oid, GetUserId()))
1400  stmt->pubname);
1401 
1402  if (stmt->options)
1403  AlterPublicationOptions(pstate, stmt, rel, tup);
1404  else
1405  {
1406  List *relations = NIL;
1407  List *schemaidlist = NIL;
1408  Oid pubid = pubform->oid;
1409 
1410  ObjectsInPublicationToOids(stmt->pubobjects, pstate, &relations,
1411  &schemaidlist);
1412 
1413  CheckAlterPublication(stmt, tup, relations, schemaidlist);
1414 
1415  heap_freetuple(tup);
1416 
1417  /* Lock the publication so nobody else can do anything with it. */
1418  LockDatabaseObject(PublicationRelationId, pubid, 0,
1420 
1421  /*
1422  * It is possible that by the time we acquire the lock on publication,
1423  * concurrent DDL has removed it. We can test this by checking the
1424  * existence of publication. We get the tuple again to avoid the risk
1425  * of any publication option getting changed.
1426  */
1428  if (!HeapTupleIsValid(tup))
1429  ereport(ERROR,
1430  errcode(ERRCODE_UNDEFINED_OBJECT),
1431  errmsg("publication \"%s\" does not exist",
1432  stmt->pubname));
1433 
1434  AlterPublicationTables(stmt, tup, relations, pstate->p_sourcetext,
1435  schemaidlist != NIL);
1436  AlterPublicationSchemas(stmt, tup, schemaidlist);
1437  }
1438 
1439  /* Cleanup. */
1440  heap_freetuple(tup);
1442 }
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2673
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:3976
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
#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:1005
#define AccessExclusiveLock
Definition: lockdefs.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid GetUserId(void)
Definition: miscinit.c:510
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2112
#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:192
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:182
@ PUBLICATIONOID
Definition: syscache.h:83
@ PUBLICATIONNAME
Definition: syscache.h:80
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, PUBLICATIONNAME, PUBLICATIONOID, RowExclusiveLock, SearchSysCacheCopy1, stmt, table_close(), and table_open().

Referenced by ProcessUtilitySlow().

◆ AlterPublicationOwner()

ObjectAddress AlterPublicationOwner ( const char *  name,
Oid  newOwnerId 
)

Definition at line 1953 of file publicationcmds.c.

1954 {
1955  Oid subid;
1956  HeapTuple tup;
1957  Relation rel;
1958  ObjectAddress address;
1959  Form_pg_publication pubform;
1960 
1961  rel = table_open(PublicationRelationId, RowExclusiveLock);
1962 
1964 
1965  if (!HeapTupleIsValid(tup))
1966  ereport(ERROR,
1967  (errcode(ERRCODE_UNDEFINED_OBJECT),
1968  errmsg("publication \"%s\" does not exist", name)));
1969 
1970  pubform = (Form_pg_publication) GETSTRUCT(tup);
1971  subid = pubform->oid;
1972 
1973  AlterPublicationOwner_internal(rel, tup, newOwnerId);
1974 
1975  ObjectAddressSet(address, PublicationRelationId, subid);
1976 
1977  heap_freetuple(tup);
1978 
1980 
1981  return address;
1982 }
const char * name
Definition: encode.c:571
#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  subid,
Oid  newOwnerId 
)

Definition at line 1988 of file publicationcmds.c.

1989 {
1990  HeapTuple tup;
1991  Relation rel;
1992 
1993  rel = table_open(PublicationRelationId, RowExclusiveLock);
1994 
1996 
1997  if (!HeapTupleIsValid(tup))
1998  ereport(ERROR,
1999  (errcode(ERRCODE_UNDEFINED_OBJECT),
2000  errmsg("publication with OID %u does not exist", subid)));
2001 
2002  AlterPublicationOwner_internal(rel, tup, newOwnerId);
2003 
2004  heap_freetuple(tup);
2005 
2007 }

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

736 {
737  Relation rel;
738  ObjectAddress myself;
739  Oid puboid;
740  bool nulls[Natts_pg_publication];
741  Datum values[Natts_pg_publication];
742  HeapTuple tup;
743  bool publish_given;
744  PublicationActions pubactions;
745  bool publish_via_partition_root_given;
746  bool publish_via_partition_root;
747  AclResult aclresult;
748  List *relations = NIL;
749  List *schemaidlist = NIL;
750 
751  /* must have CREATE privilege on database */
752  aclresult = object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(), ACL_CREATE);
753  if (aclresult != ACLCHECK_OK)
754  aclcheck_error(aclresult, OBJECT_DATABASE,
756 
757  /* FOR ALL TABLES requires superuser */
758  if (stmt->for_all_tables && !superuser())
759  ereport(ERROR,
760  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
761  errmsg("must be superuser to create FOR ALL TABLES publication")));
762 
763  rel = table_open(PublicationRelationId, RowExclusiveLock);
764 
765  /* Check if name is used */
766  puboid = GetSysCacheOid1(PUBLICATIONNAME, Anum_pg_publication_oid,
767  CStringGetDatum(stmt->pubname));
768  if (OidIsValid(puboid))
769  ereport(ERROR,
771  errmsg("publication \"%s\" already exists",
772  stmt->pubname)));
773 
774  /* Form a tuple. */
775  memset(values, 0, sizeof(values));
776  memset(nulls, false, sizeof(nulls));
777 
778  values[Anum_pg_publication_pubname - 1] =
780  values[Anum_pg_publication_pubowner - 1] = ObjectIdGetDatum(GetUserId());
781 
783  stmt->options,
784  &publish_given, &pubactions,
785  &publish_via_partition_root_given,
786  &publish_via_partition_root);
787 
788  puboid = GetNewOidWithIndex(rel, PublicationObjectIndexId,
789  Anum_pg_publication_oid);
790  values[Anum_pg_publication_oid - 1] = ObjectIdGetDatum(puboid);
791  values[Anum_pg_publication_puballtables - 1] =
792  BoolGetDatum(stmt->for_all_tables);
793  values[Anum_pg_publication_pubinsert - 1] =
794  BoolGetDatum(pubactions.pubinsert);
795  values[Anum_pg_publication_pubupdate - 1] =
796  BoolGetDatum(pubactions.pubupdate);
797  values[Anum_pg_publication_pubdelete - 1] =
798  BoolGetDatum(pubactions.pubdelete);
799  values[Anum_pg_publication_pubtruncate - 1] =
800  BoolGetDatum(pubactions.pubtruncate);
801  values[Anum_pg_publication_pubviaroot - 1] =
802  BoolGetDatum(publish_via_partition_root);
803 
804  tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
805 
806  /* Insert tuple into catalog. */
807  CatalogTupleInsert(rel, tup);
808  heap_freetuple(tup);
809 
810  recordDependencyOnOwner(PublicationRelationId, puboid, GetUserId());
811 
812  ObjectAddressSet(myself, PublicationRelationId, puboid);
813 
814  /* Make the changes visible. */
816 
817  /* Associate objects with the publication. */
818  if (stmt->for_all_tables)
819  {
820  /* Invalidate relcache so that publication info is rebuilt. */
822  }
823  else
824  {
825  ObjectsInPublicationToOids(stmt->pubobjects, pstate, &relations,
826  &schemaidlist);
827 
828  /* FOR TABLES IN SCHEMA requires superuser */
829  if (schemaidlist != NIL && !superuser())
830  ereport(ERROR,
831  errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
832  errmsg("must be superuser to create FOR TABLES IN SCHEMA publication"));
833 
834  if (relations != NIL)
835  {
836  List *rels;
837 
838  rels = OpenTableList(relations);
840  publish_via_partition_root);
841 
842  CheckPubRelationColumnList(stmt->pubname, rels,
843  schemaidlist != NIL,
844  publish_via_partition_root);
845 
846  PublicationAddTables(puboid, rels, true, NULL);
847  CloseTableList(rels);
848  }
849 
850  if (schemaidlist != NIL)
851  {
852  /*
853  * Schema lock is held until the publication is created to prevent
854  * concurrent schema deletion.
855  */
856  LockSchemaList(schemaidlist);
857  PublicationAddSchemas(puboid, schemaidlist, true, NULL);
858  }
859  }
860 
862 
863  InvokeObjectPostCreateHook(PublicationRelationId, puboid, 0);
864 
867  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
868  errmsg("wal_level is insufficient to publish logical changes"),
869  errhint("Set wal_level to \"logical\" before creating subscriptions.")));
870 
871  return myself;
872 }
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:3775
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define OidIsValid(objectId)
Definition: c.h:759
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:393
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3043
int errhint(const char *fmt,...)
Definition: elog.c:1316
#define WARNING
Definition: elog.h:36
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:642
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:233
void CacheInvalidateRelcacheAll(void)
Definition: inval.c:1387
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:48
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:173
@ OBJECT_DATABASE
Definition: parsenodes.h:2091
#define ACL_CREATE
Definition: parsenodes.h:92
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:165
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)
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:530
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32
bool superuser(void)
Definition: superuser.c:46
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:200
void CommandCounterIncrement(void)
Definition: xact.c:1078
int wal_level
Definition: xlog.c:134
@ WAL_LEVEL_LOGICAL
Definition: xlog.h:71

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(), PUBLICATIONNAME, 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 1065 of file publicationcmds.c.

1066 {
1067  /*
1068  * We don't want to send too many individual messages, at some point it's
1069  * cheaper to just reset whole relcache.
1070  */
1071  if (list_length(relids) < MAX_RELCACHE_INVAL_MSGS)
1072  {
1073  ListCell *lc;
1074 
1075  foreach(lc, relids)
1077  }
1078  else
1080 }
void CacheInvalidateRelcacheByRelid(Oid relid)
Definition: inval.c:1422
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_collist_contains_invalid_column()

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

Definition at line 341 of file publicationcmds.c.

343 {
344  HeapTuple tuple;
345  Oid relid = RelationGetRelid(relation);
346  Oid publish_as_relid = RelationGetRelid(relation);
347  bool result = false;
348  Datum datum;
349  bool isnull;
350 
351  /*
352  * For a partition, if pubviaroot is true, find the topmost ancestor that
353  * is published via this publication as we need to use its column list for
354  * the changes.
355  *
356  * Note that even though the column list used is for an ancestor, the
357  * REPLICA IDENTITY used will be for the actual child table.
358  */
359  if (pubviaroot && relation->rd_rel->relispartition)
360  {
361  publish_as_relid = GetTopMostAncestorInPublication(pubid, ancestors, NULL);
362 
363  if (!OidIsValid(publish_as_relid))
364  publish_as_relid = relid;
365  }
366 
368  ObjectIdGetDatum(publish_as_relid),
369  ObjectIdGetDatum(pubid));
370 
371  if (!HeapTupleIsValid(tuple))
372  return false;
373 
374  datum = SysCacheGetAttr(PUBLICATIONRELMAP, tuple,
375  Anum_pg_publication_rel_prattrs,
376  &isnull);
377 
378  if (!isnull)
379  {
380  int x;
381  Bitmapset *idattrs;
382  Bitmapset *columns = NULL;
383 
384  /* With REPLICA IDENTITY FULL, no column list is allowed. */
385  if (relation->rd_rel->relreplident == REPLICA_IDENTITY_FULL)
386  result = true;
387 
388  /* Transform the column list datum to a bitmapset. */
389  columns = pub_collist_to_bitmapset(NULL, datum, NULL);
390 
391  /* Remember columns that are part of the REPLICA IDENTITY */
392  idattrs = RelationGetIndexAttrBitmap(relation,
394 
395  /*
396  * Attnums in the bitmap returned by RelationGetIndexAttrBitmap are
397  * offset (to handle system columns the usual way), while column list
398  * does not use offset, so we can't do bms_is_subset(). Instead, we
399  * have to loop over the idattrs and check all of them are in the
400  * list.
401  */
402  x = -1;
403  while ((x = bms_next_member(idattrs, x)) >= 0)
404  {
406 
407  /*
408  * If pubviaroot is true, we are validating the column list of the
409  * parent table, but the bitmap contains the replica identity
410  * information of the child table. The parent/child attnums may
411  * not match, so translate them to the parent - get the attname
412  * from the child, and look it up in the parent.
413  */
414  if (pubviaroot)
415  {
416  /* attribute name in the child table */
417  char *colname = get_attname(relid, attnum, false);
418 
419  /*
420  * Determine the attnum for the attribute name in parent (we
421  * are using the column list defined on the parent).
422  */
423  attnum = get_attnum(publish_as_relid, colname);
424  }
425 
426  /* replica identity column, not covered by the column list */
427  if (!bms_is_member(attnum, columns))
428  {
429  result = true;
430  break;
431  }
432  }
433 
434  bms_free(idattrs);
435  bms_free(columns);
436  }
437 
438  ReleaseSysCache(tuple);
439 
440  return result;
441 }
int16 AttrNumber
Definition: attnum.h:21
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1039
void bms_free(Bitmapset *a)
Definition: bitmapset.c:209
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:444
int x
Definition: isn.c:71
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:857
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition: lsyscache.c:826
int16 attnum
Definition: pg_attribute.h:74
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:504
Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
Definition: relcache.c:5169
@ INDEX_ATTR_BITMAP_IDENTITY_KEY
Definition: relcache.h:61
Form_pg_class rd_rel
Definition: rel.h:111
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:866
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1079
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:829
@ 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 265 of file publicationcmds.c.

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

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

1490 {
1491  Relation rel;
1492  HeapTuple tup;
1493  Form_pg_publication pubform;
1494 
1495  rel = table_open(PublicationRelationId, RowExclusiveLock);
1496 
1498  if (!HeapTupleIsValid(tup))
1499  elog(ERROR, "cache lookup failed for publication %u", pubid);
1500 
1501  pubform = (Form_pg_publication) GETSTRUCT(tup);
1502 
1503  /* Invalidate relcache so that publication info is rebuilt. */
1504  if (pubform->puballtables)
1506 
1507  CatalogTupleDelete(rel, &tup->t_self);
1508 
1509  ReleaseSysCache(tup);
1510 
1512 }
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:818

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

1449 {
1450  Relation rel;
1451  HeapTuple tup;
1452  Form_pg_publication_rel pubrel;
1453  List *relids = NIL;
1454 
1455  rel = table_open(PublicationRelRelationId, RowExclusiveLock);
1456 
1458 
1459  if (!HeapTupleIsValid(tup))
1460  elog(ERROR, "cache lookup failed for publication table %u",
1461  proid);
1462 
1463  pubrel = (Form_pg_publication_rel) GETSTRUCT(tup);
1464 
1465  /*
1466  * Invalidate relcache so that publication info is rebuilt.
1467  *
1468  * For the partitioned tables, we must invalidate all partitions contained
1469  * in the respective partition hierarchies, not just the one explicitly
1470  * mentioned in the publication. This is required because we implicitly
1471  * publish the child tables when the parent table is published.
1472  */
1474  pubrel->prrelid);
1475 
1476  InvalidatePublicationRels(relids);
1477 
1478  CatalogTupleDelete(rel, &tup->t_self);
1479 
1480  ReleaseSysCache(tup);
1481 
1483 }
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 1518 of file publicationcmds.c.

1519 {
1520  Relation rel;
1521  HeapTuple tup;
1522  List *schemaRels = NIL;
1524 
1525  rel = table_open(PublicationNamespaceRelationId, RowExclusiveLock);
1526 
1528 
1529  if (!HeapTupleIsValid(tup))
1530  elog(ERROR, "cache lookup failed for publication schema %u", psoid);
1531 
1532  pubsch = (Form_pg_publication_namespace) GETSTRUCT(tup);
1533 
1534  /*
1535  * Invalidate relcache so that publication info is rebuilt. See
1536  * RemovePublicationRelById for why we need to consider all the
1537  * partitions.
1538  */
1539  schemaRels = GetSchemaPublicationRelations(pubsch->pnnspid,
1541  InvalidatePublicationRels(schemaRels);
1542 
1543  CatalogTupleDelete(rel, &tup->t_self);
1544 
1545  ReleaseSysCache(tup);
1546 
1548 }
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().