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 also allowed if the enum type
53  * is known to have been created earlier in the same transaction. (Note that
54  * we have to track that explicitly; comparing tuple xmins is insufficient,
55  * because the type tuple might have been updated in the current transaction.
56  * Subtransactions also create hazards to be accounted for; currently,
57  * pg_enum.c only handles ADD VALUE at the outermost transaction level.)
58  *
59  * This function needs to be called (directly or indirectly) in any of the
60  * functions below that could return an enum value to SQL operations.
61  */
62 static void
64 {
65  TransactionId xmin;
66  Form_pg_enum en = (Form_pg_enum) GETSTRUCT(enumval_tup);
67 
68  /*
69  * If the row is hinted as committed, it's surely safe. This provides a
70  * fast path for all normal use-cases.
71  */
72  if (HeapTupleHeaderXminCommitted(enumval_tup->t_data))
73  return;
74 
75  /*
76  * Usually, a row would get hinted as committed when it's read or loaded
77  * into syscache; but just in case not, let's check the xmin directly.
78  */
79  xmin = HeapTupleHeaderGetXmin(enumval_tup->t_data);
80  if (!TransactionIdIsInProgress(xmin) &&
82  return;
83 
84  /*
85  * Check if the enum value is listed as uncommitted. If not, it's safe,
86  * because it can't be shorter-lived than its owning type. (This'd also
87  * be false for values made by other transactions; but the previous tests
88  * should have handled all of those.)
89  */
90  if (!EnumUncommitted(en->oid))
91  return;
92 
93  /*
94  * There might well be other tests we could do here to narrow down the
95  * unsafe conditions, but for now just raise an exception.
96  */
97  ereport(ERROR,
98  (errcode(ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE),
99  errmsg("unsafe use of new value \"%s\" of enum type %s",
100  NameStr(en->enumlabel),
101  format_type_be(en->enumtypid)),
102  errhint("New enum values must be committed before they can be used.")));
103 }
104 
105 
106 /* Basic I/O support */
107 
108 Datum
110 {
111  char *name = PG_GETARG_CSTRING(0);
112  Oid enumtypoid = PG_GETARG_OID(1);
113  Node *escontext = fcinfo->context;
114  Oid enumoid;
115  HeapTuple tup;
116 
117  /* must check length to prevent Assert failure within SearchSysCache */
118  if (strlen(name) >= NAMEDATALEN)
119  ereturn(escontext, (Datum) 0,
120  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
121  errmsg("invalid input value for enum %s: \"%s\"",
122  format_type_be(enumtypoid),
123  name)));
124 
125  tup = SearchSysCache2(ENUMTYPOIDNAME,
126  ObjectIdGetDatum(enumtypoid),
128  if (!HeapTupleIsValid(tup))
129  ereturn(escontext, (Datum) 0,
130  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
131  errmsg("invalid input value for enum %s: \"%s\"",
132  format_type_be(enumtypoid),
133  name)));
134 
135  /*
136  * Check it's safe to use in SQL. Perhaps we should take the trouble to
137  * report "unsafe use" softly; but it's unclear that it's worth the
138  * trouble, or indeed that that is a legitimate bad-input case at all
139  * rather than an implementation shortcoming.
140  */
141  check_safe_enum_use(tup);
142 
143  /*
144  * This comes from pg_enum.oid and stores system oids in user tables. This
145  * oid must be preserved by binary upgrades.
146  */
147  enumoid = ((Form_pg_enum) GETSTRUCT(tup))->oid;
148 
149  ReleaseSysCache(tup);
150 
151  PG_RETURN_OID(enumoid);
152 }
153 
154 Datum
156 {
157  Oid enumval = PG_GETARG_OID(0);
158  char *result;
159  HeapTuple tup;
160  Form_pg_enum en;
161 
162  tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(enumval));
163  if (!HeapTupleIsValid(tup))
164  ereport(ERROR,
165  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
166  errmsg("invalid internal value for enum: %u",
167  enumval)));
168  en = (Form_pg_enum) GETSTRUCT(tup);
169 
170  result = pstrdup(NameStr(en->enumlabel));
171 
172  ReleaseSysCache(tup);
173 
174  PG_RETURN_CSTRING(result);
175 }
176 
177 /* Binary I/O support */
178 Datum
180 {
182  Oid enumtypoid = PG_GETARG_OID(1);
183  Oid enumoid;
184  HeapTuple tup;
185  char *name;
186  int nbytes;
187 
188  name = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
189 
190  /* must check length to prevent Assert failure within SearchSysCache */
191  if (strlen(name) >= NAMEDATALEN)
192  ereport(ERROR,
193  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
194  errmsg("invalid input value for enum %s: \"%s\"",
195  format_type_be(enumtypoid),
196  name)));
197 
198  tup = SearchSysCache2(ENUMTYPOIDNAME,
199  ObjectIdGetDatum(enumtypoid),
201  if (!HeapTupleIsValid(tup))
202  ereport(ERROR,
203  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
204  errmsg("invalid input value for enum %s: \"%s\"",
205  format_type_be(enumtypoid),
206  name)));
207 
208  /* check it's safe to use in SQL */
209  check_safe_enum_use(tup);
210 
211  enumoid = ((Form_pg_enum) GETSTRUCT(tup))->oid;
212 
213  ReleaseSysCache(tup);
214 
215  pfree(name);
216 
217  PG_RETURN_OID(enumoid);
218 }
219 
220 Datum
222 {
223  Oid enumval = PG_GETARG_OID(0);
225  HeapTuple tup;
226  Form_pg_enum en;
227 
228  tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(enumval));
229  if (!HeapTupleIsValid(tup))
230  ereport(ERROR,
231  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
232  errmsg("invalid internal value for enum: %u",
233  enumval)));
234  en = (Form_pg_enum) GETSTRUCT(tup);
235 
237  pq_sendtext(&buf, NameStr(en->enumlabel), strlen(NameStr(en->enumlabel)));
238 
239  ReleaseSysCache(tup);
240 
242 }
243 
244 /* Comparison functions and related */
245 
246 /*
247  * enum_cmp_internal is the common engine for all the visible comparison
248  * functions, except for enum_eq and enum_ne which can just check for OID
249  * equality directly.
250  */
251 static int
253 {
254  TypeCacheEntry *tcache;
255 
256  /*
257  * We don't need the typcache except in the hopefully-uncommon case that
258  * one or both Oids are odd. This means that cursory testing of code that
259  * fails to pass flinfo to an enum comparison function might not disclose
260  * the oversight. To make such errors more obvious, Assert that we have a
261  * place to cache even when we take a fast-path exit.
262  */
263  Assert(fcinfo->flinfo != NULL);
264 
265  /* Equal OIDs are equal no matter what */
266  if (arg1 == arg2)
267  return 0;
268 
269  /* Fast path: even-numbered Oids are known to compare correctly */
270  if ((arg1 & 1) == 0 && (arg2 & 1) == 0)
271  {
272  if (arg1 < arg2)
273  return -1;
274  else
275  return 1;
276  }
277 
278  /* Locate the typcache entry for the enum type */
279  tcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
280  if (tcache == NULL)
281  {
282  HeapTuple enum_tup;
283  Form_pg_enum en;
284  Oid typeoid;
285 
286  /* Get the OID of the enum type containing arg1 */
287  enum_tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(arg1));
288  if (!HeapTupleIsValid(enum_tup))
289  ereport(ERROR,
290  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
291  errmsg("invalid internal value for enum: %u",
292  arg1)));
293  en = (Form_pg_enum) GETSTRUCT(enum_tup);
294  typeoid = en->enumtypid;
295  ReleaseSysCache(enum_tup);
296  /* Now locate and remember the typcache entry */
297  tcache = lookup_type_cache(typeoid, 0);
298  fcinfo->flinfo->fn_extra = (void *) tcache;
299  }
300 
301  /* The remaining comparison logic is in typcache.c */
302  return compare_values_of_enum(tcache, arg1, arg2);
303 }
304 
305 Datum
307 {
308  Oid a = PG_GETARG_OID(0);
309  Oid b = PG_GETARG_OID(1);
310 
311  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) < 0);
312 }
313 
314 Datum
316 {
317  Oid a = PG_GETARG_OID(0);
318  Oid b = PG_GETARG_OID(1);
319 
320  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) <= 0);
321 }
322 
323 Datum
325 {
326  Oid a = PG_GETARG_OID(0);
327  Oid b = PG_GETARG_OID(1);
328 
329  PG_RETURN_BOOL(a == b);
330 }
331 
332 Datum
334 {
335  Oid a = PG_GETARG_OID(0);
336  Oid b = PG_GETARG_OID(1);
337 
338  PG_RETURN_BOOL(a != b);
339 }
340 
341 Datum
343 {
344  Oid a = PG_GETARG_OID(0);
345  Oid b = PG_GETARG_OID(1);
346 
347  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) >= 0);
348 }
349 
350 Datum
352 {
353  Oid a = PG_GETARG_OID(0);
354  Oid b = PG_GETARG_OID(1);
355 
356  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) > 0);
357 }
358 
359 Datum
361 {
362  Oid a = PG_GETARG_OID(0);
363  Oid b = PG_GETARG_OID(1);
364 
365  PG_RETURN_OID(enum_cmp_internal(a, b, fcinfo) < 0 ? a : b);
366 }
367 
368 Datum
370 {
371  Oid a = PG_GETARG_OID(0);
372  Oid b = PG_GETARG_OID(1);
373 
374  PG_RETURN_OID(enum_cmp_internal(a, b, fcinfo) > 0 ? a : b);
375 }
376 
377 Datum
379 {
380  Oid a = PG_GETARG_OID(0);
381  Oid b = PG_GETARG_OID(1);
382 
384 }
385 
386 /* Enum programming support functions */
387 
388 /*
389  * enum_endpoint: common code for enum_first/enum_last
390  */
391 static Oid
392 enum_endpoint(Oid enumtypoid, ScanDirection direction)
393 {
394  Relation enum_rel;
395  Relation enum_idx;
396  SysScanDesc enum_scan;
397  HeapTuple enum_tuple;
398  ScanKeyData skey;
399  Oid minmax;
400 
401  /*
402  * Find the first/last enum member using pg_enum_typid_sortorder_index.
403  * Note we must not use the syscache. See comments for RenumberEnumType
404  * in catalog/pg_enum.c for more info.
405  */
406  ScanKeyInit(&skey,
407  Anum_pg_enum_enumtypid,
408  BTEqualStrategyNumber, F_OIDEQ,
409  ObjectIdGetDatum(enumtypoid));
410 
411  enum_rel = table_open(EnumRelationId, AccessShareLock);
412  enum_idx = index_open(EnumTypIdSortOrderIndexId, AccessShareLock);
413  enum_scan = systable_beginscan_ordered(enum_rel, enum_idx, NULL,
414  1, &skey);
415 
416  enum_tuple = systable_getnext_ordered(enum_scan, direction);
417  if (HeapTupleIsValid(enum_tuple))
418  {
419  /* check it's safe to use in SQL */
420  check_safe_enum_use(enum_tuple);
421  minmax = ((Form_pg_enum) GETSTRUCT(enum_tuple))->oid;
422  }
423  else
424  {
425  /* should only happen with an empty enum */
426  minmax = InvalidOid;
427  }
428 
429  systable_endscan_ordered(enum_scan);
430  index_close(enum_idx, AccessShareLock);
431  table_close(enum_rel, AccessShareLock);
432 
433  return minmax;
434 }
435 
436 Datum
438 {
439  Oid enumtypoid;
440  Oid min;
441 
442  /*
443  * We rely on being able to get the specific enum type from the calling
444  * expression tree. Notice that the actual value of the argument isn't
445  * examined at all; in particular it might be NULL.
446  */
447  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
448  if (enumtypoid == InvalidOid)
449  ereport(ERROR,
450  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
451  errmsg("could not determine actual enum type")));
452 
453  /* Get the OID using the index */
454  min = enum_endpoint(enumtypoid, ForwardScanDirection);
455 
456  if (!OidIsValid(min))
457  ereport(ERROR,
458  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
459  errmsg("enum %s contains no values",
460  format_type_be(enumtypoid))));
461 
462  PG_RETURN_OID(min);
463 }
464 
465 Datum
467 {
468  Oid enumtypoid;
469  Oid max;
470 
471  /*
472  * We rely on being able to get the specific enum type from the calling
473  * expression tree. Notice that the actual value of the argument isn't
474  * examined at all; in particular it might be NULL.
475  */
476  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
477  if (enumtypoid == InvalidOid)
478  ereport(ERROR,
479  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
480  errmsg("could not determine actual enum type")));
481 
482  /* Get the OID using the index */
483  max = enum_endpoint(enumtypoid, BackwardScanDirection);
484 
485  if (!OidIsValid(max))
486  ereport(ERROR,
487  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
488  errmsg("enum %s contains no values",
489  format_type_be(enumtypoid))));
490 
491  PG_RETURN_OID(max);
492 }
493 
494 /* 2-argument variant of enum_range */
495 Datum
497 {
498  Oid lower;
499  Oid upper;
500  Oid enumtypoid;
501 
502  if (PG_ARGISNULL(0))
503  lower = InvalidOid;
504  else
505  lower = PG_GETARG_OID(0);
506  if (PG_ARGISNULL(1))
507  upper = InvalidOid;
508  else
509  upper = PG_GETARG_OID(1);
510 
511  /*
512  * We rely on being able to get the specific enum type from the calling
513  * expression tree. The generic type mechanism should have ensured that
514  * both are of the same type.
515  */
516  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
517  if (enumtypoid == InvalidOid)
518  ereport(ERROR,
519  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
520  errmsg("could not determine actual enum type")));
521 
523 }
524 
525 /* 1-argument variant of enum_range */
526 Datum
528 {
529  Oid enumtypoid;
530 
531  /*
532  * We rely on being able to get the specific enum type from the calling
533  * expression tree. Notice that the actual value of the argument isn't
534  * examined at all; in particular it might be NULL.
535  */
536  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
537  if (enumtypoid == InvalidOid)
538  ereport(ERROR,
539  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
540  errmsg("could not determine actual enum type")));
541 
544 }
545 
546 static ArrayType *
548 {
549  ArrayType *result;
550  Relation enum_rel;
551  Relation enum_idx;
552  SysScanDesc enum_scan;
553  HeapTuple enum_tuple;
554  ScanKeyData skey;
555  Datum *elems;
556  int max,
557  cnt;
558  bool left_found;
559 
560  /*
561  * Scan the enum members in order using pg_enum_typid_sortorder_index.
562  * Note we must not use the syscache. See comments for RenumberEnumType
563  * in catalog/pg_enum.c for more info.
564  */
565  ScanKeyInit(&skey,
566  Anum_pg_enum_enumtypid,
567  BTEqualStrategyNumber, F_OIDEQ,
568  ObjectIdGetDatum(enumtypoid));
569 
570  enum_rel = table_open(EnumRelationId, AccessShareLock);
571  enum_idx = index_open(EnumTypIdSortOrderIndexId, AccessShareLock);
572  enum_scan = systable_beginscan_ordered(enum_rel, enum_idx, NULL, 1, &skey);
573 
574  max = 64;
575  elems = (Datum *) palloc(max * sizeof(Datum));
576  cnt = 0;
577  left_found = !OidIsValid(lower);
578 
579  while (HeapTupleIsValid(enum_tuple = systable_getnext_ordered(enum_scan, ForwardScanDirection)))
580  {
581  Oid enum_oid = ((Form_pg_enum) GETSTRUCT(enum_tuple))->oid;
582 
583  if (!left_found && lower == enum_oid)
584  left_found = true;
585 
586  if (left_found)
587  {
588  /* check it's safe to use in SQL */
589  check_safe_enum_use(enum_tuple);
590 
591  if (cnt >= max)
592  {
593  max *= 2;
594  elems = (Datum *) repalloc(elems, max * sizeof(Datum));
595  }
596 
597  elems[cnt++] = ObjectIdGetDatum(enum_oid);
598  }
599 
600  if (OidIsValid(upper) && upper == enum_oid)
601  break;
602  }
603 
604  systable_endscan_ordered(enum_scan);
605  index_close(enum_idx, AccessShareLock);
606  table_close(enum_rel, AccessShareLock);
607 
608  /* and build the result array */
609  /* note this hardwires some details about the representation of Oid */
610  result = construct_array(elems, cnt, enumtypoid,
611  sizeof(Oid), true, TYPALIGN_INT);
612 
613  pfree(elems);
614 
615  return result;
616 }
#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:746
#define Assert(condition)
Definition: c.h:858
uint32 TransactionId
Definition: c.h:652
#define OidIsValid(objectId)
Definition: c.h:775
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:527
Datum enum_last(PG_FUNCTION_ARGS)
Definition: enum.c:466
static void check_safe_enum_use(HeapTuple enumval_tup)
Definition: enum.c:63
Datum enum_gt(PG_FUNCTION_ARGS)
Definition: enum.c:351
Datum enum_first(PG_FUNCTION_ARGS)
Definition: enum.c:437
static Oid enum_endpoint(Oid enumtypoid, ScanDirection direction)
Definition: enum.c:392
Datum enum_smaller(PG_FUNCTION_ARGS)
Definition: enum.c:360
Datum enum_lt(PG_FUNCTION_ARGS)
Definition: enum.c:306
Datum enum_cmp(PG_FUNCTION_ARGS)
Definition: enum.c:378
Datum enum_eq(PG_FUNCTION_ARGS)
Definition: enum.c:324
Datum enum_range_bounds(PG_FUNCTION_ARGS)
Definition: enum.c:496
Datum enum_send(PG_FUNCTION_ARGS)
Definition: enum.c:221
static ArrayType * enum_range_internal(Oid enumtypoid, Oid lower, Oid upper)
Definition: enum.c:547
Datum enum_ge(PG_FUNCTION_ARGS)
Definition: enum.c:342
Datum enum_in(PG_FUNCTION_ARGS)
Definition: enum.c:109
Datum enum_recv(PG_FUNCTION_ARGS)
Definition: enum.c:179
static int enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo fcinfo)
Definition: enum.c:252
Datum enum_out(PG_FUNCTION_ARGS)
Definition: enum.c:155
Datum enum_larger(PG_FUNCTION_ARGS)
Definition: enum.c:369
Datum enum_le(PG_FUNCTION_ARGS)
Definition: enum.c:315
Datum enum_ne(PG_FUNCTION_ARGS)
Definition: enum.c:333
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
#define AccessShareLock
Definition: lockdefs.h:36
char * pstrdup(const char *in)
Definition: mcxt.c:1695
void pfree(void *pointer)
Definition: mcxt.c:1520
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1540
void * palloc(Size size)
Definition: mcxt.c:1316
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:708
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