PostgreSQL Source Code  git master
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 "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)
 
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

◆ enum_cmp()

Datum enum_cmp ( PG_FUNCTION_ARGS  )

Definition at line 294 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_INT32.

Referenced by gbt_enumkey_cmp(), and gin_enum_cmp().

295 {
296  Oid a = PG_GETARG_OID(0);
297  Oid b = PG_GETARG_OID(1);
298 
299  PG_RETURN_INT32(enum_cmp_internal(a, b, fcinfo));
300 }
#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:168

◆ enum_cmp_internal()

static int enum_cmp_internal ( Oid  arg1,
Oid  arg2,
FunctionCallInfo  fcinfo 
)
static

Definition at line 168 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().

169 {
170  TypeCacheEntry *tcache;
171 
172  /*
173  * We don't need the typcache except in the hopefully-uncommon case that
174  * one or both Oids are odd. This means that cursory testing of code that
175  * fails to pass flinfo to an enum comparison function might not disclose
176  * the oversight. To make such errors more obvious, Assert that we have a
177  * place to cache even when we take a fast-path exit.
178  */
179  Assert(fcinfo->flinfo != NULL);
180 
181  /* Equal OIDs are equal no matter what */
182  if (arg1 == arg2)
183  return 0;
184 
185  /* Fast path: even-numbered Oids are known to compare correctly */
186  if ((arg1 & 1) == 0 && (arg2 & 1) == 0)
187  {
188  if (arg1 < arg2)
189  return -1;
190  else
191  return 1;
192  }
193 
194  /* Locate the typcache entry for the enum type */
195  tcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
196  if (tcache == NULL)
197  {
198  HeapTuple enum_tup;
199  Form_pg_enum en;
200  Oid typeoid;
201 
202  /* Get the OID of the enum type containing arg1 */
203  enum_tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(arg1));
204  if (!HeapTupleIsValid(enum_tup))
205  ereport(ERROR,
206  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
207  errmsg("invalid internal value for enum: %u",
208  arg1)));
209  en = (Form_pg_enum) GETSTRUCT(enum_tup);
210  typeoid = en->enumtypid;
211  ReleaseSysCache(enum_tup);
212  /* Now locate and remember the typcache entry */
213  tcache = lookup_type_cache(typeoid, 0);
214  fcinfo->flinfo->fn_extra = (void *) tcache;
215  }
216 
217  /* The remaining comparison logic is in typcache.c */
218  return compare_values_of_enum(tcache, arg1, arg2);
219 }
int compare_values_of_enum(TypeCacheEntry *tcache, Oid arg1, Oid arg2)
Definition: typcache.c:2154
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
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
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:311
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:670
void * fn_extra
Definition: fmgr.h:64
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ enum_endpoint()

static Oid enum_endpoint ( Oid  enumtypoid,
ScanDirection  direction 
)
static

Definition at line 308 of file enum.c.

References AccessShareLock, Anum_pg_enum_enumtypid, BTEqualStrategyNumber, 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().

309 {
310  Relation enum_rel;
311  Relation enum_idx;
312  SysScanDesc enum_scan;
313  HeapTuple enum_tuple;
314  ScanKeyData skey;
315  Oid minmax;
316 
317  /*
318  * Find the first/last enum member using pg_enum_typid_sortorder_index.
319  * Note we must not use the syscache. See comments for RenumberEnumType
320  * in catalog/pg_enum.c for more info.
321  */
322  ScanKeyInit(&skey,
324  BTEqualStrategyNumber, F_OIDEQ,
325  ObjectIdGetDatum(enumtypoid));
326 
329  enum_scan = systable_beginscan_ordered(enum_rel, enum_idx, NULL,
330  1, &skey);
331 
332  enum_tuple = systable_getnext_ordered(enum_scan, direction);
333  if (HeapTupleIsValid(enum_tuple))
334  minmax = HeapTupleGetOid(enum_tuple);
335  else
336  minmax = InvalidOid;
337 
338  systable_endscan_ordered(enum_scan);
339  index_close(enum_idx, AccessShareLock);
340  heap_close(enum_rel, AccessShareLock);
341 
342  return minmax;
343 }
#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:700
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ enum_eq()

Datum enum_eq ( PG_FUNCTION_ARGS  )

Definition at line 240 of file enum.c.

References PG_GETARG_OID, and PG_RETURN_BOOL.

241 {
242  Oid a = PG_GETARG_OID(0);
243  Oid b = PG_GETARG_OID(1);
244 
245  PG_RETURN_BOOL(a == b);
246 }
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

◆ enum_first()

Datum enum_first ( PG_FUNCTION_ARGS  )

Definition at line 346 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.

347 {
348  Oid enumtypoid;
349  Oid min;
350 
351  /*
352  * We rely on being able to get the specific enum type from the calling
353  * expression tree. Notice that the actual value of the argument isn't
354  * examined at all; in particular it might be NULL.
355  */
356  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
357  if (enumtypoid == InvalidOid)
358  ereport(ERROR,
359  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
360  errmsg("could not determine actual enum type")));
361 
362  /* Get the OID using the index */
363  min = enum_endpoint(enumtypoid, ForwardScanDirection);
364 
365  if (!OidIsValid(min))
366  ereport(ERROR,
367  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
368  errmsg("enum %s contains no values",
369  format_type_be(enumtypoid))));
370 
371  PG_RETURN_OID(min);
372 }
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:576
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1904
static Oid enum_endpoint(Oid enumtypoid, ScanDirection direction)
Definition: enum.c:308
#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

◆ enum_ge()

Datum enum_ge ( PG_FUNCTION_ARGS  )

Definition at line 258 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_BOOL.

Referenced by gbt_enumge().

259 {
260  Oid a = PG_GETARG_OID(0);
261  Oid b = PG_GETARG_OID(1);
262 
263  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) >= 0);
264 }
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:168

◆ enum_gt()

Datum enum_gt ( PG_FUNCTION_ARGS  )

Definition at line 267 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_BOOL.

Referenced by gbt_enumgt().

268 {
269  Oid a = PG_GETARG_OID(0);
270  Oid b = PG_GETARG_OID(1);
271 
272  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) > 0);
273 }
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:168

◆ enum_in()

Datum enum_in ( PG_FUNCTION_ARGS  )

Definition at line 37 of file enum.c.

References 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().

38 {
39  char *name = PG_GETARG_CSTRING(0);
40  Oid enumtypoid = PG_GETARG_OID(1);
41  Oid enumoid;
42  HeapTuple tup;
43 
44  /* must check length to prevent Assert failure within SearchSysCache */
45  if (strlen(name) >= NAMEDATALEN)
46  ereport(ERROR,
47  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
48  errmsg("invalid input value for enum %s: \"%s\"",
49  format_type_be(enumtypoid),
50  name)));
51 
53  ObjectIdGetDatum(enumtypoid),
54  CStringGetDatum(name));
55  if (!HeapTupleIsValid(tup))
56  ereport(ERROR,
57  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
58  errmsg("invalid input value for enum %s: \"%s\"",
59  format_type_be(enumtypoid),
60  name)));
61 
62  /*
63  * This comes from pg_enum.oid and stores system oids in user tables. This
64  * oid must be preserved by binary upgrades.
65  */
66  enumoid = HeapTupleGetOid(tup);
67 
68  ReleaseSysCache(tup);
69 
70  PG_RETURN_OID(enumoid);
71 }
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:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1123
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:700
#define PG_RETURN_OID(x)
Definition: fmgr.h:320

◆ enum_larger()

Datum enum_larger ( PG_FUNCTION_ARGS  )

Definition at line 285 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_OID.

286 {
287  Oid a = PG_GETARG_OID(0);
288  Oid b = PG_GETARG_OID(1);
289 
290  PG_RETURN_OID(enum_cmp_internal(a, b, fcinfo) > 0 ? a : b);
291 }
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:168
#define PG_RETURN_OID(x)
Definition: fmgr.h:320

◆ enum_last()

Datum enum_last ( PG_FUNCTION_ARGS  )

Definition at line 375 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.

376 {
377  Oid enumtypoid;
378  Oid max;
379 
380  /*
381  * We rely on being able to get the specific enum type from the calling
382  * expression tree. Notice that the actual value of the argument isn't
383  * examined at all; in particular it might be NULL.
384  */
385  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
386  if (enumtypoid == InvalidOid)
387  ereport(ERROR,
388  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
389  errmsg("could not determine actual enum type")));
390 
391  /* Get the OID using the index */
392  max = enum_endpoint(enumtypoid, BackwardScanDirection);
393 
394  if (!OidIsValid(max))
395  ereport(ERROR,
396  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
397  errmsg("enum %s contains no values",
398  format_type_be(enumtypoid))));
399 
400  PG_RETURN_OID(max);
401 }
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:576
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1904
static Oid enum_endpoint(Oid enumtypoid, ScanDirection direction)
Definition: enum.c:308
#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

◆ enum_le()

Datum enum_le ( PG_FUNCTION_ARGS  )

Definition at line 231 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_BOOL.

Referenced by gbt_enumle().

232 {
233  Oid a = PG_GETARG_OID(0);
234  Oid b = PG_GETARG_OID(1);
235 
236  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) <= 0);
237 }
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:168

◆ enum_lt()

Datum enum_lt ( PG_FUNCTION_ARGS  )

Definition at line 222 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_BOOL.

Referenced by gbt_enumlt().

223 {
224  Oid a = PG_GETARG_OID(0);
225  Oid b = PG_GETARG_OID(1);
226 
227  PG_RETURN_BOOL(enum_cmp_internal(a, b, fcinfo) < 0);
228 }
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:168

◆ enum_ne()

Datum enum_ne ( PG_FUNCTION_ARGS  )

Definition at line 249 of file enum.c.

References PG_GETARG_OID, and PG_RETURN_BOOL.

250 {
251  Oid a = PG_GETARG_OID(0);
252  Oid b = PG_GETARG_OID(1);
253 
254  PG_RETURN_BOOL(a != b);
255 }
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

◆ enum_out()

Datum enum_out ( PG_FUNCTION_ARGS  )

Definition at line 74 of file enum.c.

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

Referenced by anyenum_out().

75 {
76  Oid enumval = PG_GETARG_OID(0);
77  char *result;
78  HeapTuple tup;
79  Form_pg_enum en;
80 
81  tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(enumval));
82  if (!HeapTupleIsValid(tup))
83  ereport(ERROR,
84  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
85  errmsg("invalid internal value for enum: %u",
86  enumval)));
87  en = (Form_pg_enum) GETSTRUCT(tup);
88 
89  result = pstrdup(NameStr(en->enumlabel));
90 
91  ReleaseSysCache(tup);
92 
93  PG_RETURN_CSTRING(result);
94 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
char * pstrdup(const char *in)
Definition: mcxt.c:1076
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#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
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#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:547

◆ enum_range_all()

Datum enum_range_all ( PG_FUNCTION_ARGS  )

Definition at line 436 of file enum.c.

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

437 {
438  Oid enumtypoid;
439 
440  /*
441  * We rely on being able to get the specific enum type from the calling
442  * expression tree. Notice that the actual value of the argument isn't
443  * examined at all; in particular it might be NULL.
444  */
445  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
446  if (enumtypoid == InvalidOid)
447  ereport(ERROR,
448  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
449  errmsg("could not determine actual enum type")));
450 
453 }
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:456
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1904
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:250
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ enum_range_bounds()

Datum enum_range_bounds ( PG_FUNCTION_ARGS  )

Definition at line 405 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().

406 {
407  Oid lower;
408  Oid upper;
409  Oid enumtypoid;
410 
411  if (PG_ARGISNULL(0))
412  lower = InvalidOid;
413  else
414  lower = PG_GETARG_OID(0);
415  if (PG_ARGISNULL(1))
416  upper = InvalidOid;
417  else
418  upper = PG_GETARG_OID(1);
419 
420  /*
421  * We rely on being able to get the specific enum type from the calling
422  * expression tree. The generic type mechanism should have ensured that
423  * both are of the same type.
424  */
425  enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0);
426  if (enumtypoid == InvalidOid)
427  ereport(ERROR,
428  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
429  errmsg("could not determine actual enum type")));
430 
431  PG_RETURN_ARRAYTYPE_P(enum_range_internal(enumtypoid, lower, upper));
432 }
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:456
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1904
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:250
#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

◆ enum_range_internal()

static ArrayType * enum_range_internal ( Oid  enumtypoid,
Oid  lower,
Oid  upper 
)
static

Definition at line 456 of file enum.c.

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

Referenced by enum_range_all(), and enum_range_bounds().

457 {
458  ArrayType *result;
459  Relation enum_rel;
460  Relation enum_idx;
461  SysScanDesc enum_scan;
462  HeapTuple enum_tuple;
463  ScanKeyData skey;
464  Datum *elems;
465  int max,
466  cnt;
467  bool left_found;
468 
469  /*
470  * Scan the enum members in order using pg_enum_typid_sortorder_index.
471  * Note we must not use the syscache. See comments for RenumberEnumType
472  * in catalog/pg_enum.c for more info.
473  */
474  ScanKeyInit(&skey,
476  BTEqualStrategyNumber, F_OIDEQ,
477  ObjectIdGetDatum(enumtypoid));
478 
481  enum_scan = systable_beginscan_ordered(enum_rel, enum_idx, NULL, 1, &skey);
482 
483  max = 64;
484  elems = (Datum *) palloc(max * sizeof(Datum));
485  cnt = 0;
486  left_found = !OidIsValid(lower);
487 
488  while (HeapTupleIsValid(enum_tuple = systable_getnext_ordered(enum_scan, ForwardScanDirection)))
489  {
490  Oid enum_oid = HeapTupleGetOid(enum_tuple);
491 
492  if (!left_found && lower == enum_oid)
493  left_found = true;
494 
495  if (left_found)
496  {
497  if (cnt >= max)
498  {
499  max *= 2;
500  elems = (Datum *) repalloc(elems, max * sizeof(Datum));
501  }
502 
503  elems[cnt++] = ObjectIdGetDatum(enum_oid);
504  }
505 
506  if (OidIsValid(upper) && upper == enum_oid)
507  break;
508  }
509 
510  systable_endscan_ordered(enum_scan);
511  index_close(enum_idx, AccessShareLock);
512  heap_close(enum_rel, AccessShareLock);
513 
514  /* and build the result array */
515  /* note this hardwires some details about the representation of Oid */
516  result = construct_array(elems, cnt, enumtypoid, sizeof(Oid), true, 'i');
517 
518  pfree(elems);
519 
520  return result;
521 }
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:3279
#define AccessShareLock
Definition: lockdefs.h:36
#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:576
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:700
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ enum_recv()

Datum enum_recv ( PG_FUNCTION_ARGS  )

Definition at line 98 of file enum.c.

References buf, 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().

99 {
101  Oid enumtypoid = PG_GETARG_OID(1);
102  Oid enumoid;
103  HeapTuple tup;
104  char *name;
105  int nbytes;
106 
107  name = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
108 
109  /* must check length to prevent Assert failure within SearchSysCache */
110  if (strlen(name) >= NAMEDATALEN)
111  ereport(ERROR,
112  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
113  errmsg("invalid input value for enum %s: \"%s\"",
114  format_type_be(enumtypoid),
115  name)));
116 
118  ObjectIdGetDatum(enumtypoid),
119  CStringGetDatum(name));
120  if (!HeapTupleIsValid(tup))
121  ereport(ERROR,
122  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
123  errmsg("invalid input value for enum %s: \"%s\"",
124  format_type_be(enumtypoid),
125  name)));
126 
127  enumoid = HeapTupleGetOid(tup);
128 
129  ReleaseSysCache(tup);
130 
131  pfree(name);
132 
133  PG_RETURN_OID(enumoid);
134 }
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:548
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1123
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:700
#define PG_RETURN_OID(x)
Definition: fmgr.h:320

◆ enum_send()

Datum enum_send ( PG_FUNCTION_ARGS  )

Definition at line 137 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().

138 {
139  Oid enumval = PG_GETARG_OID(0);
141  HeapTuple tup;
142  Form_pg_enum en;
143 
144  tup = SearchSysCache1(ENUMOID, ObjectIdGetDatum(enumval));
145  if (!HeapTupleIsValid(tup))
146  ereport(ERROR,
147  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
148  errmsg("invalid internal value for enum: %u",
149  enumval)));
150  en = (Form_pg_enum) GETSTRUCT(tup);
151 
152  pq_begintypsend(&buf);
153  pq_sendtext(&buf, NameStr(en->enumlabel), strlen(NameStr(en->enumlabel)));
154 
155  ReleaseSysCache(tup);
156 
158 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
int errcode(int sqlerrcode)
Definition: elog.c:575
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:174
#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:348
#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
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:547

◆ enum_smaller()

Datum enum_smaller ( PG_FUNCTION_ARGS  )

Definition at line 276 of file enum.c.

References enum_cmp_internal(), PG_GETARG_OID, and PG_RETURN_OID.

277 {
278  Oid a = PG_GETARG_OID(0);
279  Oid b = PG_GETARG_OID(1);
280 
281  PG_RETURN_OID(enum_cmp_internal(a, b, fcinfo) < 0 ? a : b);
282 }
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:168
#define PG_RETURN_OID(x)
Definition: fmgr.h:320