⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 int.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * int.c *	  Functions for the built-in integer types (except int8). * * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.81 2008/01/01 19:45:52 momjian Exp $ * *------------------------------------------------------------------------- *//* * OLD COMMENTS *		I/O routines: *		 int2in, int2out, int2recv, int2send *		 int4in, int4out, int4recv, int4send *		 int2vectorin, int2vectorout, int2vectorrecv, int2vectorsend *		Boolean operators: *		 inteq, intne, intlt, intle, intgt, intge *		Arithmetic operators: *		 intpl, intmi, int4mul, intdiv * *		Arithmetic operators: *		 intmod */#include "postgres.h"#include <ctype.h>#include <limits.h>#include "catalog/pg_type.h"#include "funcapi.h"#include "libpq/pqformat.h"#include "utils/array.h"#include "utils/builtins.h"#define SAMESIGN(a,b)	(((a) < 0) == ((b) < 0))#define Int2VectorSize(n)	(offsetof(int2vector, values) + (n) * sizeof(int2))typedef struct{	int32		current;	int32		finish;	int32		step;} generate_series_fctx;/***************************************************************************** *	 USER I/O ROUTINES														 * *****************************************************************************//* *		int2in			- converts "num" to short */Datumint2in(PG_FUNCTION_ARGS){	char	   *num = PG_GETARG_CSTRING(0);	PG_RETURN_INT16(pg_atoi(num, sizeof(int16), '\0'));}/* *		int2out			- converts short to "num" */Datumint2out(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	char	   *result = (char *) palloc(7);	/* sign, 5 digits, '\0' */	pg_itoa(arg1, result);	PG_RETURN_CSTRING(result);}/* *		int2recv			- converts external binary format to int2 */Datumint2recv(PG_FUNCTION_ARGS){	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);	PG_RETURN_INT16((int16) pq_getmsgint(buf, sizeof(int16)));}/* *		int2send			- converts int2 to binary format */Datumint2send(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	StringInfoData buf;	pq_begintypsend(&buf);	pq_sendint(&buf, arg1, sizeof(int16));	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}/* * construct int2vector given a raw array of int2s * * If int2s is NULL then caller must fill values[] afterward */int2vector *buildint2vector(const int2 *int2s, int n){	int2vector *result;	result = (int2vector *) palloc0(Int2VectorSize(n));	if (n > 0 && int2s)		memcpy(result->values, int2s, n * sizeof(int2));	/*	 * Attach standard array header.  For historical reasons, we set the index	 * lower bound to 0 not 1.	 */	SET_VARSIZE(result, Int2VectorSize(n));	result->ndim = 1;	result->dataoffset = 0;		/* never any nulls */	result->elemtype = INT2OID;	result->dim1 = n;	result->lbound1 = 0;	return result;}/* *		int2vectorin			- converts "num num ..." to internal form */Datumint2vectorin(PG_FUNCTION_ARGS){	char	   *intString = PG_GETARG_CSTRING(0);	int2vector *result;	int			n;	result = (int2vector *) palloc0(Int2VectorSize(FUNC_MAX_ARGS));	for (n = 0; *intString && n < FUNC_MAX_ARGS; n++)	{		if (sscanf(intString, "%hd", &result->values[n]) != 1)			break;		while (*intString && isspace((unsigned char) *intString))			intString++;		while (*intString && !isspace((unsigned char) *intString))			intString++;	}	while (*intString && isspace((unsigned char) *intString))		intString++;	if (*intString)		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("int2vector has too many elements")));	SET_VARSIZE(result, Int2VectorSize(n));	result->ndim = 1;	result->dataoffset = 0;		/* never any nulls */	result->elemtype = INT2OID;	result->dim1 = n;	result->lbound1 = 0;	PG_RETURN_POINTER(result);}/* *		int2vectorout		- converts internal form to "num num ..." */Datumint2vectorout(PG_FUNCTION_ARGS){	int2vector *int2Array = (int2vector *) PG_GETARG_POINTER(0);	int			num,				nnums = int2Array->dim1;	char	   *rp;	char	   *result;	/* assumes sign, 5 digits, ' ' */	rp = result = (char *) palloc(nnums * 7 + 1);	for (num = 0; num < nnums; num++)	{		if (num != 0)			*rp++ = ' ';		pg_itoa(int2Array->values[num], rp);		while (*++rp != '\0')			;	}	*rp = '\0';	PG_RETURN_CSTRING(result);}/* *		int2vectorrecv			- converts external binary format to int2vector */Datumint2vectorrecv(PG_FUNCTION_ARGS){	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);	FunctionCallInfoData locfcinfo;	int2vector *result;	/*	 * Normally one would call array_recv() using DirectFunctionCall3, but	 * that does not work since array_recv wants to cache some data using	 * fcinfo->flinfo->fn_extra.  So we need to pass it our own flinfo	 * parameter.	 */	InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3, NULL, NULL);	locfcinfo.arg[0] = PointerGetDatum(buf);	locfcinfo.arg[1] = ObjectIdGetDatum(INT2OID);	locfcinfo.arg[2] = Int32GetDatum(-1);	locfcinfo.argnull[0] = false;	locfcinfo.argnull[1] = false;	locfcinfo.argnull[2] = false;	result = (int2vector *) DatumGetPointer(array_recv(&locfcinfo));	Assert(!locfcinfo.isnull);	/* sanity checks: int2vector must be 1-D, no nulls */	if (ARR_NDIM(result) != 1 ||		ARR_HASNULL(result) ||		ARR_ELEMTYPE(result) != INT2OID)		ereport(ERROR,				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),				 errmsg("invalid int2vector data")));	PG_RETURN_POINTER(result);}/* *		int2vectorsend			- converts int2vector to binary format */Datumint2vectorsend(PG_FUNCTION_ARGS){	return array_send(fcinfo);}/* * We don't have a complete set of int2vector support routines, * but we need int2vectoreq for catcache indexing. */Datumint2vectoreq(PG_FUNCTION_ARGS){	int2vector *a = (int2vector *) PG_GETARG_POINTER(0);	int2vector *b = (int2vector *) PG_GETARG_POINTER(1);	if (a->dim1 != b->dim1)		PG_RETURN_BOOL(false);	PG_RETURN_BOOL(memcmp(a->values, b->values, a->dim1 * sizeof(int2)) == 0);}/***************************************************************************** *	 PUBLIC ROUTINES														 * *****************************************************************************//* *		int4in			- converts "num" to int4 */Datumint4in(PG_FUNCTION_ARGS){	char	   *num = PG_GETARG_CSTRING(0);	PG_RETURN_INT32(pg_atoi(num, sizeof(int32), '\0'));}/* *		int4out			- converts int4 to "num" */Datumint4out(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	char	   *result = (char *) palloc(12);	/* sign, 10 digits, '\0' */	pg_ltoa(arg1, result);	PG_RETURN_CSTRING(result);}/* *		int4recv			- converts external binary format to int4 */Datumint4recv(PG_FUNCTION_ARGS){	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);	PG_RETURN_INT32((int32) pq_getmsgint(buf, sizeof(int32)));}/* *		int4send			- converts int4 to binary format */Datumint4send(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	StringInfoData buf;	pq_begintypsend(&buf);	pq_sendint(&buf, arg1, sizeof(int32));	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}/* *		=================== *		CONVERSION ROUTINES *		=================== */Datumi2toi4(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	PG_RETURN_INT32((int32) arg1);}Datumi4toi2(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	if (arg1 < SHRT_MIN || arg1 > SHRT_MAX)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("smallint out of range")));	PG_RETURN_INT16((int16) arg1);}/* Cast int4 -> bool */Datumint4_bool(PG_FUNCTION_ARGS){	if (PG_GETARG_INT32(0) == 0)		PG_RETURN_BOOL(false);	else		PG_RETURN_BOOL(true);}/* Cast bool -> int4 */Datumbool_int4(PG_FUNCTION_ARGS){	if (PG_GETARG_BOOL(0) == false)		PG_RETURN_INT32(0);	else		PG_RETURN_INT32(1);}/* *		============================ *		COMPARISON OPERATOR ROUTINES *		============================ *//* *		inteq			- returns 1 iff arg1 == arg2 *		intne			- returns 1 iff arg1 != arg2 *		intlt			- returns 1 iff arg1 < arg2 *		intle			- returns 1 iff arg1 <= arg2 *		intgt			- returns 1 iff arg1 > arg2 *		intge			- returns 1 iff arg1 >= arg2 */Datumint4eq(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 == arg2);}Datumint4ne(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 != arg2);}Datumint4lt(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 < arg2);}Datumint4le(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 <= arg2);}Datumint4gt(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 > arg2);}Datumint4ge(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 >= arg2);}Datumint2eq(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 == arg2);}Datumint2ne(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 != arg2);}Datumint2lt(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 < arg2);}Datumint2le(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 <= arg2);}Datumint2gt(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 > arg2);}Datumint2ge(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 >= arg2);}Datumint24eq(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 == arg2);}Datumint24ne(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 != arg2);}Datumint24lt(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 < arg2);}Datumint24le(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 <= arg2);}Datumint24gt(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 > arg2);}Datumint24ge(PG_FUNCTION_ARGS){	int16		arg1 = PG_GETARG_INT16(0);	int32		arg2 = PG_GETARG_INT32(1);	PG_RETURN_BOOL(arg1 >= arg2);}Datumint42eq(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 == arg2);}Datumint42ne(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 != arg2);}Datumint42lt(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 < arg2);}Datumint42le(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 <= arg2);}Datumint42gt(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 > arg2);}Datumint42ge(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int16		arg2 = PG_GETARG_INT16(1);	PG_RETURN_BOOL(arg1 >= arg2);}/* *		int[24]pl		- returns arg1 + arg2 *		int[24]mi		- returns arg1 - arg2 *		int[24]mul		- returns arg1 * arg2 *		int[24]div		- returns arg1 / arg2 */Datumint4um(PG_FUNCTION_ARGS){	int32		arg = PG_GETARG_INT32(0);	int32		result;	result = -arg;	/* overflow check (needed for INT_MIN) */	if (arg != 0 && SAMESIGN(result, arg))		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("integer out of range")));	PG_RETURN_INT32(result);}Datumint4up(PG_FUNCTION_ARGS){	int32		arg = PG_GETARG_INT32(0);	PG_RETURN_INT32(arg);}Datumint4pl(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int32		arg2 = PG_GETARG_INT32(1);	int32		result;	result = arg1 + arg2;	/*	 * Overflow check.	If the inputs are of different signs then their sum	 * cannot overflow.  If the inputs are of the same sign, their sum had	 * better be that sign too.	 */	if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("integer out of range")));	PG_RETURN_INT32(result);}Datumint4mi(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int32		arg2 = PG_GETARG_INT32(1);	int32		result;	result = arg1 - arg2;	/*	 * Overflow check.	If the inputs are of the same sign then their	 * difference cannot overflow.	If they are of different signs then the	 * result should be of the same sign as the first input.	 */	if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("integer out of range")));	PG_RETURN_INT32(result);}Datumint4mul(PG_FUNCTION_ARGS){	int32		arg1 = PG_GETARG_INT32(0);	int32		arg2 = PG_GETARG_INT32(1);	int32		result;#ifdef WIN32	/*	 * Win32 doesn't throw a catchable exception for SELECT -2147483648 *	 * (-1);  -- INT_MIN	 */	if (arg2 == -1 && arg1 == INT_MIN)		ereport(ERROR,				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),				 errmsg("integer out of range")));#endif	result = arg1 * arg2;	/*	 * Overflow check.	We basically check to see if result / arg2 gives arg1	 * again.  There are two cases where this fails: arg2 = 0 (which cannot	 * overflow) and arg1 = INT_MIN, arg2 = -1 (where the division itself will	 * overflow and thus incorrectly match).

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -