enum.c
来自「postgresql8.3.4源码,开源数据库」· C语言 代码 · 共 436 行
C
436 行
/*------------------------------------------------------------------------- * * enum.c * I/O functions, operators, aggregates etc for enum types * * Copyright (c) 2006-2008, PostgreSQL Global Development Group * * * IDENTIFICATION * $PostgreSQL: pgsql/src/backend/utils/adt/enum.c,v 1.6 2008/01/01 19:45:52 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "catalog/pg_enum.h"#include "fmgr.h"#include "utils/array.h"#include "utils/builtins.h"#include "utils/lsyscache.h"#include "utils/syscache.h"#include "libpq/pqformat.h"#include "miscadmin.h"static ArrayType *enum_range_internal(Oid enumtypoid, Oid lower, Oid upper);static int enum_elem_cmp(const void *left, const void *right);/* Basic I/O support */Datumenum_in(PG_FUNCTION_ARGS){ char *name = PG_GETARG_CSTRING(0); Oid enumtypoid = PG_GETARG_OID(1); Oid enumoid; HeapTuple tup; /* must check length to prevent Assert failure within SearchSysCache */ if (strlen(name) >= NAMEDATALEN) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input value for enum %s: \"%s\"", format_type_be(enumtypoid), name))); tup = SearchSysCache(ENUMTYPOIDNAME, ObjectIdGetDatum(enumtypoid), CStringGetDatum(name), 0, 0); if (!HeapTupleIsValid(tup)) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input value for enum %s: \"%s\"", format_type_be(enumtypoid), name))); enumoid = HeapTupleGetOid(tup); ReleaseSysCache(tup); PG_RETURN_OID(enumoid);}Datumenum_out(PG_FUNCTION_ARGS){ Oid enumval = PG_GETARG_OID(0); char *result; HeapTuple tup; Form_pg_enum en; tup = SearchSysCache(ENUMOID, ObjectIdGetDatum(enumval), 0, 0, 0); if (!HeapTupleIsValid(tup)) ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("invalid internal value for enum: %u", enumval))); en = (Form_pg_enum) GETSTRUCT(tup); result = pstrdup(NameStr(en->enumlabel)); ReleaseSysCache(tup); PG_RETURN_CSTRING(result);}/* Binary I/O support */Datumenum_recv(PG_FUNCTION_ARGS){ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); Oid enumtypoid = PG_GETARG_OID(1); Oid enumoid; HeapTuple tup; char *name; int nbytes; name = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes); /* must check length to prevent Assert failure within SearchSysCache */ if (strlen(name) >= NAMEDATALEN) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input value for enum %s: \"%s\"", format_type_be(enumtypoid), name))); tup = SearchSysCache(ENUMTYPOIDNAME, ObjectIdGetDatum(enumtypoid), CStringGetDatum(name), 0, 0); if (!HeapTupleIsValid(tup)) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input value for enum %s: \"%s\"", format_type_be(enumtypoid), name))); enumoid = HeapTupleGetOid(tup); ReleaseSysCache(tup); pfree(name); PG_RETURN_OID(enumoid);}Datumenum_send(PG_FUNCTION_ARGS){ Oid enumval = PG_GETARG_OID(0); StringInfoData buf; HeapTuple tup; Form_pg_enum en; tup = SearchSysCache(ENUMOID, ObjectIdGetDatum(enumval), 0, 0, 0); if (!HeapTupleIsValid(tup)) ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("invalid internal value for enum: %u", enumval))); en = (Form_pg_enum) GETSTRUCT(tup); pq_begintypsend(&buf); pq_sendtext(&buf, NameStr(en->enumlabel), strlen(NameStr(en->enumlabel))); ReleaseSysCache(tup); PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}/* Comparison functions and related */Datumenum_lt(PG_FUNCTION_ARGS){ Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); PG_RETURN_BOOL(a < b);}Datumenum_le(PG_FUNCTION_ARGS){ Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); PG_RETURN_BOOL(a <= b);}Datumenum_eq(PG_FUNCTION_ARGS){ Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); PG_RETURN_BOOL(a == b);}Datumenum_ne(PG_FUNCTION_ARGS){ Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); PG_RETURN_BOOL(a != b);}Datumenum_ge(PG_FUNCTION_ARGS){ Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); PG_RETURN_BOOL(a >= b);}Datumenum_gt(PG_FUNCTION_ARGS){ Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); PG_RETURN_BOOL(a > b);}Datumenum_smaller(PG_FUNCTION_ARGS){ Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); PG_RETURN_OID(a <= b ? a : b);}Datumenum_larger(PG_FUNCTION_ARGS){ Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); PG_RETURN_OID(a >= b ? a : b);}Datumenum_cmp(PG_FUNCTION_ARGS){ Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); if (a > b) PG_RETURN_INT32(1); else if (a == b) PG_RETURN_INT32(0); else PG_RETURN_INT32(-1);}/* Enum programming support functions */Datumenum_first(PG_FUNCTION_ARGS){ Oid enumtypoid; Oid min = InvalidOid; CatCList *list; int num, i; /* * We rely on being able to get the specific enum type from the calling * expression tree. Notice that the actual value of the argument isn't * examined at all; in particular it might be NULL. */ enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0); if (enumtypoid == InvalidOid) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("could not determine actual enum type"))); list = SearchSysCacheList(ENUMTYPOIDNAME, 1, ObjectIdGetDatum(enumtypoid), 0, 0, 0); num = list->n_members; for (i = 0; i < num; i++) { Oid valoid = HeapTupleHeaderGetOid(list->members[i]->tuple.t_data); if (!OidIsValid(min) || valoid < min) min = valoid; } ReleaseCatCacheList(list); if (!OidIsValid(min)) /* should not happen */ elog(ERROR, "no values found for enum %s", format_type_be(enumtypoid)); PG_RETURN_OID(min);}Datumenum_last(PG_FUNCTION_ARGS){ Oid enumtypoid; Oid max = InvalidOid; CatCList *list; int num, i; /* * We rely on being able to get the specific enum type from the calling * expression tree. Notice that the actual value of the argument isn't * examined at all; in particular it might be NULL. */ enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0); if (enumtypoid == InvalidOid) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("could not determine actual enum type"))); list = SearchSysCacheList(ENUMTYPOIDNAME, 1, ObjectIdGetDatum(enumtypoid), 0, 0, 0); num = list->n_members; for (i = 0; i < num; i++) { Oid valoid = HeapTupleHeaderGetOid(list->members[i]->tuple.t_data); if (!OidIsValid(max) || valoid > max) max = valoid; } ReleaseCatCacheList(list); if (!OidIsValid(max)) /* should not happen */ elog(ERROR, "no values found for enum %s", format_type_be(enumtypoid)); PG_RETURN_OID(max);}/* 2-argument variant of enum_range */Datumenum_range_bounds(PG_FUNCTION_ARGS){ Oid lower; Oid upper; Oid enumtypoid; if (PG_ARGISNULL(0)) lower = InvalidOid; else lower = PG_GETARG_OID(0); if (PG_ARGISNULL(1)) upper = InvalidOid; else upper = PG_GETARG_OID(1); /* * We rely on being able to get the specific enum type from the calling * expression tree. The generic type mechanism should have ensured that * both are of the same type. */ enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0); if (enumtypoid == InvalidOid) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("could not determine actual enum type"))); PG_RETURN_ARRAYTYPE_P(enum_range_internal(enumtypoid, lower, upper));}/* 1-argument variant of enum_range */Datumenum_range_all(PG_FUNCTION_ARGS){ Oid enumtypoid; /* * We rely on being able to get the specific enum type from the calling * expression tree. Notice that the actual value of the argument isn't * examined at all; in particular it might be NULL. */ enumtypoid = get_fn_expr_argtype(fcinfo->flinfo, 0); if (enumtypoid == InvalidOid) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("could not determine actual enum type"))); PG_RETURN_ARRAYTYPE_P(enum_range_internal(enumtypoid, InvalidOid, InvalidOid));}static ArrayType *enum_range_internal(Oid enumtypoid, Oid lower, Oid upper){ ArrayType *result; CatCList *list; int total, i, j; Datum *elems; list = SearchSysCacheList(ENUMTYPOIDNAME, 1, ObjectIdGetDatum(enumtypoid), 0, 0, 0); total = list->n_members; elems = (Datum *) palloc(total * sizeof(Datum)); j = 0; for (i = 0; i < total; i++) { Oid val = HeapTupleGetOid(&(list->members[i]->tuple)); if ((!OidIsValid(lower) || lower <= val) && (!OidIsValid(upper) || val <= upper)) elems[j++] = ObjectIdGetDatum(val); } /* shouldn't need the cache anymore */ ReleaseCatCacheList(list); /* sort results into OID order */ qsort(elems, j, sizeof(Datum), enum_elem_cmp); /* note this hardwires some details about the representation of Oid */ result = construct_array(elems, j, enumtypoid, sizeof(Oid), true, 'i'); pfree(elems); return result;}/* qsort comparison function for Datums that are OIDs */static intenum_elem_cmp(const void *left, const void *right){ Oid l = DatumGetObjectId(*((const Datum *) left)); Oid r = DatumGetObjectId(*((const Datum *) right)); if (l < r) return -1; if (l > r) return 1; return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?