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

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

1947 {
1948  Oid subid;
1949  HeapTuple tup;
1950  Relation rel;
1951  ObjectAddress address;
1952  Form_pg_publication pubform;
1953 
1954  rel = table_open(PublicationRelationId, RowExclusiveLock);
1955 
1956  tup = SearchSysCacheCopy1(PUBLICATIONNAME, CStringGetDatum(name));
1957 
1958  if (!HeapTupleIsValid(tup))
1959  ereport(ERROR,
1960  (errcode(ERRCODE_UNDEFINED_OBJECT),
1961  errmsg("publication \"%s\" does not exist", name)));
1962 
1963  pubform = (Form_pg_publication) GETSTRUCT(tup);
1964  subid = pubform->oid;
1965 
1966  AlterPublicationOwner_internal(rel, tup, newOwnerId);
1967 
1968  ObjectAddressSet(address, PublicationRelationId, subid);
1969 
1970  heap_freetuple(tup);
1971 
1973 
1974  return address;
1975 }
#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 1981 of file publicationcmds.c.

1982 {
1983  HeapTuple tup;
1984  Relation rel;
1985 
1986  rel = table_open(PublicationRelationId, RowExclusiveLock);
1987 
1988  tup = SearchSysCacheCopy1(PUBLICATIONOID, ObjectIdGetDatum(subid));
1989 
1990  if (!HeapTupleIsValid(tup))
1991  ereport(ERROR,
1992  (errcode(ERRCODE_UNDEFINED_OBJECT),
1993  errmsg("publication with OID %u does not exist", subid)));
1994 
1995  AlterPublicationOwner_internal(rel, tup, newOwnerId);
1996 
1997  heap_freetuple(tup);
1998 
2000 }

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

Referenced by shdepReassignOwned().

◆ CreatePublication()

ObjectAddress CreatePublication ( ParseState pstate,
CreatePublicationStmt stmt 
)

Definition at line 728 of file publicationcmds.c.

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

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

1059 {
1060  /*
1061  * We don't want to send too many individual messages, at some point it's
1062  * cheaper to just reset whole relcache.
1063  */
1064  if (list_length(relids) < MAX_RELCACHE_INVAL_MSGS)
1065  {
1066  ListCell *lc;
1067 
1068  foreach(lc, relids)
1070  }
1071  else
1073 }
void CacheInvalidateRelcacheByRelid(Oid relid)
Definition: inval.c:1419
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 334 of file publicationcmds.c.

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

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

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

References contain_invalid_rfcolumn_walker(), context, GetTopMostAncestorInPublication(), HeapTupleIsValid, INDEX_ATTR_BITMAP_IDENTITY_KEY, ObjectIdGetDatum(), OidIsValid, RelationData::rd_rel, RelationGetIndexAttrBitmap(), RelationGetRelid, ReleaseSysCache(), SearchSysCache2(), stringToNode(), SysCacheGetAttr(), and TextDatumGetCString.

Referenced by RelationBuildPublicationDesc().

◆ RemovePublicationById()

void RemovePublicationById ( Oid  pubid)

Definition at line 1482 of file publicationcmds.c.

1483 {
1484  Relation rel;
1485  HeapTuple tup;
1486  Form_pg_publication pubform;
1487 
1488  rel = table_open(PublicationRelationId, RowExclusiveLock);
1489 
1490  tup = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pubid));
1491  if (!HeapTupleIsValid(tup))
1492  elog(ERROR, "cache lookup failed for publication %u", pubid);
1493 
1494  pubform = (Form_pg_publication) GETSTRUCT(tup);
1495 
1496  /* Invalidate relcache so that publication info is rebuilt. */
1497  if (pubform->puballtables)
1499 
1500  CatalogTupleDelete(rel, &tup->t_self);
1501 
1502  ReleaseSysCache(tup);
1503 
1505 }
#define elog(elevel,...)
Definition: elog.h:224
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:218

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

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

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