PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_subscription.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_subscription.c
4  * replication subscriptions
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  * src/backend/catalog/pg_subscription.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 
15 #include "postgres.h"
16 
17 #include "miscadmin.h"
18 
19 #include "access/genam.h"
20 #include "access/heapam.h"
21 #include "access/htup_details.h"
22 
23 #include "catalog/pg_type.h"
25 
26 #include "nodes/makefuncs.h"
27 
28 #include "utils/array.h"
29 #include "utils/builtins.h"
30 #include "utils/fmgroids.h"
31 #include "utils/syscache.h"
32 
33 
34 static List *textarray_to_stringlist(ArrayType *textarray);
35 
36 /*
37  * Fetch the subscription from the syscache.
38  */
40 GetSubscription(Oid subid, bool missing_ok)
41 {
42  HeapTuple tup;
43  Subscription *sub;
44  Form_pg_subscription subform;
45  Datum datum;
46  bool isnull;
47 
49 
50  if (!HeapTupleIsValid(tup))
51  {
52  if (missing_ok)
53  return NULL;
54 
55  elog(ERROR, "cache lookup failed for subscription %u", subid);
56  }
57 
58  subform = (Form_pg_subscription) GETSTRUCT(tup);
59 
60  sub = (Subscription *) palloc(sizeof(Subscription));
61  sub->oid = subid;
62  sub->dbid = subform->subdbid;
63  sub->name = pstrdup(NameStr(subform->subname));
64  sub->owner = subform->subowner;
65  sub->enabled = subform->subenabled;
66 
67  /* Get conninfo */
69  tup,
71  &isnull);
72  Assert(!isnull);
73  sub->conninfo = pstrdup(TextDatumGetCString(datum));
74 
75  /* Get slotname */
77  tup,
79  &isnull);
80  Assert(!isnull);
81  sub->slotname = pstrdup(NameStr(*DatumGetName(datum)));
82 
83  /* Get publications */
85  tup,
87  &isnull);
88  Assert(!isnull);
90 
91  ReleaseSysCache(tup);
92 
93  return sub;
94 }
95 
96 /*
97  * Return number of subscriptions defined in given database.
98  * Used by dropdb() to check if database can indeed be dropped.
99  */
100 int
102 {
103  int nsubs = 0;
104  Relation rel;
105  ScanKeyData scankey;
106  SysScanDesc scan;
107  HeapTuple tup;
108 
110 
111  ScanKeyInit(&scankey,
113  BTEqualStrategyNumber, F_OIDEQ,
114  ObjectIdGetDatum(dbid));
115 
116  scan = systable_beginscan(rel, InvalidOid, false,
117  NULL, 1, &scankey);
118 
119  while (HeapTupleIsValid(tup = systable_getnext(scan)))
120  nsubs++;
121 
122  systable_endscan(scan);
123 
124  heap_close(rel, NoLock);
125 
126  return nsubs;
127 }
128 
129 /*
130  * Free memory allocated by subscription struct.
131  */
132 void
134 {
135  pfree(sub->name);
136  pfree(sub->conninfo);
137  pfree(sub->slotname);
139  pfree(sub);
140 }
141 
142 /*
143  * get_subscription_oid - given a subscription name, look up the OID
144  *
145  * If missing_ok is false, throw an error if name not found. If true, just
146  * return InvalidOid.
147  */
148 Oid
149 get_subscription_oid(const char *subname, bool missing_ok)
150 {
151  Oid oid;
152 
154  CStringGetDatum(subname));
155  if (!OidIsValid(oid) && !missing_ok)
156  ereport(ERROR,
157  (errcode(ERRCODE_UNDEFINED_OBJECT),
158  errmsg("subscription \"%s\" does not exist", subname)));
159  return oid;
160 }
161 
162 /*
163  * get_subscription_name - given a subscription OID, look up the name
164  */
165 char *
167 {
168  HeapTuple tup;
169  char *subname;
170  Form_pg_subscription subform;
171 
173 
174  if (!HeapTupleIsValid(tup))
175  elog(ERROR, "cache lookup failed for subscription %u", subid);
176 
177  subform = (Form_pg_subscription) GETSTRUCT(tup);
178  subname = pstrdup(NameStr(subform->subname));
179 
180  ReleaseSysCache(tup);
181 
182  return subname;
183 }
184 
185 /*
186  * Convert text array to list of strings.
187  *
188  * Note: the resulting list of strings is pallocated here.
189  */
190 static List *
192 {
193  Datum *elems;
194  int nelems, i;
195  List *res = NIL;
196 
197  deconstruct_array(textarray,
198  TEXTOID, -1, false, 'i',
199  &elems, NULL, &nelems);
200 
201  if (nelems == 0)
202  return NIL;
203 
204  for (i = 0; i < nelems; i++)
205  res = lappend(res, makeString(pstrdup(TextDatumGetCString(elems[i]))));
206 
207  return res;
208 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:69
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define Anum_pg_subscription_subpublications
#define TEXTOID
Definition: pg_type.h:324
char * pstrdup(const char *in)
Definition: mcxt.c:1165
int CountDBSubscriptions(Oid dbid)
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
FormData_pg_subscription * Form_pg_subscription
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:533
void list_free_deep(List *list)
Definition: list.c:1147
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define GetSysCacheOid2(cacheId, key1, key2)
Definition: syscache.h:178
#define DatumGetName(X)
Definition: postgres.h:593
Subscription * GetSubscription(Oid subid, bool missing_ok)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
void pfree(void *pointer)
Definition: mcxt.c:992
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
static List * textarray_to_stringlist(ArrayType *textarray)
#define SubscriptionRelationId
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:586
List * publications
#define ereport(elevel, rest)
Definition: elog.h:122
#define Anum_pg_subscription_subslotname
List * lappend(List *list, void *datum)
Definition: list.c:128
#define Anum_pg_subscription_subdbid
#define TextDatumGetCString(d)
Definition: builtins.h:91
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
Oid MyDatabaseId
Definition: globals.c:76
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define InvalidOid
Definition: postgres_ext.h:36
#define Anum_pg_subscription_subconninfo
Oid get_subscription_oid(const char *subname, bool missing_ok)
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
void FreeSubscription(Subscription *sub)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3475
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define NameStr(name)
Definition: c.h:494
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
Definition: pg_list.h:45
#define BTEqualStrategyNumber
Definition: stratnum.h:31
char * get_subscription_name(Oid subid)
#define DatumGetArrayTypeP(X)
Definition: array.h:242