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 + -
显示快捷键?