PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
enum.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "catalog/indexing.h"
#include "catalog/pg_enum.h"
#include "libpq/pqformat.h"
#include "storage/procarray.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
#include "utils/typcache.h"
Include dependency graph for enum.c:

Go to the source code of this file.

Functions

static Oid enum_endpoint (Oid enumtypoid, ScanDirection direction)
 
static ArrayTypeenum_range_internal (Oid enumtypoid, Oid lower, Oid upper)
 
static void check_safe_enum_use (HeapTuple enumval_tup)
 
Datum enum_in (PG_FUNCTION_ARGS)
 
Datum enum_out (PG_FUNCTION_ARGS)
 
Datum enum_recv (PG_FUNCTION_ARGS)
 
Datum enum_send (PG_FUNCTION_ARGS)
 
static int enum_cmp_internal (Oid arg1, Oid arg2, FunctionCallInfo fcinfo)
 
Datum enum_lt (PG_FUNCTION_ARGS)
 
Datum enum_le (PG_FUNCTION_ARGS)
 
Datum enum_eq (PG_FUNCTION_ARGS)
 
Datum enum_ne (PG_FUNCTION_ARGS)
 
Datum enum_ge (PG_FUNCTION_ARGS)
 
Datum enum_gt (PG_FUNCTION_ARGS)
 
Datum enum_smaller (PG_FUNCTION_ARGS)
 
Datum enum_larger (PG_FUNCTION_ARGS)
 
Datum enum_cmp (PG_FUNCTION_ARGS)
 
Datum enum_first (PG_FUNCTION_ARGS)
 
Datum enum_last (PG_FUNCTION_ARGS)
 
Datum enum_range_bounds (PG_FUNCTION_ARGS)
 
Datum enum_range_all (PG_FUNCTION_ARGS)
 

Function Documentation

static void check_safe_enum_use ( HeapTuple  enumval_tup)
static

Definition at line 57 of file enum.c.

References elog, ereport, errcode(), errhint(), errmsg(), ERROR, format_type_be(), GETSTRUCT, HEAP_UPDATED, HeapTupleHeaderGetXmin, HeapTupleHeaderXminCommitted, HeapTupleIsValid, NameStr, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, HeapTupleData::t_data, HeapTupleHeaderData::t_infomask, TransactionIdDidCommit(), TransactionIdIsInProgress(), and TYPEOID.

Referenced by enum_endpoint(), enum_in(), enum_range_internal(), and enum_recv().

58 {
59  TransactionId xmin;
60  Form_pg_enum en;
61  HeapTuple enumtyp_tup;
62 
63  /*
64  * If the row is hinted as committed, it's surely safe. This provides a
65  * fast path for all normal use-cases.
66  */
67  if (HeapTupleHeaderXminCommitted(enumval_tup->t_data))
68  return;
69 
70  /*
71  * Usually, a row would get hinted as committed when it's read or loaded
72  * into syscache; but just in case not, let's check the xmin directly.
73  */
74  xmin = HeapTupleHeaderGetXmin(enumval_tup->t_data);
75  if (!TransactionIdIsInProgress(xmin) &&
77  return;
78 
79  /* It is a new enum value, so check to see if the whole enum is new */
80  en = (Form_pg_enum) GETSTRUCT(enumval_tup);
81  enumtyp_tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(en->enumtypid));
82  if (!HeapTupleIsValid(enumtyp_tup))
83  elog(ERROR, "cache lookup failed for type %u", en->enumtypid);
84 
85  /*
86  * We insist that the type have been created in the same (sub)transaction
87  * as the enum value. It would be safe to allow the type's originating
88  * xact to be a subcommitted child of the enum value's xact, but not vice
89  * versa (since we might now be in a subxact of the type's originating
90  * xact, which could roll back along with the enum value's subxact). The
91  * former case seems a sufficiently weird usage pattern as to not be worth
92  * spending code for, so we're left with a simple equality check.
93  *
94  * We also insist that the type's pg_type row not be HEAP_UPDATED. If it
95  * is, we can't tell whether the row was created or only modified in the
96  * apparent originating xact, so it might be older than that xact. (We do
97  * not worry whether the enum value is HEAP_UPDATED; if it is, we might
98  * think it's too new and throw an unnecessary error, but we won't allow
99  * an unsafe case.)
100  */
101  if (xmin == HeapTupleHeaderGetXmin(enumtyp_tup->t_data) &&
102  !(enumtyp_tup->t_data->t_infomask & HEAP_UPDATED))
103  {
104  /* same (sub)transaction, so safe */
105  ReleaseSysCache(enumtyp_tup);
106  return;
107  }
108 
109  /*
110  * There might well be other tests we could do here to narrow down the
111  * unsafe conditions, but for now just raise an exception.
112  */
113  ereport(ERROR,
114  (errcode(ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE),
115  errmsg("unsafe use of new value \"%s\" of enum type %s",
116  NameStr(en->enumlabel),
117  format_type_be(en->enumtypid)),
118  errhint("New enum values must be committed before they can be used.")));
119 }
int errhint(const char *fmt,...)
Definition: elog.c:987
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
uint32 TransactionId
Definition: c.h:391
bool TransactionIdIsInProgress(TransactionId xid)
Definition: procarray.c:999
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
#define HEAP_UPDATED
Definition: htup_details.h:195
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:159
HeapTupleHeader t_data
Definition: htup.h:67
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:318
FormData_pg_enum * Form_pg_enum
Definition: pg_enum.h:46
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:307
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:493
#define elog
Definition: elog.h:219
Datum enum_cmp ( PG_FUNCTION_ARGS  )

Definition at line 388 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_INT32.

Referenced by gbt_enumkey_cmp(), and gin_enum_cmp().

389 {
390  Oid a = PG_GETARG_OID(0);
391  Oid b = PG_GETARG_OID(1);
392 
393  PG_RETURN_INT32(enum_cmp_internal(a, b, fcinfo));
394 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
static int enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo fcinfo)
Definition: enum.c:262
static int enum_cmp_internal ( Oid  arg1,
Oid  arg2,
FunctionCallInfo  fcinfo 
)
static

Definition at line 262 of file enum.c.

References Assert, compare_values_of_enum(), ENUMOID, ereport, errcode(), errmsg(), ERROR, FunctionCallInfoData::flinfo, FmgrInfo::fn_extra, GETSTRUCT, HeapTupleIsValid, lookup_type_cache(), ObjectIdGetDatum, ReleaseSysCache(), and SearchSysCache1.

Referenced by enum_cmp(), enum_ge(), enum_gt(), enum_larger(), enum_le(), enum_lt(), and enum_smaller().

263 {
264  TypeCacheEntry *tcache;
265 
266  /*
267  * We don't need the typcache except in the hopefully-uncommon case that
268  * one or both Oids are odd. This means that cursory testing of code that
269  * fails to pass flinfo to an enum comparison function might not disclose
270  * the oversight. To make such errors more obvious, Assert that we have a
271  * place to cache even when we take a fast-path exit.
272  */
273  Assert(fcinfo->flinfo != NULL);
274 
275  /* Equal OIDs are equal no matter what */
276  if (arg1 == arg2)
277  return 0;
278 
279  /* Fast path: even-numbered Oids are known to compare correctly */
280  if ((arg1 & 1) == 0 && (arg2 & 1) == 0)
281  {
282  if (arg1 < arg2)
283  return -1;
284  else
285  return 1;
286  }
287 
288  /* Locate the typcache entry for the enum type */
289  tcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
290  if (tcache == NULL)
291  {
292  HeapTuple enum_tup;
293  Form_pg_enum en;
294  Oid typeoid;
295 
296  /* Get the OID of the enum type containing arg1 */
297  enum_tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(arg1));
298  if (!HeapTupleIsValid(enum_tup))
299  ereport(ERROR,
300  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
301  errmsg("invalid internal value for enum: %u",
302  arg1)));
303  en = (Form_pg_enum) GETSTRUCT(enum_tup);
304  typeoid = en->enumtypid;
305  ReleaseSysCache(enum_tup);
306  /* Now locate and remember the typcache entry */
307  tcache = lookup_type_cache(typeoid, 0);
308  fcinfo->flinfo->fn_extra = (void *) tcache;
309  }
310 
311  /* The remaining comparison logic is in typcache.c */
312  return compare_values_of_enum(tcache, arg1, arg2);
313 }
int compare_values_of_enum(TypeCacheEntry *tcache, Oid arg1, Oid arg2)
Definition: typcache.c:1964
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:159
FmgrInfo * flinfo
Definition: fmgr.h:79
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
FormData_pg_enum * Form_pg_enum
Definition: pg_enum.h:46
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:305
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:664
void * fn_extra
Definition: fmgr.h:64
int errmsg(const char *fmt,...)
Definition: elog.c:797
static Oid enum_endpoint ( Oid  enumtypoid,
ScanDirection  direction 
)
static

Definition at line 402 of file enum.c.

References AccessShareLock, Anum_pg_enum_enumtypid, BTEqualStrategyNumber, check_safe_enum_use(), EnumRelationId, EnumTypIdSortOrderIndexId, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, index_close(), index_open(), InvalidOid, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan_ordered(), systable_endscan_ordered(), and systable_getnext_ordered().

Referenced by enum_first(), and enum_last().

403 {
404  Relation enum_rel;
405  Relation enum_idx;
406  SysScanDesc enum_scan;
407  HeapTuple enum_tuple;
408  ScanKeyData skey;
409  Oid minmax;
410 
411  /*
412  * Find the first/last enum member using pg_enum_typid_sortorder_index.
413  * Note we must not use the syscache. See comments for RenumberEnumType
414  * in catalog/pg_enum.c for more info.
415  */
416  ScanKeyInit(&skey,
418  BTEqualStrategyNumber, F_OIDEQ,
419  ObjectIdGetDatum(enumtypoid));
420 
423  enum_scan = systable_beginscan_ordered(enum_rel, enum_idx, NULL,
424  1, &skey);
425 
426  enum_tuple = systable_getnext_ordered(enum_scan, direction);
427  if (HeapTupleIsValid(enum_tuple))
428  {
429  /* check it's safe to use in SQL */
430  check_safe_enum_use(enum_tuple);
431  minmax = HeapTupleGetOid(enum_tuple);
432  }
433  else
434  {
435  /* should only happen with an empty enum */
436  minmax = InvalidOid;
437  }
438 
439  systable_endscan_ordered(enum_scan);
440  index_close(enum_idx, AccessShareLock);
441  heap_close(enum_rel, AccessShareLock);
442 
443  return minmax;
444 }
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
HeapTuple systable_getnext_ordered(SysScanDesc sysscan, ScanDirection direction)
Definition: genam.c:597
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define EnumRelationId
Definition: pg_enum.h:32
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
void systable_endscan_ordered(SysScanDesc sysscan)
Definition: genam.c:614
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
#define Anum_pg_enum_enumtypid
Definition: pg_enum.h:53
SysScanDesc systable_beginscan_ordered(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:533
#define EnumTypIdSortOrderIndexId
Definition: indexing.h:159
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static void check_safe_enum_use(HeapTuple enumval_tup)
Definition: enum.c:57
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
#define BTEqualStrategyNumber
Definition: stratnum.h:31
Datum enum_eq ( PG_FUNCTION_ARGS  )

Definition at line 334 of file enum.c.

References PG_GETARG_OID, and PG_RETURN_BOOL.

335 {
336  Oid a = PG_GETARG_OID(0);
337  Oid b = PG_GETARG_OID(1);
338 
339  PG_RETURN_BOOL(a == b);
340 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
Datum enum_first ( PG_FUNCTION_ARGS  )

Definition at line 447 of file enum.c.

References enum_endpoint(), ereport, errcode(), errmsg(), ERROR, format_type_be(), ForwardScanDirection, get_fn_expr_argtype(), InvalidOid, OidIsValid, and PG_RETURN_OID.

448 {
449  Oid enumtypoid;
450  Oid min;
451 
452  /*
453  * We rely on being able to get the specific enum type from the calling
454  * expression tree. Notice that the actual value of the argument isn't
455  * examined at all; in particular it might be NULL.
456  */
457  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
458  if (enumtypoid == InvalidOid)
459  ereport(ERROR,
460  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
461  errmsg("could not determine actual enum type")));
462 
463  /* Get the OID using the index */
464  min = enum_endpoint(enumtypoid, ForwardScanDirection);
465 
466  if (!OidIsValid(min))
467  ereport(ERROR,
468  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
469  errmsg("enum %s contains no values",
470  format_type_be(enumtypoid))));
471 
472  PG_RETURN_OID(min);
473 }
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1909
static Oid enum_endpoint(Oid enumtypoid, ScanDirection direction)
Definition: enum.c:402
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
Datum enum_ge ( PG_FUNCTION_ARGS  )

Definition at line 352 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_BOOL.

Referenced by gbt_enumge().

353 {
354  Oid a = PG_GETARG_OID(0);
355  Oid b = PG_GETARG_OID(1);
356 
357  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) >= 0);
358 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
static int enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo fcinfo)
Definition: enum.c:262
Datum enum_gt ( PG_FUNCTION_ARGS  )

Definition at line 361 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_BOOL.

Referenced by gbt_enumgt().

362 {
363  Oid a = PG_GETARG_OID(0);
364  Oid b = PG_GETARG_OID(1);
365 
366  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) > 0);
367 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
static int enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo fcinfo)
Definition: enum.c:262
Datum enum_in ( PG_FUNCTION_ARGS  )

Definition at line 125 of file enum.c.

References check_safe_enum_use(), CStringGetDatum, ENUMTYPOIDNAME, ereport, errcode(), errmsg(), ERROR, format_type_be(), HeapTupleGetOid, HeapTupleIsValid, name, NAMEDATALEN, ObjectIdGetDatum, PG_GETARG_CSTRING, PG_GETARG_OID, PG_RETURN_OID, ReleaseSysCache(), and SearchSysCache2.

126 {
127  char *name = PG_GETARG_CSTRING(0);
128  Oid enumtypoid = PG_GETARG_OID(1);
129  Oid enumoid;
130  HeapTuple tup;
131 
132  /* must check length to prevent Assert failure within SearchSysCache */
133  if (strlen(name) >= NAMEDATALEN)
134  ereport(ERROR,
135  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
136  errmsg("invalid input value for enum %s: \"%s\"",
137  format_type_be(enumtypoid),
138  name)));
139 
141  ObjectIdGetDatum(enumtypoid),
142  CStringGetDatum(name));
143  if (!HeapTupleIsValid(tup))
144  ereport(ERROR,
145  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
146  errmsg("invalid input value for enum %s: \"%s\"",
147  format_type_be(enumtypoid),
148  name)));
149 
150  /* check it's safe to use in SQL */
151  check_safe_enum_use(tup);
152 
153  /*
154  * This comes from pg_enum.oid and stores system oids in user tables. This
155  * oid must be preserved by binary upgrades.
156  */
157  enumoid = HeapTupleGetOid(tup);
158 
159  ReleaseSysCache(tup);
160 
161  PG_RETURN_OID(enumoid);
162 }
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
unsigned int Oid
Definition: postgres_ext.h:31
#define NAMEDATALEN
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static void check_safe_enum_use(HeapTuple enumval_tup)
Definition: enum.c:57
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
#define SearchSysCache2(cacheId, key1, key2)
Definition: syscache.h:161
Datum enum_larger ( PG_FUNCTION_ARGS  )

Definition at line 379 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_OID.

380 {
381  Oid a = PG_GETARG_OID(0);
382  Oid b = PG_GETARG_OID(1);
383 
384  PG_RETURN_OID(enum_cmp_internal(a, b, fcinfo) > 0 ? a : b);
385 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
static int enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo fcinfo)
Definition: enum.c:262
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
Datum enum_last ( PG_FUNCTION_ARGS  )

Definition at line 476 of file enum.c.

References BackwardScanDirection, enum_endpoint(), ereport, errcode(), errmsg(), ERROR, format_type_be(), get_fn_expr_argtype(), InvalidOid, OidIsValid, and PG_RETURN_OID.

477 {
478  Oid enumtypoid;
479  Oid max;
480 
481  /*
482  * We rely on being able to get the specific enum type from the calling
483  * expression tree. Notice that the actual value of the argument isn't
484  * examined at all; in particular it might be NULL.
485  */
486  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
487  if (enumtypoid == InvalidOid)
488  ereport(ERROR,
489  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
490  errmsg("could not determine actual enum type")));
491 
492  /* Get the OID using the index */
493  max = enum_endpoint(enumtypoid, BackwardScanDirection);
494 
495  if (!OidIsValid(max))
496  ereport(ERROR,
497  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
498  errmsg("enum %s contains no values",
499  format_type_be(enumtypoid))));
500 
501  PG_RETURN_OID(max);
502 }
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1909
static Oid enum_endpoint(Oid enumtypoid, ScanDirection direction)
Definition: enum.c:402
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
Datum enum_le ( PG_FUNCTION_ARGS  )

Definition at line 325 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_BOOL.

Referenced by gbt_enumle().

326 {
327  Oid a = PG_GETARG_OID(0);
328  Oid b = PG_GETARG_OID(1);
329 
330  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) <= 0);
331 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
static int enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo fcinfo)
Definition: enum.c:262
Datum enum_lt ( PG_FUNCTION_ARGS  )

Definition at line 316 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_BOOL.

Referenced by gbt_enumlt().

317 {
318  Oid a = PG_GETARG_OID(0);
319  Oid b = PG_GETARG_OID(1);
320 
321  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) < 0);
322 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
static int enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo fcinfo)
Definition: enum.c:262
Datum enum_ne ( PG_FUNCTION_ARGS  )

Definition at line 343 of file enum.c.

References PG_GETARG_OID, and PG_RETURN_BOOL.

344 {
345  Oid a = PG_GETARG_OID(0);
346  Oid b = PG_GETARG_OID(1);
347 
348  PG_RETURN_BOOL(a != b);
349 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
Datum enum_out ( PG_FUNCTION_ARGS  )

Definition at line 165 of file enum.c.

References ENUMOID, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_CSTRING, pstrdup(), ReleaseSysCache(), result, and SearchSysCache1.

Referenced by anyenum_out().

166 {
167  Oid enumval = PG_GETARG_OID(0);
168  char *result;
169  HeapTuple tup;
170  Form_pg_enum en;
171 
172  tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(enumval));
173  if (!HeapTupleIsValid(tup))
174  ereport(ERROR,
175  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
176  errmsg("invalid internal value for enum: %u",
177  enumval)));
178  en = (Form_pg_enum) GETSTRUCT(tup);
179 
180  result = pstrdup(NameStr(en->enumlabel));
181 
182  ReleaseSysCache(tup);
183 
184  PG_RETURN_CSTRING(result);
185 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
char * pstrdup(const char *in)
Definition: mcxt.c:1076
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1633
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:159
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
FormData_pg_enum * Form_pg_enum
Definition: pg_enum.h:46
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:493
Datum enum_range_all ( PG_FUNCTION_ARGS  )

Definition at line 537 of file enum.c.

References enum_range_internal(), ereport, errcode(), errmsg(), ERROR, get_fn_expr_argtype(), InvalidOid, and PG_RETURN_ARRAYTYPE_P.

538 {
539  Oid enumtypoid;
540 
541  /*
542  * We rely on being able to get the specific enum type from the calling
543  * expression tree. Notice that the actual value of the argument isn't
544  * examined at all; in particular it might be NULL.
545  */
546  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
547  if (enumtypoid == InvalidOid)
548  ereport(ERROR,
549  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
550  errmsg("could not determine actual enum type")));
551 
554 }
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
static ArrayType * enum_range_internal(Oid enumtypoid, Oid lower, Oid upper)
Definition: enum.c:557
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1909
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:246
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797
Datum enum_range_bounds ( PG_FUNCTION_ARGS  )

Definition at line 506 of file enum.c.

References enum_range_internal(), ereport, errcode(), errmsg(), ERROR, get_fn_expr_argtype(), InvalidOid, lower(), PG_ARGISNULL, PG_GETARG_OID, PG_RETURN_ARRAYTYPE_P, and upper().

507 {
508  Oid lower;
509  Oid upper;
510  Oid enumtypoid;
511 
512  if (PG_ARGISNULL(0))
513  lower = InvalidOid;
514  else
515  lower = PG_GETARG_OID(0);
516  if (PG_ARGISNULL(1))
517  upper = InvalidOid;
518  else
519  upper = PG_GETARG_OID(1);
520 
521  /*
522  * We rely on being able to get the specific enum type from the calling
523  * expression tree. The generic type mechanism should have ensured that
524  * both are of the same type.
525  */
526  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
527  if (enumtypoid == InvalidOid)
528  ereport(ERROR,
529  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
530  errmsg("could not determine actual enum type")));
531 
532  PG_RETURN_ARRAYTYPE_P(enum_range_internal(enumtypoid, lower, upper));
533 }
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
int errcode(int sqlerrcode)
Definition: elog.c:575
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
unsigned int Oid
Definition: postgres_ext.h:31
static ArrayType * enum_range_internal(Oid enumtypoid, Oid lower, Oid upper)
Definition: enum.c:557
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1909
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:246
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
int errmsg(const char *fmt,...)
Definition: elog.c:797
static ArrayType * enum_range_internal ( Oid  enumtypoid,
Oid  lower,
Oid  upper 
)
static

Definition at line 557 of file enum.c.

References AccessShareLock, Anum_pg_enum_enumtypid, BTEqualStrategyNumber, check_safe_enum_use(), construct_array(), EnumRelationId, EnumTypIdSortOrderIndexId, ForwardScanDirection, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, index_close(), index_open(), ObjectIdGetDatum, OidIsValid, palloc(), pfree(), repalloc(), result, ScanKeyInit(), systable_beginscan_ordered(), systable_endscan_ordered(), and systable_getnext_ordered().

Referenced by enum_range_all(), and enum_range_bounds().

558 {
559  ArrayType *result;
560  Relation enum_rel;
561  Relation enum_idx;
562  SysScanDesc enum_scan;
563  HeapTuple enum_tuple;
564  ScanKeyData skey;
565  Datum *elems;
566  int max,
567  cnt;
568  bool left_found;
569 
570  /*
571  * Scan the enum members in order using pg_enum_typid_sortorder_index.
572  * Note we must not use the syscache. See comments for RenumberEnumType
573  * in catalog/pg_enum.c for more info.
574  */
575  ScanKeyInit(&skey,
577  BTEqualStrategyNumber, F_OIDEQ,
578  ObjectIdGetDatum(enumtypoid));
579 
582  enum_scan = systable_beginscan_ordered(enum_rel, enum_idx, NULL, 1, &skey);
583 
584  max = 64;
585  elems = (Datum *) palloc(max * sizeof(Datum));
586  cnt = 0;
587  left_found = !OidIsValid(lower);
588 
589  while (HeapTupleIsValid(enum_tuple = systable_getnext_ordered(enum_scan, ForwardScanDirection)))
590  {
591  Oid enum_oid = HeapTupleGetOid(enum_tuple);
592 
593  if (!left_found && lower == enum_oid)
594  left_found = true;
595 
596  if (left_found)
597  {
598  /* check it's safe to use in SQL */
599  check_safe_enum_use(enum_tuple);
600 
601  if (cnt >= max)
602  {
603  max *= 2;
604  elems = (Datum *) repalloc(elems, max * sizeof(Datum));
605  }
606 
607  elems[cnt++] = ObjectIdGetDatum(enum_oid);
608  }
609 
610  if (OidIsValid(upper) && upper == enum_oid)
611  break;
612  }
613 
614  systable_endscan_ordered(enum_scan);
615  index_close(enum_idx, AccessShareLock);
616  heap_close(enum_rel, AccessShareLock);
617 
618  /* and build the result array */
619  /* note this hardwires some details about the representation of Oid */
620  result = construct_array(elems, cnt, enumtypoid, sizeof(Oid), true, 'i');
621 
622  pfree(elems);
623 
624  return result;
625 }
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3307
#define AccessShareLock
Definition: lockdefs.h:36
return result
Definition: formatting.c:1633
#define heap_close(r, l)
Definition: heapam.h:97
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
HeapTuple systable_getnext_ordered(SysScanDesc sysscan, ScanDirection direction)
Definition: genam.c:597
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
void pfree(void *pointer)
Definition: mcxt.c:949
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define EnumRelationId
Definition: pg_enum.h:32
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
void systable_endscan_ordered(SysScanDesc sysscan)
Definition: genam.c:614
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:962
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
#define Anum_pg_enum_enumtypid
Definition: pg_enum.h:53
void * palloc(Size size)
Definition: mcxt.c:848
SysScanDesc systable_beginscan_ordered(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:533
#define EnumTypIdSortOrderIndexId
Definition: indexing.h:159
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static void check_safe_enum_use(HeapTuple enumval_tup)
Definition: enum.c:57
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
#define BTEqualStrategyNumber
Definition: stratnum.h:31
Datum enum_recv ( PG_FUNCTION_ARGS  )

Definition at line 189 of file enum.c.

References buf, check_safe_enum_use(), CStringGetDatum, StringInfoData::cursor, ENUMTYPOIDNAME, ereport, errcode(), errmsg(), ERROR, format_type_be(), HeapTupleGetOid, HeapTupleIsValid, StringInfoData::len, name, NAMEDATALEN, ObjectIdGetDatum, pfree(), PG_GETARG_OID, PG_GETARG_POINTER, PG_RETURN_OID, pq_getmsgtext(), ReleaseSysCache(), and SearchSysCache2.

190 {
192  Oid enumtypoid = PG_GETARG_OID(1);
193  Oid enumoid;
194  HeapTuple tup;
195  char *name;
196  int nbytes;
197 
198  name = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
199 
200  /* must check length to prevent Assert failure within SearchSysCache */
201  if (strlen(name) >= NAMEDATALEN)
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 
209  ObjectIdGetDatum(enumtypoid),
210  CStringGetDatum(name));
211  if (!HeapTupleIsValid(tup))
212  ereport(ERROR,
213  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
214  errmsg("invalid input value for enum %s: \"%s\"",
215  format_type_be(enumtypoid),
216  name)));
217 
218  /* check it's safe to use in SQL */
219  check_safe_enum_use(tup);
220 
221  enumoid = HeapTupleGetOid(tup);
222 
223  ReleaseSysCache(tup);
224 
225  pfree(name);
226 
227  PG_RETURN_OID(enumoid);
228 }
StringInfoData * StringInfo
Definition: stringinfo.h:43
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
unsigned int Oid
Definition: postgres_ext.h:31
#define NAMEDATALEN
void pfree(void *pointer)
Definition: mcxt.c:949
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:67
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:588
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
static void check_safe_enum_use(HeapTuple enumval_tup)
Definition: enum.c:57
#define PG_RETURN_OID(x)
Definition: fmgr.h:320
#define SearchSysCache2(cacheId, key1, key2)
Definition: syscache.h:161
Datum enum_send ( PG_FUNCTION_ARGS  )

Definition at line 231 of file enum.c.

References buf, ENUMOID, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum, PG_GETARG_OID, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendtext(), ReleaseSysCache(), and SearchSysCache1.

232 {
233  Oid enumval = PG_GETARG_OID(0);
235  HeapTuple tup;
236  Form_pg_enum en;
237 
238  tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(enumval));
239  if (!HeapTupleIsValid(tup))
240  ereport(ERROR,
241  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
242  errmsg("invalid internal value for enum: %u",
243  enumval)));
244  en = (Form_pg_enum) GETSTRUCT(tup);
245 
246  pq_begintypsend(&buf);
247  pq_sendtext(&buf, NameStr(en->enumlabel), strlen(NameStr(en->enumlabel)));
248 
249  ReleaseSysCache(tup);
250 
252 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
int errcode(int sqlerrcode)
Definition: elog.c:575
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:163
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
unsigned int Oid
Definition: postgres_ext.h:31
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:379
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:159
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:67
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
FormData_pg_enum * Form_pg_enum
Definition: pg_enum.h:46
#define ereport(elevel, rest)
Definition: elog.h:122
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:493
Datum enum_smaller ( PG_FUNCTION_ARGS  )

Definition at line 370 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_OID.

371 {
372  Oid a = PG_GETARG_OID(0);
373  Oid b = PG_GETARG_OID(1);
374 
375  PG_RETURN_OID(enum_cmp_internal(a, b, fcinfo) < 0 ? a : b);
376 }
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
static int enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo fcinfo)
Definition: enum.c:262
#define PG_RETURN_OID(x)
Definition: fmgr.h:320