PostgreSQL Source Code  git master
seclabel.c
Go to the documentation of this file.
1 /* -------------------------------------------------------------------------
2  *
3  * seclabel.c
4  * routines to support security label feature.
5  *
6  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * -------------------------------------------------------------------------
10  */
11 #include "postgres.h"
12 
13 #include "access/genam.h"
14 #include "access/htup_details.h"
15 #include "access/relation.h"
16 #include "access/table.h"
17 #include "catalog/catalog.h"
18 #include "catalog/indexing.h"
19 #include "catalog/pg_seclabel.h"
20 #include "catalog/pg_shseclabel.h"
21 #include "commands/seclabel.h"
22 #include "miscadmin.h"
23 #include "utils/builtins.h"
24 #include "utils/fmgroids.h"
25 #include "utils/memutils.h"
26 #include "utils/rel.h"
27 
28 typedef struct
29 {
30  const char *provider_name;
33 
35 
36 static bool
38 {
39  switch (objtype)
40  {
41  case OBJECT_AGGREGATE:
42  case OBJECT_COLUMN:
43  case OBJECT_DATABASE:
44  case OBJECT_DOMAIN:
47  case OBJECT_FUNCTION:
48  case OBJECT_LANGUAGE:
49  case OBJECT_LARGEOBJECT:
50  case OBJECT_MATVIEW:
51  case OBJECT_PROCEDURE:
52  case OBJECT_PUBLICATION:
53  case OBJECT_ROLE:
54  case OBJECT_ROUTINE:
55  case OBJECT_SCHEMA:
56  case OBJECT_SEQUENCE:
58  case OBJECT_TABLE:
59  case OBJECT_TABLESPACE:
60  case OBJECT_TYPE:
61  case OBJECT_VIEW:
62  return true;
63 
65  case OBJECT_AMOP:
66  case OBJECT_AMPROC:
67  case OBJECT_ATTRIBUTE:
68  case OBJECT_CAST:
69  case OBJECT_COLLATION:
70  case OBJECT_CONVERSION:
71  case OBJECT_DEFAULT:
72  case OBJECT_DEFACL:
74  case OBJECT_EXTENSION:
75  case OBJECT_FDW:
77  case OBJECT_INDEX:
78  case OBJECT_OPCLASS:
79  case OBJECT_OPERATOR:
80  case OBJECT_OPFAMILY:
81  case OBJECT_POLICY:
84  case OBJECT_RULE:
87  case OBJECT_TRANSFORM:
88  case OBJECT_TRIGGER:
91  case OBJECT_TSPARSER:
92  case OBJECT_TSTEMPLATE:
94  return false;
95 
96  /*
97  * There's intentionally no default: case here; we want the
98  * compiler to warn if a new ObjectType hasn't been handled above.
99  */
100  }
101 
102  /* Shouldn't get here, but if we do, say "no support" */
103  return false;
104 }
105 
106 /*
107  * ExecSecLabelStmt --
108  *
109  * Apply a security label to a database object.
110  *
111  * Returns the ObjectAddress of the object to which the policy was applied.
112  */
115 {
116  LabelProvider *provider = NULL;
117  ObjectAddress address;
118  Relation relation;
119  ListCell *lc;
120 
121  /*
122  * Find the named label provider, or if none specified, check whether
123  * there's exactly one, and if so use it.
124  */
125  if (stmt->provider == NULL)
126  {
127  if (label_provider_list == NIL)
128  ereport(ERROR,
129  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
130  errmsg("no security label providers have been loaded")));
131  if (list_length(label_provider_list) != 1)
132  ereport(ERROR,
133  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
134  errmsg("must specify provider when multiple security label providers have been loaded")));
135  provider = (LabelProvider *) linitial(label_provider_list);
136  }
137  else
138  {
139  foreach(lc, label_provider_list)
140  {
141  LabelProvider *lp = lfirst(lc);
142 
143  if (strcmp(stmt->provider, lp->provider_name) == 0)
144  {
145  provider = lp;
146  break;
147  }
148  }
149  if (provider == NULL)
150  ereport(ERROR,
151  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
152  errmsg("security label provider \"%s\" is not loaded",
153  stmt->provider)));
154  }
155 
157  ereport(ERROR,
158  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
159  errmsg("security labels are not supported for this type of object")));
160 
161  /*
162  * Translate the parser representation which identifies this object into
163  * an ObjectAddress. get_object_address() will throw an error if the
164  * object does not exist, and will also acquire a lock on the target to
165  * guard against concurrent modifications.
166  */
167  address = get_object_address(stmt->objtype, stmt->object,
168  &relation, ShareUpdateExclusiveLock, false);
169 
170  /* Require ownership of the target object. */
171  check_object_ownership(GetUserId(), stmt->objtype, address,
172  stmt->object, relation);
173 
174  /* Perform other integrity checks as needed. */
175  switch (stmt->objtype)
176  {
177  case OBJECT_COLUMN:
178 
179  /*
180  * Allow security labels only on columns of tables, views,
181  * materialized views, composite types, and foreign tables (which
182  * are the only relkinds for which pg_dump will dump labels).
183  */
184  if (relation->rd_rel->relkind != RELKIND_RELATION &&
185  relation->rd_rel->relkind != RELKIND_VIEW &&
186  relation->rd_rel->relkind != RELKIND_MATVIEW &&
187  relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
188  relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
189  relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
190  ereport(ERROR,
191  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
192  errmsg("cannot set security label on relation \"%s\"",
193  RelationGetRelationName(relation)),
194  errdetail_relkind_not_supported(relation->rd_rel->relkind)));
195  break;
196  default:
197  break;
198  }
199 
200  /* Provider gets control here, may throw ERROR to veto new label. */
201  provider->hook(&address, stmt->label);
202 
203  /* Apply new label. */
204  SetSecurityLabel(&address, provider->provider_name, stmt->label);
205 
206  /*
207  * If get_object_address() opened the relation for us, we close it to keep
208  * the reference count correct - but we retain any locks acquired by
209  * get_object_address() until commit time, to guard against concurrent
210  * activity.
211  */
212  if (relation != NULL)
213  relation_close(relation, NoLock);
214 
215  return address;
216 }
217 
218 /*
219  * GetSharedSecurityLabel returns the security label for a shared object for
220  * a given provider, or NULL if there is no such label.
221  */
222 static char *
223 GetSharedSecurityLabel(const ObjectAddress *object, const char *provider)
224 {
225  Relation pg_shseclabel;
226  ScanKeyData keys[3];
227  SysScanDesc scan;
228  HeapTuple tuple;
229  Datum datum;
230  bool isnull;
231  char *seclabel = NULL;
232 
233  ScanKeyInit(&keys[0],
234  Anum_pg_shseclabel_objoid,
235  BTEqualStrategyNumber, F_OIDEQ,
236  ObjectIdGetDatum(object->objectId));
237  ScanKeyInit(&keys[1],
238  Anum_pg_shseclabel_classoid,
239  BTEqualStrategyNumber, F_OIDEQ,
240  ObjectIdGetDatum(object->classId));
241  ScanKeyInit(&keys[2],
242  Anum_pg_shseclabel_provider,
243  BTEqualStrategyNumber, F_TEXTEQ,
244  CStringGetTextDatum(provider));
245 
246  pg_shseclabel = table_open(SharedSecLabelRelationId, AccessShareLock);
247 
248  scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId,
249  criticalSharedRelcachesBuilt, NULL, 3, keys);
250 
251  tuple = systable_getnext(scan);
252  if (HeapTupleIsValid(tuple))
253  {
254  datum = heap_getattr(tuple, Anum_pg_shseclabel_label,
255  RelationGetDescr(pg_shseclabel), &isnull);
256  if (!isnull)
257  seclabel = TextDatumGetCString(datum);
258  }
259  systable_endscan(scan);
260 
261  table_close(pg_shseclabel, AccessShareLock);
262 
263  return seclabel;
264 }
265 
266 /*
267  * GetSecurityLabel returns the security label for a shared or database object
268  * for a given provider, or NULL if there is no such label.
269  */
270 char *
271 GetSecurityLabel(const ObjectAddress *object, const char *provider)
272 {
273  Relation pg_seclabel;
274  ScanKeyData keys[4];
275  SysScanDesc scan;
276  HeapTuple tuple;
277  Datum datum;
278  bool isnull;
279  char *seclabel = NULL;
280 
281  /* Shared objects have their own security label catalog. */
282  if (IsSharedRelation(object->classId))
283  return GetSharedSecurityLabel(object, provider);
284 
285  /* Must be an unshared object, so examine pg_seclabel. */
286  ScanKeyInit(&keys[0],
287  Anum_pg_seclabel_objoid,
288  BTEqualStrategyNumber, F_OIDEQ,
289  ObjectIdGetDatum(object->objectId));
290  ScanKeyInit(&keys[1],
291  Anum_pg_seclabel_classoid,
292  BTEqualStrategyNumber, F_OIDEQ,
293  ObjectIdGetDatum(object->classId));
294  ScanKeyInit(&keys[2],
295  Anum_pg_seclabel_objsubid,
296  BTEqualStrategyNumber, F_INT4EQ,
297  Int32GetDatum(object->objectSubId));
298  ScanKeyInit(&keys[3],
299  Anum_pg_seclabel_provider,
300  BTEqualStrategyNumber, F_TEXTEQ,
301  CStringGetTextDatum(provider));
302 
303  pg_seclabel = table_open(SecLabelRelationId, AccessShareLock);
304 
305  scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true,
306  NULL, 4, keys);
307 
308  tuple = systable_getnext(scan);
309  if (HeapTupleIsValid(tuple))
310  {
311  datum = heap_getattr(tuple, Anum_pg_seclabel_label,
312  RelationGetDescr(pg_seclabel), &isnull);
313  if (!isnull)
314  seclabel = TextDatumGetCString(datum);
315  }
316  systable_endscan(scan);
317 
318  table_close(pg_seclabel, AccessShareLock);
319 
320  return seclabel;
321 }
322 
323 /*
324  * SetSharedSecurityLabel is a helper function of SetSecurityLabel to
325  * handle shared database objects.
326  */
327 static void
329  const char *provider, const char *label)
330 {
331  Relation pg_shseclabel;
332  ScanKeyData keys[4];
333  SysScanDesc scan;
334  HeapTuple oldtup;
335  HeapTuple newtup = NULL;
336  Datum values[Natts_pg_shseclabel];
337  bool nulls[Natts_pg_shseclabel];
338  bool replaces[Natts_pg_shseclabel];
339 
340  /* Prepare to form or update a tuple, if necessary. */
341  memset(nulls, false, sizeof(nulls));
342  memset(replaces, false, sizeof(replaces));
343  values[Anum_pg_shseclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
344  values[Anum_pg_shseclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
345  values[Anum_pg_shseclabel_provider - 1] = CStringGetTextDatum(provider);
346  if (label != NULL)
347  values[Anum_pg_shseclabel_label - 1] = CStringGetTextDatum(label);
348 
349  /* Use the index to search for a matching old tuple */
350  ScanKeyInit(&keys[0],
351  Anum_pg_shseclabel_objoid,
352  BTEqualStrategyNumber, F_OIDEQ,
353  ObjectIdGetDatum(object->objectId));
354  ScanKeyInit(&keys[1],
355  Anum_pg_shseclabel_classoid,
356  BTEqualStrategyNumber, F_OIDEQ,
357  ObjectIdGetDatum(object->classId));
358  ScanKeyInit(&keys[2],
359  Anum_pg_shseclabel_provider,
360  BTEqualStrategyNumber, F_TEXTEQ,
361  CStringGetTextDatum(provider));
362 
363  pg_shseclabel = table_open(SharedSecLabelRelationId, RowExclusiveLock);
364 
365  scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true,
366  NULL, 3, keys);
367 
368  oldtup = systable_getnext(scan);
369  if (HeapTupleIsValid(oldtup))
370  {
371  if (label == NULL)
372  CatalogTupleDelete(pg_shseclabel, &oldtup->t_self);
373  else
374  {
375  replaces[Anum_pg_shseclabel_label - 1] = true;
376  newtup = heap_modify_tuple(oldtup, RelationGetDescr(pg_shseclabel),
377  values, nulls, replaces);
378  CatalogTupleUpdate(pg_shseclabel, &oldtup->t_self, newtup);
379  }
380  }
381  systable_endscan(scan);
382 
383  /* If we didn't find an old tuple, insert a new one */
384  if (newtup == NULL && label != NULL)
385  {
386  newtup = heap_form_tuple(RelationGetDescr(pg_shseclabel),
387  values, nulls);
388  CatalogTupleInsert(pg_shseclabel, newtup);
389  }
390 
391  if (newtup != NULL)
392  heap_freetuple(newtup);
393 
394  table_close(pg_shseclabel, RowExclusiveLock);
395 }
396 
397 /*
398  * SetSecurityLabel attempts to set the security label for the specified
399  * provider on the specified object to the given value. NULL means that any
400  * existing label should be deleted.
401  */
402 void
404  const char *provider, const char *label)
405 {
406  Relation pg_seclabel;
407  ScanKeyData keys[4];
408  SysScanDesc scan;
409  HeapTuple oldtup;
410  HeapTuple newtup = NULL;
411  Datum values[Natts_pg_seclabel];
412  bool nulls[Natts_pg_seclabel];
413  bool replaces[Natts_pg_seclabel];
414 
415  /* Shared objects have their own security label catalog. */
416  if (IsSharedRelation(object->classId))
417  {
418  SetSharedSecurityLabel(object, provider, label);
419  return;
420  }
421 
422  /* Prepare to form or update a tuple, if necessary. */
423  memset(nulls, false, sizeof(nulls));
424  memset(replaces, false, sizeof(replaces));
425  values[Anum_pg_seclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
426  values[Anum_pg_seclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
427  values[Anum_pg_seclabel_objsubid - 1] = Int32GetDatum(object->objectSubId);
428  values[Anum_pg_seclabel_provider - 1] = CStringGetTextDatum(provider);
429  if (label != NULL)
430  values[Anum_pg_seclabel_label - 1] = CStringGetTextDatum(label);
431 
432  /* Use the index to search for a matching old tuple */
433  ScanKeyInit(&keys[0],
434  Anum_pg_seclabel_objoid,
435  BTEqualStrategyNumber, F_OIDEQ,
436  ObjectIdGetDatum(object->objectId));
437  ScanKeyInit(&keys[1],
438  Anum_pg_seclabel_classoid,
439  BTEqualStrategyNumber, F_OIDEQ,
440  ObjectIdGetDatum(object->classId));
441  ScanKeyInit(&keys[2],
442  Anum_pg_seclabel_objsubid,
443  BTEqualStrategyNumber, F_INT4EQ,
444  Int32GetDatum(object->objectSubId));
445  ScanKeyInit(&keys[3],
446  Anum_pg_seclabel_provider,
447  BTEqualStrategyNumber, F_TEXTEQ,
448  CStringGetTextDatum(provider));
449 
450  pg_seclabel = table_open(SecLabelRelationId, RowExclusiveLock);
451 
452  scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true,
453  NULL, 4, keys);
454 
455  oldtup = systable_getnext(scan);
456  if (HeapTupleIsValid(oldtup))
457  {
458  if (label == NULL)
459  CatalogTupleDelete(pg_seclabel, &oldtup->t_self);
460  else
461  {
462  replaces[Anum_pg_seclabel_label - 1] = true;
463  newtup = heap_modify_tuple(oldtup, RelationGetDescr(pg_seclabel),
464  values, nulls, replaces);
465  CatalogTupleUpdate(pg_seclabel, &oldtup->t_self, newtup);
466  }
467  }
468  systable_endscan(scan);
469 
470  /* If we didn't find an old tuple, insert a new one */
471  if (newtup == NULL && label != NULL)
472  {
473  newtup = heap_form_tuple(RelationGetDescr(pg_seclabel),
474  values, nulls);
475  CatalogTupleInsert(pg_seclabel, newtup);
476  }
477 
478  /* Update indexes, if necessary */
479  if (newtup != NULL)
480  heap_freetuple(newtup);
481 
482  table_close(pg_seclabel, RowExclusiveLock);
483 }
484 
485 /*
486  * DeleteSharedSecurityLabel is a helper function of DeleteSecurityLabel
487  * to handle shared database objects.
488  */
489 void
491 {
492  Relation pg_shseclabel;
493  ScanKeyData skey[2];
494  SysScanDesc scan;
495  HeapTuple oldtup;
496 
497  ScanKeyInit(&skey[0],
498  Anum_pg_shseclabel_objoid,
499  BTEqualStrategyNumber, F_OIDEQ,
500  ObjectIdGetDatum(objectId));
501  ScanKeyInit(&skey[1],
502  Anum_pg_shseclabel_classoid,
503  BTEqualStrategyNumber, F_OIDEQ,
504  ObjectIdGetDatum(classId));
505 
506  pg_shseclabel = table_open(SharedSecLabelRelationId, RowExclusiveLock);
507 
508  scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true,
509  NULL, 2, skey);
510  while (HeapTupleIsValid(oldtup = systable_getnext(scan)))
511  CatalogTupleDelete(pg_shseclabel, &oldtup->t_self);
512  systable_endscan(scan);
513 
514  table_close(pg_shseclabel, RowExclusiveLock);
515 }
516 
517 /*
518  * DeleteSecurityLabel removes all security labels for an object (and any
519  * sub-objects, if applicable).
520  */
521 void
523 {
524  Relation pg_seclabel;
525  ScanKeyData skey[3];
526  SysScanDesc scan;
527  HeapTuple oldtup;
528  int nkeys;
529 
530  /* Shared objects have their own security label catalog. */
531  if (IsSharedRelation(object->classId))
532  {
533  Assert(object->objectSubId == 0);
534  DeleteSharedSecurityLabel(object->objectId, object->classId);
535  return;
536  }
537 
538  ScanKeyInit(&skey[0],
539  Anum_pg_seclabel_objoid,
540  BTEqualStrategyNumber, F_OIDEQ,
541  ObjectIdGetDatum(object->objectId));
542  ScanKeyInit(&skey[1],
543  Anum_pg_seclabel_classoid,
544  BTEqualStrategyNumber, F_OIDEQ,
545  ObjectIdGetDatum(object->classId));
546  if (object->objectSubId != 0)
547  {
548  ScanKeyInit(&skey[2],
549  Anum_pg_seclabel_objsubid,
550  BTEqualStrategyNumber, F_INT4EQ,
551  Int32GetDatum(object->objectSubId));
552  nkeys = 3;
553  }
554  else
555  nkeys = 2;
556 
557  pg_seclabel = table_open(SecLabelRelationId, RowExclusiveLock);
558 
559  scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true,
560  NULL, nkeys, skey);
561  while (HeapTupleIsValid(oldtup = systable_getnext(scan)))
562  CatalogTupleDelete(pg_seclabel, &oldtup->t_self);
563  systable_endscan(scan);
564 
565  table_close(pg_seclabel, RowExclusiveLock);
566 }
567 
568 void
569 register_label_provider(const char *provider_name, check_object_relabel_type hook)
570 {
572  MemoryContext oldcxt;
573 
575  provider = palloc(sizeof(LabelProvider));
576  provider->provider_name = pstrdup(provider_name);
577  provider->hook = hook;
578  label_provider_list = lappend(label_provider_list, provider);
579  MemoryContextSwitchTo(oldcxt);
580 }
int errdetail_relkind_not_supported(char relkind)
Definition: pg_class.c:24
#define NIL
Definition: pg_list.h:65
ObjectType objtype
Definition: parsenodes.h:2805
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
Node * object
Definition: parsenodes.h:2806
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:595
void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition: seclabel.c:403
#define RelationGetDescr(relation)
Definition: rel.h:503
ObjectAddress ExecSecLabelStmt(SecLabelStmt *stmt)
Definition: seclabel.c:114
Oid GetUserId(void)
Definition: miscinit.c:495
char * pstrdup(const char *in)
Definition: mcxt.c:1299
static char * GetSharedSecurityLabel(const ObjectAddress *object, const char *provider)
Definition: seclabel.c:223
void DeleteSecurityLabel(const ObjectAddress *object)
Definition: seclabel.c:522
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define AccessShareLock
Definition: lockdefs.h:36
char * provider
Definition: parsenodes.h:2807
int errcode(int sqlerrcode)
Definition: elog.c:698
const char * provider_name
Definition: seclabel.c:30
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
bool criticalSharedRelcachesBuilt
Definition: relcache.c:143
Form_pg_class rd_rel
Definition: rel.h:109
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
static List * label_provider_list
Definition: seclabel.c:34
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define linitial(l)
Definition: pg_list.h:174
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * GetSecurityLabel(const ObjectAddress *object, const char *provider)
Definition: seclabel.c:271
char * label
Definition: parsenodes.h:2808
ItemPointerData t_self
Definition: htup.h:65
static JitProviderCallbacks provider
Definition: jit.c:43
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
struct statement * stmt
#define RelationGetRelationName(relation)
Definition: rel.h:511
void(* check_object_relabel_type)(const ObjectAddress *object, const char *seclabel)
Definition: seclabel.h:29
MemoryContext TopMemoryContext
Definition: mcxt.c:48
ObjectType
Definition: parsenodes.h:1787
List * lappend(List *list, void *datum)
Definition: list.c:336
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:761
#define TextDatumGetCString(d)
Definition: builtins.h:87
uintptr_t Datum
Definition: postgres.h:411
check_object_relabel_type hook
Definition: seclabel.c:31
static char * label
bool IsSharedRelation(Oid relationId)
Definition: catalog.c:244
void register_label_provider(const char *provider_name, check_object_relabel_type hook)
Definition: seclabel.c:569
#define ereport(elevel,...)
Definition: elog.h:157
static void SetSharedSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition: seclabel.c:328
#define ShareUpdateExclusiveLock
Definition: lockdefs.h:39
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:206
#define Assert(condition)
Definition: c.h:804
#define lfirst(lc)
Definition: pg_list.h:169
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
static int list_length(const List *l)
Definition: pg_list.h:149
void DeleteSharedSecurityLabel(Oid objectId, Oid classId)
Definition: seclabel.c:490
static Datum values[MAXATTR]
Definition: bootstrap.c:156
void check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, Node *object, Relation relation)
#define Int32GetDatum(X)
Definition: postgres.h:523
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define CStringGetTextDatum(s)
Definition: builtins.h:86
static bool SecLabelSupportsObjectType(ObjectType objtype)
Definition: seclabel.c:37
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1113
Definition: pg_list.h:50
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:221
#define BTEqualStrategyNumber
Definition: stratnum.h:31