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

📄 timestamp.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
	result = timestamp;	AdjustTimestampForTypmod(&result, typmod);	PG_RETURN_TIMESTAMPTZ(result);}/* interval_in() * Convert a string to internal form. * * External format(s): *	Uses the generic date/time parsing and decoding routines. */Datuminterval_in(PG_FUNCTION_ARGS){	char	   *str = PG_GETARG_CSTRING(0);#ifdef NOT_USED	Oid			typelem = PG_GETARG_OID(1);#endif	int32		typmod = PG_GETARG_INT32(2);	Interval   *result;	fsec_t		fsec;	struct pg_tm tt,			   *tm = &tt;	int			dtype;	int			nf;	int			dterr;	char	   *field[MAXDATEFIELDS];	int			ftype[MAXDATEFIELDS];	char		workbuf[256];	tm->tm_year = 0;	tm->tm_mon = 0;	tm->tm_mday = 0;	tm->tm_hour = 0;	tm->tm_min = 0;	tm->tm_sec = 0;	fsec = 0;	dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field,						  ftype, MAXDATEFIELDS, &nf);	if (dterr == 0)		dterr = DecodeInterval(field, ftype, nf, &dtype, tm, &fsec);	if (dterr != 0)	{		if (dterr == DTERR_FIELD_OVERFLOW)			dterr = DTERR_INTERVAL_OVERFLOW;		DateTimeParseError(dterr, str, "interval");	}	result = (Interval *) palloc(sizeof(Interval));	switch (dtype)	{		case DTK_DELTA:			if (tm2interval(tm, fsec, result) != 0)				ereport(ERROR,						(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),						 errmsg("interval out of range")));			break;		case DTK_INVALID:			ereport(ERROR,					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),			  errmsg("date/time value \"%s\" is no longer supported", str)));			break;		default:			elog(ERROR, "unexpected dtype %d while parsing interval \"%s\"",				 dtype, str);	}	AdjustIntervalForTypmod(result, typmod);	PG_RETURN_INTERVAL_P(result);}/* interval_out() * Convert a time span to external form. */Datuminterval_out(PG_FUNCTION_ARGS){	Interval   *span = PG_GETARG_INTERVAL_P(0);	char	   *result;	struct pg_tm tt,			   *tm = &tt;	fsec_t		fsec;	char		buf[MAXDATELEN + 1];	if (interval2tm(*span, tm, &fsec) != 0)		elog(ERROR, "could not convert interval to tm");	if (EncodeInterval(tm, fsec, DateStyle, buf) != 0)		elog(ERROR, "could not format interval");	result = pstrdup(buf);	PG_RETURN_CSTRING(result);}/* *		interval_recv			- converts external binary format to interval */Datuminterval_recv(PG_FUNCTION_ARGS){	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);#ifdef NOT_USED	Oid			typelem = PG_GETARG_OID(1);#endif	int32		typmod = PG_GETARG_INT32(2);	Interval   *interval;	interval = (Interval *) palloc(sizeof(Interval));#ifdef HAVE_INT64_TIMESTAMP	interval->time = pq_getmsgint64(buf);#else	interval->time = pq_getmsgfloat8(buf);#endif	interval->day = pq_getmsgint(buf, sizeof(interval->day));	interval->month = pq_getmsgint(buf, sizeof(interval->month));	AdjustIntervalForTypmod(interval, typmod);	PG_RETURN_INTERVAL_P(interval);}/* *		interval_send			- converts interval to binary format */Datuminterval_send(PG_FUNCTION_ARGS){	Interval   *interval = PG_GETARG_INTERVAL_P(0);	StringInfoData buf;	pq_begintypsend(&buf);#ifdef HAVE_INT64_TIMESTAMP	pq_sendint64(&buf, interval->time);#else	pq_sendfloat8(&buf, interval->time);#endif	pq_sendint(&buf, interval->day, sizeof(interval->day));	pq_sendint(&buf, interval->month, sizeof(interval->month));	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}Datumintervaltypmodin(PG_FUNCTION_ARGS){	ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);	int32	   *tl;	int			n;	int32		typmod;	tl = ArrayGetIntegerTypmods(ta, &n);	/*	 * tl[0] - opt_interval tl[1] - Iconst (optional)	 *	 * Note we must validate tl[0] even though it's normally guaranteed	 * correct by the grammar --- consider SELECT 'foo'::"interval"(1000).	 */	if (n > 0)	{		switch (tl[0])		{			case INTERVAL_MASK(YEAR):			case INTERVAL_MASK(MONTH):			case INTERVAL_MASK(DAY):			case INTERVAL_MASK(HOUR):			case INTERVAL_MASK(MINUTE):			case INTERVAL_MASK(SECOND):			case INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH):			case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR):			case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):			case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):			case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):			case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):			case INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):			case INTERVAL_FULL_RANGE:				/* all OK */				break;			default:				ereport(ERROR,						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),						 errmsg("invalid INTERVAL type modifier")));		}	}	if (n == 1)	{		if (tl[0] != INTERVAL_FULL_RANGE)			typmod = INTERVAL_TYPMOD(INTERVAL_FULL_PRECISION, tl[0]);		else			typmod = -1;	}	else if (n == 2)	{		if (tl[1] < 0)			ereport(ERROR,					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),					 errmsg("INTERVAL(%d) precision must not be negative",							tl[1])));		if (tl[1] > MAX_INTERVAL_PRECISION)		{			ereport(WARNING,					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),			  errmsg("INTERVAL(%d) precision reduced to maximum allowed, %d",					 tl[1], MAX_INTERVAL_PRECISION)));			typmod = INTERVAL_TYPMOD(MAX_INTERVAL_PRECISION, tl[0]);		}		else			typmod = INTERVAL_TYPMOD(tl[1], tl[0]);	}	else	{		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("invalid INTERVAL type modifier")));		typmod = 0;				/* keep compiler quiet */	}	PG_RETURN_INT32(typmod);}Datumintervaltypmodout(PG_FUNCTION_ARGS){	int32		typmod = PG_GETARG_INT32(0);	char	   *res = (char *) palloc(64);	int			fields;	int			precision;	const char *fieldstr;	if (typmod < 0)	{		*res = '\0';		PG_RETURN_CSTRING(res);	}	fields = INTERVAL_RANGE(typmod);	precision = INTERVAL_PRECISION(typmod);	switch (fields)	{		case INTERVAL_MASK(YEAR):			fieldstr = " year";			break;		case INTERVAL_MASK(MONTH):			fieldstr = " month";			break;		case INTERVAL_MASK(DAY):			fieldstr = " day";			break;		case INTERVAL_MASK(HOUR):			fieldstr = " hour";			break;		case INTERVAL_MASK(MINUTE):			fieldstr = " minute";			break;		case INTERVAL_MASK(SECOND):			fieldstr = " second";			break;		case INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH):			fieldstr = " year to month";			break;		case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR):			fieldstr = " day to hour";			break;		case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):			fieldstr = " day to minute";			break;		case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):			fieldstr = " day to second";			break;		case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):			fieldstr = " hour to minute";			break;		case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):			fieldstr = " hour to second";			break;		case INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):			fieldstr = " minute to second";			break;		case INTERVAL_FULL_RANGE:			fieldstr = "";			break;		default:			elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);			fieldstr = "";			break;	}	if (precision != INTERVAL_FULL_PRECISION)		snprintf(res, 64, "(%d)%s", precision, fieldstr);	else		snprintf(res, 64, "%s", fieldstr);	PG_RETURN_CSTRING(res);}/* interval_scale() * Adjust interval type for specified fields. * Used by PostgreSQL type system to stuff columns. */Datuminterval_scale(PG_FUNCTION_ARGS){	Interval   *interval = PG_GETARG_INTERVAL_P(0);	int32		typmod = PG_GETARG_INT32(1);	Interval   *result;	result = palloc(sizeof(Interval));	*result = *interval;	AdjustIntervalForTypmod(result, typmod);	PG_RETURN_INTERVAL_P(result);}/* *	Adjust interval for specified precision, in both YEAR to SECOND *	range and sub-second precision. */static voidAdjustIntervalForTypmod(Interval *interval, int32 typmod){#ifdef HAVE_INT64_TIMESTAMP	static const int64 IntervalScales[MAX_INTERVAL_PRECISION + 1] = {		INT64CONST(1000000),		INT64CONST(100000),		INT64CONST(10000),		INT64CONST(1000),		INT64CONST(100),		INT64CONST(10),		INT64CONST(1)	};	static const int64 IntervalOffsets[MAX_INTERVAL_PRECISION + 1] = {		INT64CONST(500000),		INT64CONST(50000),		INT64CONST(5000),		INT64CONST(500),		INT64CONST(50),		INT64CONST(5),		INT64CONST(0)	};#else	static const double IntervalScales[MAX_INTERVAL_PRECISION + 1] = {		1,		10,		100,		1000,		10000,		100000,		1000000	};#endif	/*	 * Unspecified range and precision? Then not necessary to adjust. Setting	 * typmod to -1 is the convention for all types.	 */	if (typmod != -1)	{		int			range = INTERVAL_RANGE(typmod);		int			precision = INTERVAL_PRECISION(typmod);		if (range == INTERVAL_FULL_RANGE)		{			/* Do nothing... */		}		else if (range == INTERVAL_MASK(YEAR))		{			interval->month = (interval->month / MONTHS_PER_YEAR) * MONTHS_PER_YEAR;			interval->day = 0;			interval->time = 0;		}		else if (range == INTERVAL_MASK(MONTH))		{			interval->month %= MONTHS_PER_YEAR;			interval->day = 0;			interval->time = 0;		}		/* YEAR TO MONTH */		else if (range == (INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH)))		{			/* month is already year to month */			interval->day = 0;			interval->time = 0;		}		else if (range == INTERVAL_MASK(DAY))		{			interval->month = 0;			interval->time = 0;		}		else if (range == INTERVAL_MASK(HOUR))		{			interval->month = 0;			interval->day = 0;#ifdef HAVE_INT64_TIMESTAMP			interval->time = (interval->time / USECS_PER_HOUR) *				USECS_PER_HOUR;#else			interval->time = ((int) (interval->time / SECS_PER_HOUR)) * (double) SECS_PER_HOUR;#endif		}		else if (range == INTERVAL_MASK(MINUTE))		{#ifdef HAVE_INT64_TIMESTAMP			int64		hour;#else			double		hour;#endif			interval->month = 0;			interval->day = 0;#ifdef HAVE_INT64_TIMESTAMP			hour = interval->time / USECS_PER_HOUR;			interval->time -= hour * USECS_PER_HOUR;			interval->time = (interval->time / USECS_PER_MINUTE) *				USECS_PER_MINUTE;#else			TMODULO(interval->time, hour, (double) SECS_PER_HOUR);			interval->time = ((int) (interval->time / SECS_PER_MINUTE)) * (double) SECS_PER_MINUTE;#endif		}		else if (range == INTERVAL_MASK(SECOND))		{#ifdef HAVE_INT64_TIMESTAMP			int64		minute;#else			double		minute;#endif			interval->month = 0;			interval->day = 0;#ifdef HAVE_INT64_TIMESTAMP			minute = interval->time / USECS_PER_MINUTE;			interval->time -= minute * USECS_PER_MINUTE;#else			TMODULO(interval->time, minute, (double) SECS_PER_MINUTE);			/* return subseconds too */#endif		}		/* DAY TO HOUR */		else if (range == (INTERVAL_MASK(DAY) |						   INTERVAL_MASK(HOUR)))		{			interval->month = 0;#ifdef HAVE_INT64_TIMESTAMP			interval->time = (interval->time / USECS_PER_HOUR) *				USECS_PER_HOUR;#else			interval->time = ((int) (interval->time / SECS_PER_HOUR)) * (double) SECS_PER_HOUR;#endif		}		/* DAY TO MINUTE */		else if (range == (INTERVAL_MASK(DAY) |						   INTERVAL_MASK(HOUR) |						   INTERVAL_MASK(MINUTE)))		{			interval->month = 0;#ifdef HAVE_INT64_TIMESTAMP			interval->time = (interval->time / USECS_PER_MINUTE) *				USECS_PER_MINUTE;#else			interval->time = ((int) (interval->time / SECS_PER_MINUTE)) * (double) SECS_PER_MINUTE;#endif		}		/* DAY TO SECOND */		else if (range == (INTERVAL_MASK(DAY) |						   INTERVAL_MASK(HOUR) |						   INTERVAL_MASK(MINUTE) |						   INTERVAL_MASK(SECOND)))			interval->month = 0;		/* HOUR TO MINUTE */		else if (range == (INTERVAL_MASK(HOUR) |						   INTERVAL_MASK(MINUTE)))		{			interval->month = 0;			interval->day = 0;#ifdef HAVE_INT64_TIMESTAMP			interval->time = (interval->time / USECS_PER_MINUTE) *				USECS_PER_MINUTE;#else			interval->time = ((int) (interval->time / SECS_PER_MINUTE)) * (double) SECS_PER_MINUTE;#endif		}		/* HOUR TO SECOND */		else if (range == (INTERVAL_MASK(HOUR) |						   INTERVAL_MASK(MINUTE) |						   INTERVAL_MASK(SECOND)))		{			interval->month = 0;			interval->day = 0;			/* return subseconds too */		}		/* MINUTE TO SECOND */		else if (range == (INTERVAL_MASK(MINUTE) |						   INTERVAL_MASK(SECOND)))		{#ifdef HAVE_INT64_TIMESTAMP			int64		hour;#else			double		hour;#endif			interval->month = 0;			interval->day = 0;#ifdef HAVE_INT64_TIMESTAMP			hour = interval->time / USECS_PER_HOUR;			interval->time -= hour * USECS_PER_HOUR;#else			TMODULO(interval->time, hour, (double) SECS_PER_HOUR);#endif		}		else			elog(ERROR, "unrecognized interval typmod: %d", typmod);		/* Need to adjust subsecond precision? */		if (precision != INTERVAL_FULL_PRECISION)		{			if (precision < 0 || precision > MAX_INTERVAL_PRECISION)				ereport(ERROR,						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				   errmsg("interval(%d) precision must be between %d and %d",						  precision, 0, MAX_INTERVAL_PRECISION)));			/*			 * Note: this round-to-nearest code is not completely consistent			 * about rounding values that are exactly halfway between integral			 * values.	On most platforms, rint() will implement			 * round-to-nearest-even, but the integer code always rounds up			 * (away from zero).  Is it worth trying to be consistent?			 */#ifdef HAVE_INT64_TIMESTAMP			if (interval->time >= INT64CONST(0))			{				interval->time = ((interval->time +								   IntervalOffsets[precision]) /								  IntervalScales[precision]) *					IntervalScales[precision];			}			else			{				interval->time = -(((-interval->time +

⌨️ 快捷键说明

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