PostgreSQL Source Code  git master
enum.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * enum.c
4  * I/O functions, operators, aggregates etc for enum types
5  *
6  * Copyright (c) 2006-2024, PostgreSQL Global Development Group
7  *
8  *
9  * IDENTIFICATION
10  * src/backend/utils/adt/enum.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15 
16 #include "access/genam.h"
17 #include "access/htup_details.h"
18 #include "access/table.h"
19 #include "catalog/pg_enum.h"
20 #include "libpq/pqformat.h"
21 #include "storage/procarray.h"
22 #include "utils/array.h"
23 #include "utils/builtins.h"
24 #include "utils/fmgroids.h"
25 #include "utils/syscache.h"
26 #include "utils/typcache.h"
27 
28 
29 static Oid enum_endpoint(Oid enumtypoid, ScanDirection direction);
30 static ArrayType *enum_range_internal(Oid enumtypoid, Oid lower, Oid upper);
31 
32 
33 /*
34  * Disallow use of an uncommitted pg_enum tuple.
35  *
36  * We need to make sure that uncommitted enum values don't get into indexes.
37  * If they did, and if we then rolled back the pg_enum addition, we'd have
38  * broken the index because value comparisons will not work reliably without
39  * an underlying pg_enum entry. (Note that removal of the heap entry
40  * containing an enum value is not sufficient to ensure that it doesn't appear
41  * in upper levels of indexes.) To do this we prevent an uncommitted row from
42  * being used for any SQL-level purpose. This is stronger than necessary,
43  * since the value might not be getting inserted into a table or there might
44  * be no index on its column, but it's easy to enforce centrally.
45  *
46  * However, it's okay to allow use of uncommitted values belonging to enum
47  * types that were themselves created in the same transaction, because then
48  * any such index would also be new and would go away altogether on rollback.
49  * We don't implement that fully right now, but we do allow free use of enum
50  * values created during CREATE TYPE AS ENUM, which are surely of the same
51  * lifespan as the enum type. (This case is required by "pg_restore -1".)
52  * Values added by ALTER TYPE ADD VALUE are currently restricted, but could
53  * be allowed if the enum type could be proven to have been created earlier
54  * in the same transaction. (Note that comparing tuple xmins would not work
55  * for that, because the type tuple might have been updated in the current
56  * transaction. Subtransactions also create hazards to be accounted for.)
57  *
58  * This function needs to be called (directly or indirectly) in any of the
59  * functions below that could return an enum value to SQL operations.
60  */
61 static void
63 {
64  TransactionId xmin;
65  Form_pg_enum en = (Form_pg_enum) GETSTRUCT(enumval_tup);
66 
67  /*
68  * If the row is hinted as committed, it's surely safe. This provides a
69  * fast path for all normal use-cases.
70  */
71  if (HeapTupleHeaderXminCommitted(enumval_tup->t_data))
72  return;
73 
74  /*
75  * Usually, a row would get hinted as committed when it's read or loaded
76  * into syscache; but just in case not, let's check the xmin directly.
77  */
78  xmin = HeapTupleHeaderGetXmin(enumval_tup->t_data);
79  if (!TransactionIdIsInProgress(xmin) &&
81  return;
82 
83  /*
84  * Check if the enum value is uncommitted. If not, it's safe, because it
85  * was made during CREATE TYPE AS ENUM and can't be shorter-lived than its
86  * owning type. (This'd also be false for values made by other
87  * transactions; but the previous tests should have handled all of those.)
88  */
89  if (!EnumUncommitted(en->oid))
90  return;
91 
92  /*
93  * There might well be other tests we could do here to narrow down the
94  * unsafe conditions, but for now just raise an exception.
95  */
96  ereport(ERROR,
97  (errcode(ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE),
98  errmsg("unsafe use of new value \"%s\" of enum type %s",
99  NameStr(en->enumlabel),
100  format_type_be(en->enumtypid)),
101  errhint("New enum values must be committed before they can be used.")));
102 }
103 
104 
105 /* Basic I/O support */
106 
107 Datum
109 {
110  char *name = PG_GETARG_CSTRING(0);
111  Oid enumtypoid = PG_GETARG_OID(1);
112  Node *escontext = fcinfo->context;
113  Oid enumoid;
114  HeapTuple tup;
115 
116  /* must check length to prevent Assert failure within SearchSysCache */
117  if (strlen(name) >= NAMEDATALEN)
118  ereturn(escontext, (Datum) 0,
119  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
120  errmsg("invalid input value for enum %s: \"%s\"",
121  format_type_be(enumtypoid),
122  name)));
123 
124  tup = SearchSysCache2(ENUMTYPOIDNAME,
125  ObjectIdGetDatum(enumtypoid),
127  if (!HeapTupleIsValid(tup))
128  ereturn(escontext, (Datum) 0,
129  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
130  errmsg("invalid input value for enum %s: \"%s\"",
131  format_type_be(enumtypoid),
132  name)));
133 
134  /*
135  * Check it's safe to use in SQL. Perhaps we should take the trouble to
136  * report "unsafe use" softly; but it's unclear that it's worth the
137  * trouble, or indeed that that is a legitimate bad-input case at all
138  * rather than an implementation shortcoming.
139  */
140  check_safe_enum_use(tup);
141 
142  /*
143  * This comes from pg_enum.oid and stores system oids in user tables. This
144  * oid must be preserved by binary upgrades.
145  */
146  enumoid = ((Form_pg_enum) GETSTRUCT(tup))->oid;
147 
148  ReleaseSysCache(tup);
149 
150  PG_RETURN_OID(enumoid);
151 }
152 
153 Datum
155 {
156  Oid enumval = PG_GETARG_OID(0);
157  char *result;
158  HeapTuple tup;
159  Form_pg_enum en;
160 
161  tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(enumval));
162  if (!HeapTupleIsValid(tup))
163  ereport(ERROR,
164  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
165  errmsg("invalid internal value for enum: %u",
166  enumval)));
167  en = (Form_pg_enum) GETSTRUCT(tup);
168 
169  result = pstrdup(NameStr(en->enumlabel));
170 
171  ReleaseSysCache(tup);
172 
173  PG_RETURN_CSTRING(result);
174 }
175 
176 /* Binary I/O support */
177 Datum
179 {
181  Oid enumtypoid = PG_GETARG_OID(1);
182  Oid enumoid;
183  HeapTuple tup;
184  char *name;
185  int nbytes;
186 
187  name = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
188 
189  /* must check length to prevent Assert failure within SearchSysCache */
190  if (strlen(name) >= NAMEDATALEN)
191  ereport(ERROR,
192  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
193  errmsg("invalid input value for enum %s: \"%s\"",
194  format_type_be(enumtypoid),
195  name)));
196 
197  tup = SearchSysCache2(ENUMTYPOIDNAME,
198  ObjectIdGetDatum(enumtypoid),
200  if (!HeapTupleIsValid(tup))
201  ereport(ERROR,
202  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
203  errmsg("invalid input value for enum %s: \"%s\"",
204  format_type_be(enumtypoid),
205  name)));
206 
207  /* check it's safe to use in SQL */
208  check_safe_enum_use(tup);
209 
210  enumoid = ((Form_pg_enum) GETSTRUCT(tup))->oid;
211 
212  ReleaseSysCache(tup);
213 
214  pfree(name);
215 
216  PG_RETURN_OID(enumoid);
217 }
218 
219 Datum
221 {
222  Oid enumval = PG_GETARG_OID(0);
224  HeapTuple tup;
225  Form_pg_enum en;
226 
227  tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(enumval));
228  if (!HeapTupleIsValid(tup))
229  ereport(ERROR,
230  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
231  errmsg("invalid internal value for enum: %u",
232  enumval)));
233  en = (Form_pg_enum) GETSTRUCT(tup);
234 
236  pq_sendtext(&buf, NameStr(en->enumlabel), strlen(NameStr(en->enumlabel)));
237 
238  ReleaseSysCache(tup);
239 
241 }
242 
243 /* Comparison functions and related */
244 
245 /*
246  * enum_cmp_internal is the common engine for all the visible comparison
247  * functions, except for enum_eq and enum_ne which can just check for OID
248  * equality directly.
249  */
250 static int
252 {
253  TypeCacheEntry *tcache;
254 
255  /*
256  * We don't need the typcache except in the hopefully-uncommon case that
257  * one or both Oids are odd. This means that cursory testing of code that
258  * fails to pass flinfo to an enum comparison function might not disclose
259  * the oversight. To make such errors more obvious, Assert that we have a
260  * place to cache even when we take a fast-path exit.
261  */
262  Assert(fcinfo->flinfo != NULL);
263 
264  /* Equal OIDs are equal no matter what */
265  if (arg1 == arg2)
266  return 0;
267 
268  /* Fast path: even-numbered Oids are known to compare correctly */
269  if ((arg1 & 1) == 0 && (arg2 & 1) == 0)
270  {
271  if (arg1 < arg2)
272  return -1;
273  else
274  return 1;
275  }
276 
277  /* Locate the typcache entry for the enum type */
278  tcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
279  if (tcache == NULL)
280  {
281  HeapTuple enum_tup;
282  Form_pg_enum en;
283  Oid typeoid;
284 
285  /* Get the OID of the enum type containing arg1 */
286  enum_tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(arg1));
287  if (!HeapTupleIsValid(enum_tup))
288  ereport(ERROR,
289  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
290  errmsg("invalid internal value for enum: %u",
291  arg1)));
292  en = (Form_pg_enum) GETSTRUCT(enum_tup);
293  typeoid = en->enumtypid;
294  ReleaseSysCache(enum_tup);
295  /* Now locate and remember the typcache entry */
296  tcache = lookup_type_cache(typeoid, 0);
297  fcinfo->flinfo->fn_extra = (void *) tcache;
298  }
299 
300  /* The remaining comparison logic is in typcache.c */
301  return compare_values_of_enum(tcache, arg1, arg2);
302 }
303 
304 Datum
306 {
307  Oid a = PG_GETARG_OID(0);
308  Oid b = PG_GETARG_OID(1);
309 
310  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) < 0);
311 }
312 
313 Datum
315 {
316  Oid a = PG_GETARG_OID(0);
317  Oid b = PG_GETARG_OID(1);
318 
319  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) <= 0);
320 }
321 
322 Datum
324 {
325  Oid a = PG_GETARG_OID(0);
326  Oid b = PG_GETARG_OID(1);
327 
328  PG_RETURN_BOOL(a == b);
329 }
330 
331 Datum
333 {
334  Oid a = PG_GETARG_OID(0);
335  Oid b = PG_GETARG_OID(1);
336 
337  PG_RETURN_BOOL(a != b);
338 }
339 
340 Datum
342 {
343  Oid a = PG_GETARG_OID(0);
344  Oid b = PG_GETARG_OID(1);
345 
346  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) >= 0);
347 }
348 
349 Datum
351 {
352  Oid a = PG_GETARG_OID(0);
353  Oid b = PG_GETARG_OID(1);
354 
355  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) > 0);
356 }
357 
358 Datum
360 {
361  Oid a = PG_GETARG_OID(0);
362  Oid b = PG_GETARG_OID(1);
363 
364  PG_RETURN_OID(enum_cmp_internal(a, b, fcinfo) < 0 ? a : b);
365 }
366 
367 Datum
369 {
370  Oid a = PG_GETARG_OID(0);
371  Oid b = PG_GETARG_OID(1);
372 
373  PG_RETURN_OID(enum_cmp_internal(a, b, fcinfo) > 0 ? a : b);
374 }
375 
376 Datum
378 {
379  Oid a = PG_GETARG_OID(0);
380  Oid b = PG_GETARG_OID(1);
381 
383 }
384 
385 /* Enum programming support functions */
386 
387 /*
388  * enum_endpoint: common code for enum_first/enum_last
389  */
390 static Oid
391 enum_endpoint(Oid enumtypoid, ScanDirection direction)
392 {
393  Relation enum_rel;
394  Relation enum_idx;
395  SysScanDesc enum_scan;
396  HeapTuple enum_tuple;
397  ScanKeyData skey;
398  Oid minmax;
399 
400  /*
401  * Find the first/last enum member using pg_enum_typid_sortorder_index.
402  * Note we must not use the syscache. See comments for RenumberEnumType
403  * in catalog/pg_enum.c for more info.
404  */
405  ScanKeyInit(&skey,
406  Anum_pg_enum_enumtypid,
407  BTEqualStrategyNumber, F_OIDEQ,
408  ObjectIdGetDatum(enumtypoid));
409 
410  enum_rel = table_open(EnumRelationId, AccessShareLock);
411  enum_idx = index_open(EnumTypIdSortOrderIndexId, AccessShareLock);
412  enum_scan = systable_beginscan_ordered(enum_rel, enum_idx, NULL,
413  1, &skey);
414 
415  enum_tuple = systable_getnext_ordered(enum_scan, direction);
416  if (HeapTupleIsValid(enum_tuple))
417  {
418  /* check it's safe to use in SQL */
419  check_safe_enum_use(enum_tuple);
420  minmax = ((Form_pg_enum) GETSTRUCT(enum_tuple))->oid;
421  }
422  else
423  {
424  /* should only happen with an empty enum */
425  minmax = InvalidOid;
426  }
427 
428  systable_endscan_ordered(enum_scan);
429  index_close(enum_idx, AccessShareLock);
430  table_close(enum_rel, AccessShareLock);
431 
432  return minmax;
433 }
434 
435 Datum
437 {
438  Oid enumtypoid;
439  Oid min;
440 
441  /*
442  * We rely on being able to get the specific enum type from the calling
443  * expression tree. Notice that the actual value of the argument isn't
444  * examined at all; in particular it might be NULL.
445  */
446  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
447  if (enumtypoid == InvalidOid)
448  ereport(ERROR,
449  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
450  errmsg("could not determine actual enum type")));
451 
452  /* Get the OID using the index */
453  min = enum_endpoint(enumtypoid, ForwardScanDirection);
454 
455  if (!OidIsValid(min))
456  ereport(ERROR,
457  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
458  errmsg("enum %s contains no values",
459  format_type_be(enumtypoid))));
460 
461  PG_RETURN_OID(min);
462 }
463 
464 Datum
466 {
467  Oid enumtypoid;
468  Oid max;
469 
470  /*
471  * We rely on being able to get the specific enum type from the calling
472  * expression tree. Notice that the actual value of the argument isn't
473  * examined at all; in particular it might be NULL.
474  */
475  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
476  if (enumtypoid == InvalidOid)
477  ereport(ERROR,
478  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
479  errmsg("could not determine actual enum type")));
480 
481  /* Get the OID using the index */
482  max = enum_endpoint(enumtypoid, BackwardScanDirection);
483 
484  if (!OidIsValid(max))
485  ereport(ERROR,
486  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
487  errmsg("enum %s contains no values",
488  format_type_be(enumtypoid))));
489 
490  PG_RETURN_OID(max);
491 }
492 
493 /* 2-argument variant of enum_range */
494 Datum
496 {
497  Oid lower;
498  Oid upper;
499  Oid enumtypoid;
500 
501  if (PG_ARGISNULL(0))
502  lower = InvalidOid;
503  else
504  lower = PG_GETARG_OID(0);
505  if (PG_ARGISNULL(1))
506  upper = InvalidOid;
507  else
508  upper = PG_GETARG_OID(1);
509 
510  /*
511  * We rely on being able to get the specific enum type from the calling
512  * expression tree. The generic type mechanism should have ensured that
513  * both are of the same type.
514  */
515  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
516  if (enumtypoid == InvalidOid)
517  ereport(ERROR,
518  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
519  errmsg("could not determine actual enum type")));
520 
522 }
523 
524 /* 1-argument variant of enum_range */
525 Datum
527 {
528  Oid enumtypoid;
529 
530  /*
531  * We rely on being able to get the specific enum type from the calling
532  * expression tree. Notice that the actual value of the argument isn't
533  * examined at all; in particular it might be NULL.
534  */
535  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
536  if (enumtypoid == InvalidOid)
537  ereport(ERROR,
538  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
539  errmsg("could not determine actual enum type")));
540 
543 }
544 
545 static ArrayType *
547 {
548  ArrayType *result;
549  Relation enum_rel;
550  Relation enum_idx;
551  SysScanDesc enum_scan;
552  HeapTuple enum_tuple;
553  ScanKeyData skey;
554  Datum *elems;
555  int max,
556  cnt;
557  bool left_found;
558 
559  /*
560  * Scan the enum members in order using pg_enum_typid_sortorder_index.
561  * Note we must not use the syscache. See comments for RenumberEnumType
562  * in catalog/pg_enum.c for more info.
563  */
564  ScanKeyInit(&skey,
565  Anum_pg_enum_enumtypid,
566  BTEqualStrategyNumber, F_OIDEQ,
567  ObjectIdGetDatum(enumtypoid));
568 
569  enum_rel = table_open(EnumRelationId, AccessShareLock);
570  enum_idx = index_open(EnumTypIdSortOrderIndexId, AccessShareLock);
571  enum_scan = systable_beginscan_ordered(enum_rel, enum_idx, NULL, 1, &skey);
572 
573  max = 64;
574  elems = (Datum *) palloc(max * sizeof(Datum));
575  cnt = 0;
576  left_found = !OidIsValid(lower);
577 
578  while (HeapTupleIsValid(enum_tuple = systable_getnext_ordered(enum_scan, ForwardScanDirection)))
579  {
580  Oid enum_oid = ((Form_pg_enum) GETSTRUCT(enum_tuple))->oid;
581 
582  if (!left_found && lower == enum_oid)
583  left_found = true;
584 
585  if (left_found)
586  {
587  /* check it's safe to use in SQL */
588  check_safe_enum_use(enum_tuple);
589 
590  if (cnt >= max)
591  {
592  max *= 2;
593  elems = (Datum *) repalloc(elems, max * sizeof(Datum));
594  }
595 
596  elems[cnt++] = ObjectIdGetDatum(enum_oid);
597  }
598 
599  if (OidIsValid(upper) && upper == enum_oid)
600  break;
601  }
602 
603  systable_endscan_ordered(enum_scan);
604  index_close(enum_idx, AccessShareLock);
605  table_close(enum_rel, AccessShareLock);
606 
607  /* and build the result array */
608  /* note this hardwires some details about the representation of Oid */
609  result = construct_array(elems, cnt, enumtypoid,
610  sizeof(Oid), true, TYPALIGN_INT);
611 
612  pfree(elems);
613 
614  return result;
615 }
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:265
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3354
#define NameStr(name)
Definition: c.h:733
uint32 TransactionId
Definition: c.h:639
#define OidIsValid(objectId)
Definition: c.h:762
int errhint(const char *fmt,...)
Definition: elog.c:1319
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ereturn(context, dummy_value,...)
Definition: elog.h:276
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
Datum enum_range_all(PG_FUNCTION_ARGS)
Definition: enum.c:526
Datum enum_last(PG_FUNCTION_ARGS)
Definition: enum.c:465
static void check_safe_enum_use(HeapTuple enumval_tup)
Definition: enum.c:62
Datum enum_gt(PG_FUNCTION_ARGS)
Definition: enum.c:350
Datum enum_first(PG_FUNCTION_ARGS)
Definition: enum.c:436
static Oid enum_endpoint(Oid enumtypoid, ScanDirection direction)
Definition: enum.c:391
Datum enum_smaller(PG_FUNCTION_ARGS)
Definition: enum.c:359
Datum enum_lt(PG_FUNCTION_ARGS)
Definition: enum.c:305
Datum enum_cmp(PG_FUNCTION_ARGS)
Definition: enum.c:377
Datum enum_eq(PG_FUNCTION_ARGS)
Definition: enum.c:323
Datum enum_range_bounds(PG_FUNCTION_ARGS)
Definition: enum.c:495
Datum enum_send(PG_FUNCTION_ARGS)
Definition: enum.c:220
static ArrayType * enum_range_internal(Oid enumtypoid, Oid lower, Oid upper)
Definition: enum.c:546
Datum enum_ge(PG_FUNCTION_ARGS)
Definition: enum.c:341
Datum enum_in(PG_FUNCTION_ARGS)
Definition: enum.c:108
Datum enum_recv(PG_FUNCTION_ARGS)
Definition: enum.c:178
static int enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo fcinfo)
Definition: enum.c:251
Datum enum_out(PG_FUNCTION_ARGS)
Definition: enum.c:154
Datum enum_larger(PG_FUNCTION_ARGS)
Definition: enum.c:368
Datum enum_le(PG_FUNCTION_ARGS)
Definition: enum.c:314
Datum enum_ne(PG_FUNCTION_ARGS)
Definition: enum.c:332
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1910
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_RETURN_OID(x)
Definition: fmgr.h:360
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
SysScanDesc systable_beginscan_ordered(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:643
void systable_endscan_ordered(SysScanDesc sysscan)
Definition: genam.c:735
HeapTuple systable_getnext_ordered(SysScanDesc sysscan, ScanDirection direction)
Definition: genam.c:710
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:309
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:320
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:177
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:133
int b
Definition: isn.c:70
int a
Definition: isn.c:69
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
Assert(fmt[strlen(fmt) - 1] !='\n')
#define AccessShareLock
Definition: lockdefs.h:36
char * pstrdup(const char *in)
Definition: mcxt.c:1576
void pfree(void *pointer)
Definition: mcxt.c:1401
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1421
void * palloc(Size size)
Definition: mcxt.c:1197
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:49
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:80
#define NAMEDATALEN
bool EnumUncommitted(Oid enum_id)
Definition: pg_enum.c:620
FormData_pg_enum * Form_pg_enum
Definition: pg_enum.h:44
static char * buf
Definition: pg_test_fsync.c:73
uintptr_t Datum
Definition: postgres.h:64
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:172
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:546
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:1390
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
ScanDirection
Definition: sdir.h:25
@ BackwardScanDirection
Definition: sdir.h:26
@ ForwardScanDirection
Definition: sdir.h:28
#define BTEqualStrategyNumber
Definition: stratnum.h:31
StringInfoData * StringInfo
Definition: stringinfo.h:54
void * fn_extra
Definition: fmgr.h:64
FmgrInfo * flinfo
Definition: fmgr.h:87
HeapTupleHeader t_data
Definition: htup.h:68
Definition: nodes.h:129
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:229
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:126
int compare_values_of_enum(TypeCacheEntry *tcache, Oid arg1, Oid arg2)
Definition: typcache.c:2477
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:346
const char * name