date.c

来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 2,274 行 · 第 1/4 页

C
2,274
字号
	result->month = 0;	PG_RETURN_INTERVAL_P(result);}/* time_pl_interval() * Add interval to time. */Datumtime_pl_interval(PG_FUNCTION_ARGS){	TimeADT		time = PG_GETARG_TIMEADT(0);	Interval   *span = PG_GETARG_INTERVAL_P(1);	TimeADT		result;#ifdef HAVE_INT64_TIMESTAMP	result = (time + span->time);	result -= (result / INT64CONST(86400000000) * INT64CONST(86400000000));	if (result < INT64CONST(0))		result += INT64CONST(86400000000);#else	TimeADT		time1;	result = (time + span->time);	TMODULO(result, time1, 86400e0);	if (result < 0)		result += 86400;#endif	PG_RETURN_TIMEADT(result);}/* time_mi_interval() * Subtract interval from time. */Datumtime_mi_interval(PG_FUNCTION_ARGS){	TimeADT		time = PG_GETARG_TIMEADT(0);	Interval   *span = PG_GETARG_INTERVAL_P(1);	TimeADT		result;#ifdef HAVE_INT64_TIMESTAMP	result = (time - span->time);	result -= (result / INT64CONST(86400000000) * INT64CONST(86400000000));	if (result < INT64CONST(0))		result += INT64CONST(86400000000);#else	TimeADT		time1;	result = (time - span->time);	TMODULO(result, time1, 86400e0);	if (result < 0)		result += 86400;#endif	PG_RETURN_TIMEADT(result);}/* interval_pl_time() * Add time to interval. */Datuminterval_pl_time(PG_FUNCTION_ARGS){	Datum		span = PG_GETARG_DATUM(0);	Datum		time = PG_GETARG_DATUM(1);	return DirectFunctionCall2(time_pl_interval, time, span);}/* time_text() * Convert time to text data type. */Datumtime_text(PG_FUNCTION_ARGS){	/* Input is a Time, but may as well leave it in Datum form */	Datum		time = PG_GETARG_DATUM(0);	text	   *result;	char	   *str;	int			len;	str = DatumGetCString(DirectFunctionCall1(time_out, time));	len = (strlen(str) + VARHDRSZ);	result = palloc(len);	VARATT_SIZEP(result) = len;	memmove(VARDATA(result), str, (len - VARHDRSZ));	pfree(str);	PG_RETURN_TEXT_P(result);}/* text_time() * Convert text string to time. * Text type is not null terminated, so use temporary string *	then call the standard input routine. */Datumtext_time(PG_FUNCTION_ARGS){	text	   *str = PG_GETARG_TEXT_P(0);	int			i;	char	   *sp,			   *dp,				dstr[MAXDATELEN + 1];	if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)		ereport(ERROR,				(errcode(ERRCODE_INVALID_DATETIME_FORMAT),				 errmsg("invalid input syntax for type time: \"%s\"",						VARDATA(str))));	sp = VARDATA(str);	dp = dstr;	for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)		*dp++ = *sp++;	*dp = '\0';	return DirectFunctionCall3(time_in,							   CStringGetDatum(dstr),							   ObjectIdGetDatum(InvalidOid),							   Int32GetDatum(-1));}/* time_part() * Extract specified field from time type. */Datumtime_part(PG_FUNCTION_ARGS){	text	   *units = PG_GETARG_TEXT_P(0);	TimeADT		time = PG_GETARG_TIMEADT(1);	float8		result;	int			type,				val;	int			i;	char	   *up,			   *lp,				lowunits[MAXDATELEN + 1];	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("\"time\" units \"%s\" not recognized",						DatumGetCString(DirectFunctionCall1(textout,											 PointerGetDatum(units))))));	up = VARDATA(units);	lp = lowunits;	for (i = 0; i < (VARSIZE(units) - VARHDRSZ); i++)		*lp++ = tolower((unsigned char) *up++);	*lp = '\0';	type = DecodeUnits(0, lowunits, &val);	if (type == UNKNOWN_FIELD)		type = DecodeSpecial(0, lowunits, &val);	if (type == UNITS)	{		fsec_t		fsec;		struct tm	tt,				   *tm = &tt;		time2tm(time, tm, &fsec);		switch (val)		{			case DTK_MICROSEC:#ifdef HAVE_INT64_TIMESTAMP				result = ((tm->tm_sec * INT64CONST(1000000)) + fsec);#else				result = ((tm->tm_sec + fsec) * 1000000);#endif				break;			case DTK_MILLISEC:#ifdef HAVE_INT64_TIMESTAMP				result = ((tm->tm_sec * INT64CONST(1000))						  + (fsec / INT64CONST(1000)));#else				result = ((tm->tm_sec + fsec) * 1000);#endif				break;			case DTK_SECOND:#ifdef HAVE_INT64_TIMESTAMP				result = (tm->tm_sec + (fsec / INT64CONST(1000000)));#else				result = (tm->tm_sec + fsec);#endif				break;			case DTK_MINUTE:				result = tm->tm_min;				break;			case DTK_HOUR:				result = tm->tm_hour;				break;			case DTK_TZ:			case DTK_TZ_MINUTE:			case DTK_TZ_HOUR:			case DTK_DAY:			case DTK_MONTH:			case DTK_QUARTER:			case DTK_YEAR:			case DTK_DECADE:			case DTK_CENTURY:			case DTK_MILLENNIUM:			default:				ereport(ERROR,						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),						 errmsg("\"time\" units \"%s\" not recognized",							 DatumGetCString(DirectFunctionCall1(textout,											 PointerGetDatum(units))))));				result = 0;		}	}	else if ((type == RESERV) && (val == DTK_EPOCH))	{#ifdef HAVE_INT64_TIMESTAMP		result = (time / 1000000e0);#else		result = time;#endif	}	else	{		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("\"time\" units \"%s\" not recognized",						DatumGetCString(DirectFunctionCall1(textout,											 PointerGetDatum(units))))));		result = 0;	}	PG_RETURN_FLOAT8(result);}/***************************************************************************** *	 Time With Time Zone ADT *****************************************************************************//* tm2timetz() * Convert a tm structure to a time data type. */static inttm2timetz(struct tm * tm, fsec_t fsec, int tz, TimeTzADT *result){#ifdef HAVE_INT64_TIMESTAMP	result->time = ((((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec)					 * INT64CONST(1000000)) + fsec);#else	result->time = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);#endif	result->zone = tz;	return 0;}Datumtimetz_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);	TimeTzADT  *result;	fsec_t		fsec;	struct tm	tt,			   *tm = &tt;	int			tz;	int			nf;	int			dterr;	char		lowstr[MAXDATELEN + 1];	char	   *field[MAXDATEFIELDS];	int			dtype;	int			ftype[MAXDATEFIELDS];	if (strlen(str) >= sizeof(lowstr))		dterr = DTERR_BAD_FORMAT;	else		dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);	if (dterr == 0)		dterr = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz);	if (dterr != 0)		DateTimeParseError(dterr, str, "time with time zone");	result = (TimeTzADT *) palloc(sizeof(TimeTzADT));	tm2timetz(tm, fsec, tz, result);	AdjustTimeForTypmod(&(result->time), typmod);	PG_RETURN_TIMETZADT_P(result);}Datumtimetz_out(PG_FUNCTION_ARGS){	TimeTzADT  *time = PG_GETARG_TIMETZADT_P(0);	char	   *result;	struct tm	tt,			   *tm = &tt;	fsec_t		fsec;	int			tz;	char		buf[MAXDATELEN + 1];	timetz2tm(time, tm, &fsec, &tz);	EncodeTimeOnly(tm, fsec, &tz, DateStyle, buf);	result = pstrdup(buf);	PG_RETURN_CSTRING(result);}/* *		timetz_recv			- converts external binary format to timetz */Datumtimetz_recv(PG_FUNCTION_ARGS){	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);	TimeTzADT  *time;	time = (TimeTzADT *) palloc(sizeof(TimeTzADT));#ifdef HAVE_INT64_TIMESTAMP	time->time = pq_getmsgint64(buf);#else	time->time = pq_getmsgfloat8(buf);#endif	time->zone = pq_getmsgint(buf, sizeof(time->zone));	PG_RETURN_TIMETZADT_P(time);}/* *		timetz_send			- converts timetz to binary format */Datumtimetz_send(PG_FUNCTION_ARGS){	TimeTzADT  *time = PG_GETARG_TIMETZADT_P(0);	StringInfoData buf;	pq_begintypsend(&buf);#ifdef HAVE_INT64_TIMESTAMP	pq_sendint64(&buf, time->time);#else	pq_sendfloat8(&buf, time->time);#endif	pq_sendint(&buf, time->zone, sizeof(time->zone));	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}/* timetz2tm() * Convert TIME WITH TIME ZONE data type to POSIX time structure. */static inttimetz2tm(TimeTzADT *time, struct tm * tm, fsec_t *fsec, int *tzp){#ifdef HAVE_INT64_TIMESTAMP	int64		trem = time->time;	tm->tm_hour = (trem / INT64CONST(3600000000));	trem -= (tm->tm_hour * INT64CONST(3600000000));	tm->tm_min = (trem / INT64CONST(60000000));	trem -= (tm->tm_min * INT64CONST(60000000));	tm->tm_sec = (trem / INT64CONST(1000000));	*fsec = (trem - (tm->tm_sec * INT64CONST(1000000)));#else	double		trem = time->time;	TMODULO(trem, tm->tm_hour, 3600e0);	TMODULO(trem, tm->tm_min, 60e0);	TMODULO(trem, tm->tm_sec, 1e0);	*fsec = trem;#endif	if (tzp != NULL)		*tzp = time->zone;	return 0;}/* timetz_scale() * Adjust time type for specified scale factor. * Used by PostgreSQL type system to stuff columns. */Datumtimetz_scale(PG_FUNCTION_ARGS){	TimeTzADT  *time = PG_GETARG_TIMETZADT_P(0);	int32		typmod = PG_GETARG_INT32(1);	TimeTzADT  *result;	result = (TimeTzADT *) palloc(sizeof(TimeTzADT));	result->time = time->time;	result->zone = time->zone;	AdjustTimeForTypmod(&(result->time), typmod);	PG_RETURN_TIMETZADT_P(result);}static inttimetz_cmp_internal(TimeTzADT *time1, TimeTzADT *time2){	double		t1,				t2;	/* Primary sort is by true (GMT-equivalent) time */	t1 = time1->time + time1->zone;	t2 = time2->time + time2->zone;	if (t1 > t2)		return 1;	if (t1 < t2)		return -1;	/*	 * If same GMT time, sort by timezone; we only want to say that two	 * timetz's are equal if both the time and zone parts are equal.	 */	if (time1->zone > time2->zone)		return 1;	if (time1->zone < time2->zone)		return -1;	return 0;}Datumtimetz_eq(PG_FUNCTION_ARGS){	TimeTzADT  *time1 = PG_GETARG_TIMETZADT_P(0);	TimeTzADT  *time2 = PG_GETARG_TIMETZADT_P(1);	PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) == 0);}Datumtimetz_ne(PG_FUNCTION_ARGS){	TimeTzADT  *time1 = PG_GETARG_TIMETZADT_P(0);	TimeTzADT  *time2 = PG_GETARG_TIMETZADT_P(1);	PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) != 0);}Datumtimetz_lt(PG_FUNCTION_ARGS){	TimeTzADT  *time1 = PG_GETARG_TIMETZADT_P(0);	TimeTzADT  *time2 = PG_GETARG_TIMETZADT_P(1);	PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) < 0);}Datumtimetz_le(PG_FUNCTION_ARGS){	TimeTzADT  *time1 = PG_GETARG_TIMETZADT_P(0);	TimeTzADT  *time2 = PG_GETARG_TIMETZADT_P(1);	PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) <= 0);}Datumtimetz_gt(PG_FUNCTION_ARGS){	TimeTzADT  *time1 = PG_GETARG_TIMETZADT_P(0);	TimeTzADT  *time2 = PG_GETARG_TIMETZADT_P(1);	PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) > 0);}Datumtimetz_ge(PG_FUNCTION_ARGS){	TimeTzADT  *time1 = PG_GETARG_TIMETZADT_P(0);	TimeTzADT  *time2 = PG_GETARG_TIMETZADT_P(1);	PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) >= 0);}Datumtimetz_cmp(PG_FUNCTION_ARGS){	TimeTzADT  *time1 = PG_GETARG_TIMETZADT_P(0);	TimeTzADT  *time2 = PG_GETARG_TIMETZADT_P(1);	PG_RETURN_INT32(timetz_cmp_internal(time1, time2));}/* * timetz, being an unusual size, needs a specialized hash function. */Datumtimetz_hash(PG_FUNCTION_ARGS){	TimeTzADT  *key = PG_GETARG_TIMETZADT_P(0);	/*	 * Specify hash length as sizeof(double) + sizeof(int4), not as	 * sizeof(TimeTzADT), so that any garbage pad bytes in the structure	 * won't be included in the hash!	 */	return hash_any((unsigned char *) key, sizeof(key->time) + sizeof(key->zone));}Datumtimetz_larger(PG_FUNCTION_ARGS){	TimeTzADT  *time1 = PG_GETARG_TIMETZADT_P(0);	TimeTzADT  *time2 = PG_GETARG_TIMETZADT_P(1);	TimeTzADT  *result;	if (timetz_cmp_internal(time1, time2) > 0)		result = time1;	else		result = time2;	PG_RETURN_TIMETZADT_P(result);}Datumtimetz_smaller(PG_FUNCTION_ARGS){	TimeTzADT  *time1 = PG_GETARG_TIMETZADT_P(0);	TimeTzADT  *time2 = PG_GETARG_TIMETZADT_P(1);	TimeTzADT  *result;	if (timetz_cmp_internal(time1, time2) < 0)		result = time1;	else		result = time2;	PG_RETURN_TIMETZADT_P(result);}/* timetz_pl_interval() * Add interval to timetz. */Datumtimetz_pl_interval(PG_FUNCTION_ARGS){	TimeTzADT  *time = PG_GETARG_TIMETZADT_P(0);	Interval   *span = PG_GETARG_INTERVAL_P(1);	TimeTzADT  *result;#ifndef HAVE_INT64_TIMESTAMP	TimeTzADT	time1;#endif	result = (TimeTzADT *) palloc(sizeof(TimeTzADT));#ifdef HAVE_INT64_TIMESTAMP

⌨️ 快捷键说明

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