PostgreSQL Source Code  git master
pg_publication.h File Reference
#include "catalog/genbki.h"
#include "catalog/objectaddress.h"
#include "catalog/pg_publication_d.h"
Include dependency graph for pg_publication.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PublicationActions
 
struct  PublicationDesc
 
struct  Publication
 
struct  PublicationRelInfo
 

Typedefs

typedef FormData_pg_publicationForm_pg_publication
 
typedef struct PublicationActions PublicationActions
 
typedef struct PublicationDesc PublicationDesc
 
typedef struct Publication Publication
 
typedef struct PublicationRelInfo PublicationRelInfo
 
typedef enum PublicationPartOpt PublicationPartOpt
 

Enumerations

enum  PublicationPartOpt { PUBLICATION_PART_ROOT , PUBLICATION_PART_LEAF , PUBLICATION_PART_ALL }
 

Functions

 CATALOG (pg_publication, 6104, PublicationRelationId)
 
 DECLARE_UNIQUE_INDEX_PKEY (pg_publication_oid_index, 6110, PublicationObjectIndexId, pg_publication, btree(oid oid_ops))
 
 DECLARE_UNIQUE_INDEX (pg_publication_pubname_index, 6111, PublicationNameIndexId, pg_publication, btree(pubname name_ops))
 
 MAKE_SYSCACHE (PUBLICATIONOID, pg_publication_oid_index, 8)
 
 MAKE_SYSCACHE (PUBLICATIONNAME, pg_publication_pubname_index, 8)
 
PublicationGetPublication (Oid pubid)
 
PublicationGetPublicationByName (const char *pubname, bool missing_ok)
 
ListGetRelationPublications (Oid relid)
 
ListGetPublicationRelations (Oid pubid, PublicationPartOpt pub_partopt)
 
ListGetAllTablesPublications (void)
 
ListGetAllTablesPublicationRelations (bool pubviaroot)
 
ListGetPublicationSchemas (Oid pubid)
 
ListGetSchemaPublications (Oid schemaid)
 
ListGetSchemaPublicationRelations (Oid schemaid, PublicationPartOpt pub_partopt)
 
ListGetAllSchemaPublicationRelations (Oid pubid, PublicationPartOpt pub_partopt)
 
ListGetPubPartitionOptionRelations (List *result, PublicationPartOpt pub_partopt, Oid relid)
 
Oid GetTopMostAncestorInPublication (Oid puboid, List *ancestors, int *ancestor_level)
 
bool is_publishable_relation (Relation rel)
 
bool is_schema_publication (Oid pubid)
 
ObjectAddress publication_add_relation (Oid pubid, PublicationRelInfo *pri, bool if_not_exists)
 
ObjectAddress publication_add_schema (Oid pubid, Oid schemaid, bool if_not_exists)
 
Bitmapsetpub_collist_to_bitmapset (Bitmapset *columns, Datum pubcols, MemoryContext mcxt)
 

Variables

 FormData_pg_publication
 

Typedef Documentation

◆ Form_pg_publication

Definition at line 64 of file pg_publication.h.

◆ Publication

typedef struct Publication Publication

◆ PublicationActions

◆ PublicationDesc

◆ PublicationPartOpt

◆ PublicationRelInfo

Enumeration Type Documentation

◆ PublicationPartOpt

Enumerator
PUBLICATION_PART_ROOT 
PUBLICATION_PART_LEAF 
PUBLICATION_PART_ALL 

Definition at line 129 of file pg_publication.h.

130 {
PublicationPartOpt
@ PUBLICATION_PART_LEAF
@ PUBLICATION_PART_ROOT
@ PUBLICATION_PART_ALL

Function Documentation

◆ CATALOG()

CATALOG ( pg_publication  ,
6104  ,
PublicationRelationId   
)

Definition at line 29 of file pg_publication.h.

30 {
31  Oid oid; /* oid */
32 
33  NameData pubname; /* name of the publication */
34 
35  Oid pubowner BKI_LOOKUP(pg_authid); /* publication owner */
36 
37  /*
38  * indicates that this is special publication which should encompass all
39  * tables in the database (except for the unlogged and temp ones)
40  */
41  bool puballtables;
42 
43  /* true if inserts are published */
44  bool pubinsert;
45 
46  /* true if updates are published */
47  bool pubupdate;
48 
49  /* true if deletes are published */
50  bool pubdelete;
51 
52  /* true if truncates are published */
53  bool pubtruncate;
54 
55  /* true if partition changes are published using root schema */
56  bool pubviaroot;
#define BKI_LOOKUP(catalog)
Definition: genbki.h:46
FormData_pg_publication
unsigned int Oid
Definition: postgres_ext.h:31
Definition: c.h:730

References BKI_LOOKUP.

◆ DECLARE_UNIQUE_INDEX()

DECLARE_UNIQUE_INDEX ( pg_publication_pubname_index  ,
6111  ,
PublicationNameIndexId  ,
pg_publication  ,
btree(pubname name_ops)   
)

◆ DECLARE_UNIQUE_INDEX_PKEY()

DECLARE_UNIQUE_INDEX_PKEY ( pg_publication_oid_index  ,
6110  ,
PublicationObjectIndexId  ,
pg_publication  ,
btree(oid oid_ops)   
)

◆ GetAllSchemaPublicationRelations()

List* GetAllSchemaPublicationRelations ( Oid  pubid,
PublicationPartOpt  pub_partopt 
)

Definition at line 987 of file pg_publication.c.

988 {
989  List *result = NIL;
990  List *pubschemalist = GetPublicationSchemas(pubid);
991  ListCell *cell;
992 
993  foreach(cell, pubschemalist)
994  {
995  Oid schemaid = lfirst_oid(cell);
996  List *schemaRels = NIL;
997 
998  schemaRels = GetSchemaPublicationRelations(schemaid, pub_partopt);
999  result = list_concat(result, schemaRels);
1000  }
1001 
1002  return result;
1003 }
List * list_concat(List *list1, const List *list2)
Definition: list.c:561
#define NIL
Definition: pg_list.h:68
#define lfirst_oid(lc)
Definition: pg_list.h:174
List * GetPublicationSchemas(Oid pubid)
List * GetSchemaPublicationRelations(Oid schemaid, PublicationPartOpt pub_partopt)
Definition: pg_list.h:54

References GetPublicationSchemas(), GetSchemaPublicationRelations(), lfirst_oid, list_concat(), and NIL.

Referenced by AlterPublicationOptions(), and pg_get_publication_tables().

◆ GetAllTablesPublicationRelations()

List* GetAllTablesPublicationRelations ( bool  pubviaroot)

Definition at line 805 of file pg_publication.c.

806 {
807  Relation classRel;
808  ScanKeyData key[1];
809  TableScanDesc scan;
810  HeapTuple tuple;
811  List *result = NIL;
812 
813  classRel = table_open(RelationRelationId, AccessShareLock);
814 
815  ScanKeyInit(&key[0],
816  Anum_pg_class_relkind,
817  BTEqualStrategyNumber, F_CHAREQ,
818  CharGetDatum(RELKIND_RELATION));
819 
820  scan = table_beginscan_catalog(classRel, 1, key);
821 
822  while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
823  {
824  Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple);
825  Oid relid = relForm->oid;
826 
827  if (is_publishable_class(relid, relForm) &&
828  !(relForm->relispartition && pubviaroot))
829  result = lappend_oid(result, relid);
830  }
831 
832  table_endscan(scan);
833 
834  if (pubviaroot)
835  {
836  ScanKeyInit(&key[0],
837  Anum_pg_class_relkind,
838  BTEqualStrategyNumber, F_CHAREQ,
839  CharGetDatum(RELKIND_PARTITIONED_TABLE));
840 
841  scan = table_beginscan_catalog(classRel, 1, key);
842 
843  while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
844  {
845  Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple);
846  Oid relid = relForm->oid;
847 
848  if (is_publishable_class(relid, relForm) &&
849  !relForm->relispartition)
850  result = lappend_oid(result, relid);
851  }
852 
853  table_endscan(scan);
854  }
855 
856  table_close(classRel, AccessShareLock);
857  return result;
858 }
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
Definition: heapam.c:1086
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
#define AccessShareLock
Definition: lockdefs.h:36
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
static bool is_publishable_class(Oid relid, Form_pg_class reltuple)
static Datum CharGetDatum(char X)
Definition: postgres.h:122
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
@ ForwardScanDirection
Definition: sdir.h:28
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, struct ScanKeyData *key)
Definition: tableam.c:112
static void table_endscan(TableScanDesc scan)
Definition: tableam.h:1009

References AccessShareLock, BTEqualStrategyNumber, CharGetDatum(), ForwardScanDirection, GETSTRUCT, heap_getnext(), is_publishable_class(), sort-test::key, lappend_oid(), NIL, ScanKeyInit(), table_beginscan_catalog(), table_close(), table_endscan(), and table_open().

Referenced by pg_get_publication_tables().

◆ GetAllTablesPublications()

List* GetAllTablesPublications ( void  )

Definition at line 764 of file pg_publication.c.

765 {
766  List *result;
767  Relation rel;
768  ScanKeyData scankey;
769  SysScanDesc scan;
770  HeapTuple tup;
771 
772  /* Find all publications that are marked as for all tables. */
773  rel = table_open(PublicationRelationId, AccessShareLock);
774 
775  ScanKeyInit(&scankey,
776  Anum_pg_publication_puballtables,
777  BTEqualStrategyNumber, F_BOOLEQ,
778  BoolGetDatum(true));
779 
780  scan = systable_beginscan(rel, InvalidOid, false,
781  NULL, 1, &scankey);
782 
783  result = NIL;
784  while (HeapTupleIsValid(tup = systable_getnext(scan)))
785  {
786  Oid oid = ((Form_pg_publication) GETSTRUCT(tup))->oid;
787 
788  result = lappend_oid(result, oid);
789  }
790 
791  systable_endscan(scan);
793 
794  return result;
795 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:599
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:506
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_publication * Form_pg_publication
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
#define InvalidOid
Definition: postgres_ext.h:36

References AccessShareLock, BoolGetDatum(), BTEqualStrategyNumber, GETSTRUCT, HeapTupleIsValid, InvalidOid, lappend_oid(), NIL, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by RelationBuildPublicationDesc().

◆ GetPublication()

Publication* GetPublication ( Oid  pubid)

Definition at line 1011 of file pg_publication.c.

1012 {
1013  HeapTuple tup;
1014  Publication *pub;
1015  Form_pg_publication pubform;
1016 
1017  tup = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pubid));
1018  if (!HeapTupleIsValid(tup))
1019  elog(ERROR, "cache lookup failed for publication %u", pubid);
1020 
1021  pubform = (Form_pg_publication) GETSTRUCT(tup);
1022 
1023  pub = (Publication *) palloc(sizeof(Publication));
1024  pub->oid = pubid;
1025  pub->name = pstrdup(NameStr(pubform->pubname));
1026  pub->alltables = pubform->puballtables;
1027  pub->pubactions.pubinsert = pubform->pubinsert;
1028  pub->pubactions.pubupdate = pubform->pubupdate;
1029  pub->pubactions.pubdelete = pubform->pubdelete;
1030  pub->pubactions.pubtruncate = pubform->pubtruncate;
1031  pub->pubviaroot = pubform->pubviaroot;
1032 
1033  ReleaseSysCache(tup);
1034 
1035  return pub;
1036 }
#define NameStr(name)
Definition: c.h:735
#define ERROR
Definition: elog.h:39
char * pstrdup(const char *in)
Definition: mcxt.c:1619
void * palloc(Size size)
Definition: mcxt.c:1201
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
PublicationActions pubactions
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:267
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:219

References Publication::alltables, elog(), ERROR, GETSTRUCT, HeapTupleIsValid, Publication::name, NameStr, ObjectIdGetDatum(), Publication::oid, palloc(), pstrdup(), Publication::pubactions, PublicationActions::pubdelete, PublicationActions::pubinsert, PublicationActions::pubtruncate, PublicationActions::pubupdate, Publication::pubviaroot, ReleaseSysCache(), and SearchSysCache1().

Referenced by GetPublicationByName(), pg_get_publication_tables(), publication_add_relation(), and publication_add_schema().

◆ GetPublicationByName()

Publication* GetPublicationByName ( const char *  pubname,
bool  missing_ok 
)

Definition at line 1042 of file pg_publication.c.

1043 {
1044  Oid oid;
1045 
1046  oid = get_publication_oid(pubname, missing_ok);
1047 
1048  return OidIsValid(oid) ? GetPublication(oid) : NULL;
1049 }
#define OidIsValid(objectId)
Definition: c.h:764
Oid get_publication_oid(const char *pubname, bool missing_ok)
Definition: lsyscache.c:3580
Publication * GetPublication(Oid pubid)

References get_publication_oid(), GetPublication(), and OidIsValid.

Referenced by get_object_address_publication_rel(), get_object_address_publication_schema(), LoadPublications(), and pg_get_publication_tables().

◆ GetPublicationRelations()

List* GetPublicationRelations ( Oid  pubid,
PublicationPartOpt  pub_partopt 
)

Definition at line 721 of file pg_publication.c.

722 {
723  List *result;
724  Relation pubrelsrel;
725  ScanKeyData scankey;
726  SysScanDesc scan;
727  HeapTuple tup;
728 
729  /* Find all publications associated with the relation. */
730  pubrelsrel = table_open(PublicationRelRelationId, AccessShareLock);
731 
732  ScanKeyInit(&scankey,
733  Anum_pg_publication_rel_prpubid,
734  BTEqualStrategyNumber, F_OIDEQ,
735  ObjectIdGetDatum(pubid));
736 
737  scan = systable_beginscan(pubrelsrel, PublicationRelPrpubidIndexId,
738  true, NULL, 1, &scankey);
739 
740  result = NIL;
741  while (HeapTupleIsValid(tup = systable_getnext(scan)))
742  {
744 
745  pubrel = (Form_pg_publication_rel) GETSTRUCT(tup);
746  result = GetPubPartitionOptionRelations(result, pub_partopt,
747  pubrel->prrelid);
748  }
749 
750  systable_endscan(scan);
751  table_close(pubrelsrel, AccessShareLock);
752 
753  /* Now sort and de-duplicate the result list */
754  list_sort(result, list_oid_cmp);
755  list_deduplicate_oid(result);
756 
757  return result;
758 }
void list_sort(List *list, list_sort_comparator cmp)
Definition: list.c:1674
void list_deduplicate_oid(List *list)
Definition: list.c:1495
int list_oid_cmp(const ListCell *p1, const ListCell *p2)
Definition: list.c:1703
List * GetPubPartitionOptionRelations(List *result, PublicationPartOpt pub_partopt, Oid relid)
FormData_pg_publication_rel * Form_pg_publication_rel

References AccessShareLock, BTEqualStrategyNumber, GetPubPartitionOptionRelations(), GETSTRUCT, HeapTupleIsValid, list_deduplicate_oid(), list_oid_cmp(), list_sort(), NIL, ObjectIdGetDatum(), ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by AlterPublicationOptions(), AlterPublicationSchemas(), AlterPublicationTables(), and pg_get_publication_tables().

◆ GetPublicationSchemas()

List* GetPublicationSchemas ( Oid  pubid)

Definition at line 866 of file pg_publication.c.

867 {
868  List *result = NIL;
869  Relation pubschsrel;
870  ScanKeyData scankey;
871  SysScanDesc scan;
872  HeapTuple tup;
873 
874  /* Find all schemas associated with the publication */
875  pubschsrel = table_open(PublicationNamespaceRelationId, AccessShareLock);
876 
877  ScanKeyInit(&scankey,
878  Anum_pg_publication_namespace_pnpubid,
879  BTEqualStrategyNumber, F_OIDEQ,
880  ObjectIdGetDatum(pubid));
881 
882  scan = systable_beginscan(pubschsrel,
883  PublicationNamespacePnnspidPnpubidIndexId,
884  true, NULL, 1, &scankey);
885  while (HeapTupleIsValid(tup = systable_getnext(scan)))
886  {
888 
890 
891  result = lappend_oid(result, pubsch->pnnspid);
892  }
893 
894  systable_endscan(scan);
895  table_close(pubschsrel, AccessShareLock);
896 
897  return result;
898 }
FormData_pg_publication_namespace * Form_pg_publication_namespace

References AccessShareLock, BTEqualStrategyNumber, GETSTRUCT, HeapTupleIsValid, lappend_oid(), NIL, ObjectIdGetDatum(), ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by AlterPublicationSchemas(), and GetAllSchemaPublicationRelations().

◆ GetPubPartitionOptionRelations()

List* GetPubPartitionOptionRelations ( List result,
PublicationPartOpt  pub_partopt,
Oid  relid 
)

Definition at line 272 of file pg_publication.c.

274 {
275  if (get_rel_relkind(relid) == RELKIND_PARTITIONED_TABLE &&
276  pub_partopt != PUBLICATION_PART_ROOT)
277  {
278  List *all_parts = find_all_inheritors(relid, NoLock,
279  NULL);
280 
281  if (pub_partopt == PUBLICATION_PART_ALL)
282  result = list_concat(result, all_parts);
283  else if (pub_partopt == PUBLICATION_PART_LEAF)
284  {
285  ListCell *lc;
286 
287  foreach(lc, all_parts)
288  {
289  Oid partOid = lfirst_oid(lc);
290 
291  if (get_rel_relkind(partOid) != RELKIND_PARTITIONED_TABLE)
292  result = lappend_oid(result, partOid);
293  }
294  }
295  else
296  Assert(false);
297  }
298  else
299  result = lappend_oid(result, relid);
300 
301  return result;
302 }
Assert(fmt[strlen(fmt) - 1] !='\n')
#define NoLock
Definition: lockdefs.h:34
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1980
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
Definition: pg_inherits.c:256

References Assert(), find_all_inheritors(), get_rel_relkind(), lappend_oid(), lfirst_oid, list_concat(), NoLock, PUBLICATION_PART_ALL, PUBLICATION_PART_LEAF, and PUBLICATION_PART_ROOT.

Referenced by AlterPublicationOptions(), GetPublicationRelations(), GetSchemaPublicationRelations(), publication_add_relation(), and RemovePublicationRelById().

◆ GetRelationPublications()

List* GetRelationPublications ( Oid  relid)

Definition at line 692 of file pg_publication.c.

693 {
694  List *result = NIL;
695  CatCList *pubrellist;
696  int i;
697 
698  /* Find all publications associated with the relation. */
699  pubrellist = SearchSysCacheList1(PUBLICATIONRELMAP,
700  ObjectIdGetDatum(relid));
701  for (i = 0; i < pubrellist->n_members; i++)
702  {
703  HeapTuple tup = &pubrellist->members[i]->tuple;
704  Oid pubid = ((Form_pg_publication_rel) GETSTRUCT(tup))->prpubid;
705 
706  result = lappend_oid(result, pubid);
707  }
708 
709  ReleaseSysCacheList(pubrellist);
710 
711  return result;
712 }
int i
Definition: isn.c:73
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
int n_members
Definition: catcache.h:176
HeapTupleData tuple
Definition: catcache.h:121
#define ReleaseSysCacheList(x)
Definition: syscache.h:129
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:122

References GETSTRUCT, i, lappend_oid(), catclist::members, catclist::n_members, NIL, ObjectIdGetDatum(), ReleaseSysCacheList, SearchSysCacheList1, and catctup::tuple.

Referenced by ATPrepChangePersistence(), get_rel_sync_entry(), GetTopMostAncestorInPublication(), and RelationBuildPublicationDesc().

◆ GetSchemaPublicationRelations()

List* GetSchemaPublicationRelations ( Oid  schemaid,
PublicationPartOpt  pub_partopt 
)

Definition at line 930 of file pg_publication.c.

931 {
932  Relation classRel;
933  ScanKeyData key[1];
934  TableScanDesc scan;
935  HeapTuple tuple;
936  List *result = NIL;
937 
938  Assert(OidIsValid(schemaid));
939 
940  classRel = table_open(RelationRelationId, AccessShareLock);
941 
942  ScanKeyInit(&key[0],
943  Anum_pg_class_relnamespace,
944  BTEqualStrategyNumber, F_OIDEQ,
945  schemaid);
946 
947  /* get all the relations present in the specified schema */
948  scan = table_beginscan_catalog(classRel, 1, key);
949  while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
950  {
951  Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple);
952  Oid relid = relForm->oid;
953  char relkind;
954 
955  if (!is_publishable_class(relid, relForm))
956  continue;
957 
958  relkind = get_rel_relkind(relid);
959  if (relkind == RELKIND_RELATION)
960  result = lappend_oid(result, relid);
961  else if (relkind == RELKIND_PARTITIONED_TABLE)
962  {
963  List *partitionrels = NIL;
964 
965  /*
966  * It is quite possible that some of the partitions are in a
967  * different schema than the parent table, so we need to get such
968  * partitions separately.
969  */
970  partitionrels = GetPubPartitionOptionRelations(partitionrels,
971  pub_partopt,
972  relForm->oid);
973  result = list_concat_unique_oid(result, partitionrels);
974  }
975  }
976 
977  table_endscan(scan);
978  table_close(classRel, AccessShareLock);
979  return result;
980 }
List * list_concat_unique_oid(List *list1, const List *list2)
Definition: list.c:1469

References AccessShareLock, Assert(), BTEqualStrategyNumber, ForwardScanDirection, get_rel_relkind(), GetPubPartitionOptionRelations(), GETSTRUCT, heap_getnext(), is_publishable_class(), sort-test::key, lappend_oid(), list_concat_unique_oid(), NIL, OidIsValid, ScanKeyInit(), table_beginscan_catalog(), table_close(), table_endscan(), and table_open().

Referenced by GetAllSchemaPublicationRelations(), publication_add_schema(), and RemovePublicationSchemaById().

◆ GetSchemaPublications()

List* GetSchemaPublications ( Oid  schemaid)

Definition at line 904 of file pg_publication.c.

905 {
906  List *result = NIL;
907  CatCList *pubschlist;
908  int i;
909 
910  /* Find all publications associated with the schema */
911  pubschlist = SearchSysCacheList1(PUBLICATIONNAMESPACEMAP,
912  ObjectIdGetDatum(schemaid));
913  for (i = 0; i < pubschlist->n_members; i++)
914  {
915  HeapTuple tup = &pubschlist->members[i]->tuple;
916  Oid pubid = ((Form_pg_publication_namespace) GETSTRUCT(tup))->pnpubid;
917 
918  result = lappend_oid(result, pubid);
919  }
920 
921  ReleaseSysCacheList(pubschlist);
922 
923  return result;
924 }

References GETSTRUCT, i, lappend_oid(), catclist::members, catclist::n_members, NIL, ObjectIdGetDatum(), ReleaseSysCacheList, SearchSysCacheList1, and catctup::tuple.

Referenced by get_rel_sync_entry(), GetTopMostAncestorInPublication(), and RelationBuildPublicationDesc().

◆ GetTopMostAncestorInPublication()

Oid GetTopMostAncestorInPublication ( Oid  puboid,
List ancestors,
int *  ancestor_level 
)

Definition at line 316 of file pg_publication.c.

317 {
318  ListCell *lc;
319  Oid topmost_relid = InvalidOid;
320  int level = 0;
321 
322  /*
323  * Find the "topmost" ancestor that is in this publication.
324  */
325  foreach(lc, ancestors)
326  {
327  Oid ancestor = lfirst_oid(lc);
328  List *apubids = GetRelationPublications(ancestor);
329  List *aschemaPubids = NIL;
330 
331  level++;
332 
333  if (list_member_oid(apubids, puboid))
334  {
335  topmost_relid = ancestor;
336 
337  if (ancestor_level)
338  *ancestor_level = level;
339  }
340  else
341  {
342  aschemaPubids = GetSchemaPublications(get_rel_namespace(ancestor));
343  if (list_member_oid(aschemaPubids, puboid))
344  {
345  topmost_relid = ancestor;
346 
347  if (ancestor_level)
348  *ancestor_level = level;
349  }
350  }
351 
352  list_free(apubids);
353  list_free(aschemaPubids);
354  }
355 
356  return topmost_relid;
357 }
void list_free(List *list)
Definition: list.c:1546
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:722
Oid get_rel_namespace(Oid relid)
Definition: lsyscache.c:1929
List * GetSchemaPublications(Oid schemaid)
List * GetRelationPublications(Oid relid)

References get_rel_namespace(), GetRelationPublications(), GetSchemaPublications(), InvalidOid, lfirst_oid, list_free(), list_member_oid(), and NIL.

Referenced by get_rel_sync_entry(), pub_collist_contains_invalid_column(), and pub_rf_contains_invalid_column().

◆ is_publishable_relation()

bool is_publishable_relation ( Relation  rel)

Definition at line 155 of file pg_publication.c.

156 {
157  return is_publishable_class(RelationGetRelid(rel), rel->rd_rel);
158 }
#define RelationGetRelid(relation)
Definition: rel.h:504
Form_pg_class rd_rel
Definition: rel.h:111

References is_publishable_class(), RelationData::rd_rel, and RelationGetRelid.

Referenced by pgoutput_change(), pgoutput_truncate(), and RelationBuildPublicationDesc().

◆ is_schema_publication()

bool is_schema_publication ( Oid  pubid)

Definition at line 241 of file pg_publication.c.

242 {
243  Relation pubschsrel;
244  ScanKeyData scankey;
245  SysScanDesc scan;
246  HeapTuple tup;
247  bool result = false;
248 
249  pubschsrel = table_open(PublicationNamespaceRelationId, AccessShareLock);
250  ScanKeyInit(&scankey,
251  Anum_pg_publication_namespace_pnpubid,
252  BTEqualStrategyNumber, F_OIDEQ,
253  ObjectIdGetDatum(pubid));
254 
255  scan = systable_beginscan(pubschsrel,
256  PublicationNamespacePnnspidPnpubidIndexId,
257  true, NULL, 1, &scankey);
258  tup = systable_getnext(scan);
259  result = HeapTupleIsValid(tup);
260 
261  systable_endscan(scan);
262  table_close(pubschsrel, AccessShareLock);
263 
264  return result;
265 }

References AccessShareLock, BTEqualStrategyNumber, HeapTupleIsValid, ObjectIdGetDatum(), ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by AlterPublicationOwner_internal(), and AlterPublicationTables().

◆ MAKE_SYSCACHE() [1/2]

MAKE_SYSCACHE ( PUBLICATIONNAME  ,
pg_publication_pubname_index  ,
 
)

◆ MAKE_SYSCACHE() [2/2]

MAKE_SYSCACHE ( PUBLICATIONOID  ,
pg_publication_oid_index  ,
 
)

◆ pub_collist_to_bitmapset()

Bitmapset* pub_collist_to_bitmapset ( Bitmapset columns,
Datum  pubcols,
MemoryContext  mcxt 
)

Definition at line 575 of file pg_publication.c.

576 {
577  Bitmapset *result = NULL;
578  ArrayType *arr;
579  int nelems;
580  int16 *elems;
581  MemoryContext oldcxt = NULL;
582 
583  /*
584  * If an existing bitmap was provided, use it. Otherwise just use NULL and
585  * build a new bitmap.
586  */
587  if (columns)
588  result = columns;
589 
590  arr = DatumGetArrayTypeP(pubcols);
591  nelems = ARR_DIMS(arr)[0];
592  elems = (int16 *) ARR_DATA_PTR(arr);
593 
594  /* If a memory context was specified, switch to it. */
595  if (mcxt)
596  oldcxt = MemoryContextSwitchTo(mcxt);
597 
598  for (int i = 0; i < nelems; i++)
599  result = bms_add_member(result, elems[i]);
600 
601  if (mcxt)
602  MemoryContextSwitchTo(oldcxt);
603 
604  return result;
605 }
#define ARR_DATA_PTR(a)
Definition: array.h:322
#define DatumGetArrayTypeP(X)
Definition: array.h:261
#define ARR_DIMS(a)
Definition: array.h:294
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:828
signed short int16
Definition: c.h:482
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124

References ARR_DATA_PTR, ARR_DIMS, bms_add_member(), DatumGetArrayTypeP, i, and MemoryContextSwitchTo().

Referenced by AlterPublicationTables(), pgoutput_column_list_init(), and pub_collist_contains_invalid_column().

◆ publication_add_relation()

ObjectAddress publication_add_relation ( Oid  pubid,
PublicationRelInfo pri,
bool  if_not_exists 
)

Definition at line 363 of file pg_publication.c.

365 {
366  Relation rel;
367  HeapTuple tup;
368  Datum values[Natts_pg_publication_rel];
369  bool nulls[Natts_pg_publication_rel];
370  Relation targetrel = pri->relation;
371  Oid relid = RelationGetRelid(targetrel);
372  Oid pubreloid;
373  Publication *pub = GetPublication(pubid);
374  AttrNumber *attarray = NULL;
375  int natts = 0;
376  ObjectAddress myself,
377  referenced;
378  List *relids = NIL;
379 
380  rel = table_open(PublicationRelRelationId, RowExclusiveLock);
381 
382  /*
383  * Check for duplicates. Note that this does not really prevent
384  * duplicates, it's here just to provide nicer error message in common
385  * case. The real protection is the unique key on the catalog.
386  */
387  if (SearchSysCacheExists2(PUBLICATIONRELMAP, ObjectIdGetDatum(relid),
388  ObjectIdGetDatum(pubid)))
389  {
391 
392  if (if_not_exists)
393  return InvalidObjectAddress;
394 
395  ereport(ERROR,
397  errmsg("relation \"%s\" is already member of publication \"%s\"",
398  RelationGetRelationName(targetrel), pub->name)));
399  }
400 
402 
403  /*
404  * Translate column names to attnums and make sure the column list
405  * contains only allowed elements (no system or generated columns etc.).
406  * Also build an array of attnums, for storing in the catalog.
407  */
409  &natts, &attarray);
410 
411  /* Form a tuple. */
412  memset(values, 0, sizeof(values));
413  memset(nulls, false, sizeof(nulls));
414 
415  pubreloid = GetNewOidWithIndex(rel, PublicationRelObjectIndexId,
416  Anum_pg_publication_rel_oid);
417  values[Anum_pg_publication_rel_oid - 1] = ObjectIdGetDatum(pubreloid);
418  values[Anum_pg_publication_rel_prpubid - 1] =
419  ObjectIdGetDatum(pubid);
420  values[Anum_pg_publication_rel_prrelid - 1] =
421  ObjectIdGetDatum(relid);
422 
423  /* Add qualifications, if available */
424  if (pri->whereClause != NULL)
425  values[Anum_pg_publication_rel_prqual - 1] = CStringGetTextDatum(nodeToString(pri->whereClause));
426  else
427  nulls[Anum_pg_publication_rel_prqual - 1] = true;
428 
429  /* Add column list, if available */
430  if (pri->columns)
431  values[Anum_pg_publication_rel_prattrs - 1] = PointerGetDatum(buildint2vector(attarray, natts));
432  else
433  nulls[Anum_pg_publication_rel_prattrs - 1] = true;
434 
435  tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
436 
437  /* Insert tuple into catalog. */
438  CatalogTupleInsert(rel, tup);
439  heap_freetuple(tup);
440 
441  /* Register dependencies as needed */
442  ObjectAddressSet(myself, PublicationRelRelationId, pubreloid);
443 
444  /* Add dependency on the publication */
445  ObjectAddressSet(referenced, PublicationRelationId, pubid);
446  recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
447 
448  /* Add dependency on the relation */
449  ObjectAddressSet(referenced, RelationRelationId, relid);
450  recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
451 
452  /* Add dependency on the objects mentioned in the qualifications */
453  if (pri->whereClause)
454  recordDependencyOnSingleRelExpr(&myself, pri->whereClause, relid,
456  false);
457 
458  /* Add dependency on the columns, if any are listed */
459  for (int i = 0; i < natts; i++)
460  {
461  ObjectAddressSubSet(referenced, RelationRelationId, relid, attarray[i]);
462  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
463  }
464 
465  /* Close the table. */
467 
468  /*
469  * Invalidate relcache so that publication info is rebuilt.
470  *
471  * For the partitioned tables, we must invalidate all partitions contained
472  * in the respective partition hierarchies, not just the one explicitly
473  * mentioned in the publication. This is required because we implicitly
474  * publish the child tables when the parent table is published.
475  */
477  relid);
478 
480 
481  return myself;
482 }
int16 AttrNumber
Definition: attnum.h:21
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define CStringGetTextDatum(s)
Definition: builtins.h:97
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:393
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool reverse_self)
Definition: dependency.c:1652
@ DEPENDENCY_AUTO
Definition: dependency.h:34
@ DEPENDENCY_NORMAL
Definition: dependency.h:33
int errcode(int sqlerrcode)
Definition: elog.c:860
int errmsg(const char *fmt,...)
Definition: elog.c:1075
#define ereport(elevel,...)
Definition: elog.h:149
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1435
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:233
int2vector * buildint2vector(const int16 *int2s, int n)
Definition: int.c:114
#define RowExclusiveLock
Definition: lockdefs.h:38
const ObjectAddress InvalidObjectAddress
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define ObjectAddressSubSet(addr, class_id, object_id, object_sub_id)
Definition: objectaddress.h:33
char * nodeToString(const void *obj)
Definition: outfuncs.c:762
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
static void check_publication_add_relation(Relation targetrel)
static void publication_translate_columns(Relation targetrel, List *columns, int *natts, AttrNumber **attrs)
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
void InvalidatePublicationRels(List *relids)
#define RelationGetDescr(relation)
Definition: rel.h:530
#define RelationGetRelationName(relation)
Definition: rel.h:538
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:97

References buildint2vector(), CatalogTupleInsert(), check_publication_add_relation(), PublicationRelInfo::columns, CStringGetTextDatum, DEPENDENCY_AUTO, DEPENDENCY_NORMAL, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, GetNewOidWithIndex(), GetPublication(), GetPubPartitionOptionRelations(), heap_form_tuple(), heap_freetuple(), i, InvalidatePublicationRels(), InvalidObjectAddress, Publication::name, NIL, nodeToString(), ObjectAddressSet, ObjectAddressSubSet, ObjectIdGetDatum(), PointerGetDatum(), PUBLICATION_PART_ALL, publication_translate_columns(), recordDependencyOn(), recordDependencyOnSingleRelExpr(), PublicationRelInfo::relation, RelationGetDescr, RelationGetRelationName, RelationGetRelid, RowExclusiveLock, SearchSysCacheExists2, table_close(), table_open(), values, and PublicationRelInfo::whereClause.

Referenced by PublicationAddTables().

◆ publication_add_schema()

ObjectAddress publication_add_schema ( Oid  pubid,
Oid  schemaid,
bool  if_not_exists 
)

Definition at line 611 of file pg_publication.c.

612 {
613  Relation rel;
614  HeapTuple tup;
615  Datum values[Natts_pg_publication_namespace];
616  bool nulls[Natts_pg_publication_namespace];
617  Oid psschid;
618  Publication *pub = GetPublication(pubid);
619  List *schemaRels = NIL;
620  ObjectAddress myself,
621  referenced;
622 
623  rel = table_open(PublicationNamespaceRelationId, RowExclusiveLock);
624 
625  /*
626  * Check for duplicates. Note that this does not really prevent
627  * duplicates, it's here just to provide nicer error message in common
628  * case. The real protection is the unique key on the catalog.
629  */
630  if (SearchSysCacheExists2(PUBLICATIONNAMESPACEMAP,
631  ObjectIdGetDatum(schemaid),
632  ObjectIdGetDatum(pubid)))
633  {
635 
636  if (if_not_exists)
637  return InvalidObjectAddress;
638 
639  ereport(ERROR,
641  errmsg("schema \"%s\" is already member of publication \"%s\"",
642  get_namespace_name(schemaid), pub->name)));
643  }
644 
646 
647  /* Form a tuple */
648  memset(values, 0, sizeof(values));
649  memset(nulls, false, sizeof(nulls));
650 
651  psschid = GetNewOidWithIndex(rel, PublicationNamespaceObjectIndexId,
652  Anum_pg_publication_namespace_oid);
653  values[Anum_pg_publication_namespace_oid - 1] = ObjectIdGetDatum(psschid);
654  values[Anum_pg_publication_namespace_pnpubid - 1] =
655  ObjectIdGetDatum(pubid);
656  values[Anum_pg_publication_namespace_pnnspid - 1] =
657  ObjectIdGetDatum(schemaid);
658 
659  tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
660 
661  /* Insert tuple into catalog */
662  CatalogTupleInsert(rel, tup);
663  heap_freetuple(tup);
664 
665  ObjectAddressSet(myself, PublicationNamespaceRelationId, psschid);
666 
667  /* Add dependency on the publication */
668  ObjectAddressSet(referenced, PublicationRelationId, pubid);
669  recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
670 
671  /* Add dependency on the schema */
672  ObjectAddressSet(referenced, NamespaceRelationId, schemaid);
673  recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
674 
675  /* Close the table */
677 
678  /*
679  * Invalidate relcache so that publication info is rebuilt. See
680  * publication_add_relation for why we need to consider all the
681  * partitions.
682  */
683  schemaRels = GetSchemaPublicationRelations(schemaid,
685  InvalidatePublicationRels(schemaRels);
686 
687  return myself;
688 }
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3321
static void check_publication_add_schema(Oid schemaid)

References CatalogTupleInsert(), check_publication_add_schema(), DEPENDENCY_AUTO, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, get_namespace_name(), GetNewOidWithIndex(), GetPublication(), GetSchemaPublicationRelations(), heap_form_tuple(), heap_freetuple(), InvalidatePublicationRels(), InvalidObjectAddress, Publication::name, NIL, ObjectAddressSet, ObjectIdGetDatum(), PUBLICATION_PART_ALL, recordDependencyOn(), RelationGetDescr, RowExclusiveLock, SearchSysCacheExists2, table_close(), table_open(), and values.

Referenced by PublicationAddSchemas().

Variable Documentation

◆ FormData_pg_publication

FormData_pg_publication

Definition at line 57 of file pg_publication.h.