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

📄 timestamp.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		if (tm->tm_sec < 0)		{			tm->tm_sec += 60;			tm->tm_min--;		}		if (tm->tm_min < 0)		{			tm->tm_min += 60;			tm->tm_hour--;		}		if (tm->tm_hour < 0)		{			tm->tm_hour += 24;			tm->tm_mday--;		}		if (tm->tm_mday < 0)		{			if (dt1 < dt2)			{				tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];				tm->tm_mon--;			}			else			{				tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];				tm->tm_mon--;			}		}		if (tm->tm_mon < 0)		{			tm->tm_mon += 12;			tm->tm_year--;		}		/* recover sign if necessary... */		if (dt1 < dt2)		{			fsec = -fsec;			tm->tm_sec = -tm->tm_sec;			tm->tm_min = -tm->tm_min;			tm->tm_hour = -tm->tm_hour;			tm->tm_mday = -tm->tm_mday;			tm->tm_mon = -tm->tm_mon;			tm->tm_year = -tm->tm_year;		}		if (tm2interval(tm, fsec, result) != 0)			ereport(ERROR,					(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),					 errmsg("interval out of range")));	}	else		ereport(ERROR,				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),				 errmsg("timestamp out of range")));	PG_RETURN_INTERVAL_P(result);}/*---------------------------------------------------------- *	Conversion operators. *---------------------------------------------------------*//* timestamp_text() * Convert timestamp to text data type. */Datumtimestamp_text(PG_FUNCTION_ARGS){	/* Input is a Timestamp, but may as well leave it in Datum form */	Datum		timestamp = PG_GETARG_DATUM(0);	text	   *result;	char	   *str;	int			len;	str = DatumGetCString(DirectFunctionCall1(timestamp_out, timestamp));	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_timestamp() * Convert text string to timestamp. * Text type is not null terminated, so use temporary string *	then call the standard input routine. */Datumtext_timestamp(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 timestamp: \"%s\"",						DatumGetCString(DirectFunctionCall1(textout,											   PointerGetDatum(str))))));	sp = VARDATA(str);	dp = dstr;	for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)		*dp++ = *sp++;	*dp = '\0';	return DirectFunctionCall3(timestamp_in,							   CStringGetDatum(dstr),							   ObjectIdGetDatum(InvalidOid),							   Int32GetDatum(-1));}/* timestamptz_text() * Convert timestamp with time zone to text data type. */Datumtimestamptz_text(PG_FUNCTION_ARGS){	/* Input is a Timestamp, but may as well leave it in Datum form */	Datum		timestamp = PG_GETARG_DATUM(0);	text	   *result;	char	   *str;	int			len;	str = DatumGetCString(DirectFunctionCall1(timestamptz_out, timestamp));	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_timestamptz() * Convert text string to timestamp with time zone. * Text type is not null terminated, so use temporary string *	then call the standard input routine. */Datumtext_timestamptz(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 timestamp with time zone: \"%s\"",						DatumGetCString(DirectFunctionCall1(textout,											   PointerGetDatum(str))))));	sp = VARDATA(str);	dp = dstr;	for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)		*dp++ = *sp++;	*dp = '\0';	return DirectFunctionCall3(timestamptz_in,							   CStringGetDatum(dstr),							   ObjectIdGetDatum(InvalidOid),							   Int32GetDatum(-1));}/* interval_text() * Convert interval to text data type. */Datuminterval_text(PG_FUNCTION_ARGS){	Interval   *interval = PG_GETARG_INTERVAL_P(0);	text	   *result;	char	   *str;	int			len;	str = DatumGetCString(DirectFunctionCall1(interval_out,										   IntervalPGetDatum(interval)));	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_interval() * Convert text string to interval. * Text type may not be null terminated, so copy to temporary string *	then call the standard input routine. */Datumtext_interval(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 interval: \"%s\"",						DatumGetCString(DirectFunctionCall1(textout,											   PointerGetDatum(str))))));	sp = VARDATA(str);	dp = dstr;	for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)		*dp++ = *sp++;	*dp = '\0';	return DirectFunctionCall3(interval_in,							   CStringGetDatum(dstr),							   ObjectIdGetDatum(InvalidOid),							   Int32GetDatum(-1));}/* timestamp_trunc() * Truncate timestamp to specified units. */Datumtimestamp_trunc(PG_FUNCTION_ARGS){	text	   *units = PG_GETARG_TEXT_P(0);	Timestamp	timestamp = PG_GETARG_TIMESTAMP(1);	Timestamp	result;	int			type,				val;	int			i;	char	   *up,			   *lp,				lowunits[MAXDATELEN + 1];	fsec_t		fsec;	struct tm	tt,			   *tm = &tt;	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("timestamp 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 (TIMESTAMP_NOT_FINITE(timestamp))		PG_RETURN_TIMESTAMP(timestamp);	if (type == UNITS)	{		if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)			ereport(ERROR,					(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),					 errmsg("timestamp out of range")));		switch (val)		{			case DTK_MILLENNIUM:				tm->tm_year = (tm->tm_year / 1000) * 1000;			case DTK_CENTURY:				tm->tm_year = (tm->tm_year / 100) * 100;			case DTK_DECADE:				tm->tm_year = (tm->tm_year / 10) * 10;			case DTK_YEAR:				tm->tm_mon = 1;			case DTK_QUARTER:				tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;			case DTK_MONTH:				tm->tm_mday = 1;			case DTK_DAY:				tm->tm_hour = 0;			case DTK_HOUR:				tm->tm_min = 0;			case DTK_MINUTE:				tm->tm_sec = 0;			case DTK_SECOND:				fsec = 0;				break;			case DTK_MILLISEC:#ifdef HAVE_INT64_TIMESTAMP				fsec = ((fsec / 1000) * 1000);#else				fsec = rint(fsec * 1000) / 1000;#endif				break;			case DTK_MICROSEC:#ifndef HAVE_INT64_TIMESTAMP				fsec = rint(fsec * 1000000) / 1000000;#endif				break;			default:				ereport(ERROR,						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),						 errmsg("timestamp units \"%s\" not supported",								lowunits)));				result = 0;		}		if (tm2timestamp(tm, fsec, NULL, &result) != 0)			ereport(ERROR,					(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),					 errmsg("timestamp out of range")));	}	else	{		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("timestamp units \"%s\" not recognized",						lowunits)));		result = 0;	}	PG_RETURN_TIMESTAMP(result);}/* timestamptz_trunc() * Truncate timestamp to specified units. */Datumtimestamptz_trunc(PG_FUNCTION_ARGS){	text	   *units = PG_GETARG_TEXT_P(0);	TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1);	TimestampTz result;	int			tz;	int			type,				val;	int			i;	char	   *up,			   *lp,				lowunits[MAXDATELEN + 1];	fsec_t		fsec;	char	   *tzn;	struct tm	tt,			   *tm = &tt;	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),		   errmsg("timestamp with time zone 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 (TIMESTAMP_NOT_FINITE(timestamp))		PG_RETURN_TIMESTAMPTZ(timestamp);	if (type == UNITS)	{		if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)			ereport(ERROR,					(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),					 errmsg("timestamp out of range")));		switch (val)		{			case DTK_MILLENNIUM:				tm->tm_year = (tm->tm_year / 1000) * 1000;			case DTK_CENTURY:				tm->tm_year = (tm->tm_year / 100) * 100;			case DTK_DECADE:				tm->tm_year = (tm->tm_year / 10) * 10;			case DTK_YEAR:				tm->tm_mon = 1;			case DTK_QUARTER:				tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;			case DTK_MONTH:				tm->tm_mday = 1;			case DTK_DAY:				tm->tm_hour = 0;			case DTK_HOUR:				tm->tm_min = 0;			case DTK_MINUTE:				tm->tm_sec = 0;			case DTK_SECOND:				fsec = 0;				break;			case DTK_MILLISEC:#ifdef HAVE_INT64_TIMESTAMP				fsec = ((fsec / 1000) * 1000);#else				fsec = rint(fsec * 1000) / 1000;#endif				break;			case DTK_MICROSEC:#ifndef HAVE_INT64_TIMESTAMP				fsec = rint(fsec * 1000000) / 1000000;#endif				break;			default:				ereport(ERROR,						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),					  errmsg("timestamp with time zone units \"%s\" not "							 "supported", lowunits)));				result = 0;		}		tz = DetermineLocalTimeZone(tm);		if (tm2timestamp(tm, fsec, &tz, &result) != 0)			ereport(ERROR,					(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),					 errmsg("timestamp out of range")));	}	else	{		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),		   errmsg("timestamp with time zone units \"%s\" not recognized",				  lowunits)));		result = 0;	}	PG_RETURN_TIMESTAMPTZ(result);}/* interval_trunc() * Extract specified field from interval. */Datuminterval_trunc(PG_FUNCTION_ARGS){	text	   *units = PG_GETARG_TEXT_P(0);	Interval   *interval = PG_GETARG_INTERVAL_P(1);	Interval   *result;	int			type,				val;	int			i;	char	   *up,			   *lp,				lowunits[MAXDATELEN + 1];	fsec_t		fsec;	struct tm	tt,			   *tm = &tt;	result = (Interval *) palloc(sizeof(Interval));	if (VARSIZE(units) - VARHDRSZ > MAXDATELEN)		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("interval 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 == UNITS)	{		if (interval2tm(*interval, tm, &fsec) == 0)		{			switch (val)			{				case DTK_MILLENNIUM:					tm->tm_year = (tm->tm_year / 1000) * 1000;				case DTK_CENTURY:					tm->tm_year = (tm->tm_year / 100) * 100;				case DTK_DECADE:					tm->tm_year = (tm->tm_year / 10) * 10;				case DTK_YEAR:					tm->tm_mon = 0;				case DTK_QUARTER:					tm->tm_mon = (3 * (tm->tm_mon / 3));				case DTK_MONTH:					tm->tm_mday = 0;				case DTK_DAY:					tm->tm_hour = 0;				case DTK_HOUR:					tm->tm_min = 0;				case DTK_MINUTE:					tm->tm_sec = 0;				case DTK_SECOND:					fsec = 0;					break;				case DTK_MILLISEC:#ifdef HAVE_INT64_TIMESTAMP					fsec = ((fsec / 1000) * 1000);#else					fsec = rint(fsec * 1000) / 1000;#endif					break;				case DTK_MICROSEC:#ifndef HAVE_INT64_TIMESTAMP					fsec = rint(fsec * 1000000) / 1000000;#endif					break;				default:					ereport(ERROR,							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),							 errmsg("interval units \"%s\" not supported",									lowunits)));			}			if (tm2interval(tm, fsec, result) != 0)				ereport(ERROR,						(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),						 errmsg("interval out of range")));		}		else			elog(ERROR, "could not convert interval to tm");	}	else	{		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("interval units \"%s\" not recognized",						DatumGetCString(DirectFunctionCall1(textout,											 Pointe

⌨️ 快捷键说明

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