nabstime.c

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

C
1,745
字号
}Datumabstimege(PG_FUNCTION_ARGS){	AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);	AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);	PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) >= 0);}Datumbtabstimecmp(PG_FUNCTION_ARGS){	AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);	AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);	PG_RETURN_INT32(abstime_cmp_internal(t1, t2));}/* timestamp_abstime() * Convert timestamp to abstime. */Datumtimestamp_abstime(PG_FUNCTION_ARGS){	Timestamp	timestamp = PG_GETARG_TIMESTAMP(0);	AbsoluteTime result;	fsec_t		fsec;	int			tz;	struct tm	tt,			   *tm = &tt;	if (TIMESTAMP_IS_NOBEGIN(timestamp))		result = NOSTART_ABSTIME;	else if (TIMESTAMP_IS_NOEND(timestamp))		result = NOEND_ABSTIME;	else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0)	{		tz = DetermineLocalTimeZone(tm);		result = tm2abstime(tm, tz);	}	else	{		ereport(ERROR,				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),				 errmsg("timestamp out of range")));		result = INVALID_ABSTIME;	}	PG_RETURN_ABSOLUTETIME(result);}/* abstime_timestamp() * Convert abstime to timestamp. */Datumabstime_timestamp(PG_FUNCTION_ARGS){	AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);	Timestamp	result;	struct tm	tt,			   *tm = &tt;	int			tz;	char		zone[MAXDATELEN + 1],			   *tzn = zone;	switch (abstime)	{		case INVALID_ABSTIME:			ereport(ERROR,					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),			 errmsg("cannot convert abstime \"invalid\" to timestamp")));			TIMESTAMP_NOBEGIN(result);			break;		case NOSTART_ABSTIME:			TIMESTAMP_NOBEGIN(result);			break;		case NOEND_ABSTIME:			TIMESTAMP_NOEND(result);			break;		default:			abstime2tm(abstime, &tz, tm, &tzn);			if (tm2timestamp(tm, 0, NULL, &result) != 0)				ereport(ERROR,						(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),						 errmsg("timestamp out of range")));			break;	};	PG_RETURN_TIMESTAMP(result);}/* timestamptz_abstime() * Convert timestamp with time zone to abstime. */Datumtimestamptz_abstime(PG_FUNCTION_ARGS){	TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);	AbsoluteTime result;	fsec_t		fsec;	struct tm	tt,			   *tm = &tt;	if (TIMESTAMP_IS_NOBEGIN(timestamp))		result = NOSTART_ABSTIME;	else if (TIMESTAMP_IS_NOEND(timestamp))		result = NOEND_ABSTIME;	else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0)		result = tm2abstime(tm, 0);	else	{		ereport(ERROR,				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),				 errmsg("timestamp out of range")));		result = INVALID_ABSTIME;	}	PG_RETURN_ABSOLUTETIME(result);}/* abstime_timestamptz() * Convert abstime to timestamp with time zone. */Datumabstime_timestamptz(PG_FUNCTION_ARGS){	AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);	TimestampTz result;	struct tm	tt,			   *tm = &tt;	int			tz;	char		zone[MAXDATELEN + 1],			   *tzn = zone;	switch (abstime)	{		case INVALID_ABSTIME:			ereport(ERROR,					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),			 errmsg("cannot convert abstime \"invalid\" to timestamp")));			TIMESTAMP_NOBEGIN(result);			break;		case NOSTART_ABSTIME:			TIMESTAMP_NOBEGIN(result);			break;		case NOEND_ABSTIME:			TIMESTAMP_NOEND(result);			break;		default:			abstime2tm(abstime, &tz, tm, &tzn);			if (tm2timestamp(tm, 0, &tz, &result) != 0)				ereport(ERROR,						(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),						 errmsg("timestamp out of range")));			break;	};	PG_RETURN_TIMESTAMP(result);}/***************************************************************************** *	 USER I/O ROUTINES														 * *****************************************************************************//* *		reltimein		- converts a reltime string in an internal format */Datumreltimein(PG_FUNCTION_ARGS){	char	   *str = PG_GETARG_CSTRING(0);	RelativeTime result;	struct tm	tt,			   *tm = &tt;	fsec_t		fsec;	int			dtype;	int			dterr;	char	   *field[MAXDATEFIELDS];	int			nf,				ftype[MAXDATEFIELDS];	char		lowstr[MAXDATELEN + 1];	if (strlen(str) >= sizeof(lowstr))		dterr = DTERR_BAD_FORMAT;	else		dterr = ParseDateTime(str, lowstr, 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, "reltime");	}	switch (dtype)	{		case DTK_DELTA:			result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec);			result += ((tm->tm_year * 36525 * 864) + (((tm->tm_mon * 30) + tm->tm_mday) * 86400));			break;		default:			elog(ERROR, "unexpected dtype %d while parsing reltime \"%s\"",				 dtype, str);			result = INVALID_RELTIME;			break;	}	PG_RETURN_RELATIVETIME(result);}/* *		reltimeout		- converts the internal format to a reltime string */Datumreltimeout(PG_FUNCTION_ARGS){	RelativeTime time = PG_GETARG_RELATIVETIME(0);	char	   *result;	struct tm	tt,			   *tm = &tt;	char		buf[MAXDATELEN + 1];	reltime2tm(time, tm);	EncodeInterval(tm, 0, DateStyle, buf);	result = pstrdup(buf);	PG_RETURN_CSTRING(result);}/* *		reltimerecv			- converts external binary format to reltime */Datumreltimerecv(PG_FUNCTION_ARGS){	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);	PG_RETURN_RELATIVETIME((RelativeTime) pq_getmsgint(buf, sizeof(RelativeTime)));}/* *		reltimesend			- converts reltime to binary format */Datumreltimesend(PG_FUNCTION_ARGS){	RelativeTime time = PG_GETARG_RELATIVETIME(0);	StringInfoData buf;	pq_begintypsend(&buf);	pq_sendint(&buf, time, sizeof(time));	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}static voidreltime2tm(RelativeTime time, struct tm * tm){	double		dtime = time;	FMODULO(dtime, tm->tm_year, 31557600);	FMODULO(dtime, tm->tm_mon, 2592000);	FMODULO(dtime, tm->tm_mday, 86400);	FMODULO(dtime, tm->tm_hour, 3600);	FMODULO(dtime, tm->tm_min, 60);	FMODULO(dtime, tm->tm_sec, 1);}/* *		tintervalin		- converts an interval string to internal format */Datumtintervalin(PG_FUNCTION_ARGS){	char	   *intervalstr = PG_GETARG_CSTRING(0);	TimeInterval interval;	AbsoluteTime i_start,				i_end,				t1,				t2;	interval = (TimeInterval) palloc(sizeof(TimeIntervalData));	if (istinterval(intervalstr, &t1, &t2) == 0)		ereport(ERROR,				(errcode(ERRCODE_INVALID_DATETIME_FORMAT),				 errmsg("invalid input syntax for type tinterval: \"%s\"",						intervalstr)));	if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)		interval->status = T_INTERVAL_INVAL;	/* undefined  */	else		interval->status = T_INTERVAL_VALID;	i_start = ABSTIMEMIN(t1, t2);	i_end = ABSTIMEMAX(t1, t2);	interval->data[0] = i_start;	interval->data[1] = i_end;	PG_RETURN_TIMEINTERVAL(interval);}/* *		tintervalout	- converts an internal interval format to a string */Datumtintervalout(PG_FUNCTION_ARGS){	TimeInterval interval = PG_GETARG_TIMEINTERVAL(0);	char	   *i_str,			   *p;	i_str = (char *) palloc(T_INTERVAL_LEN);	/* ["..." "..."] */	strcpy(i_str, "[\"");	if (interval->status == T_INTERVAL_INVAL)		strcat(i_str, INVALID_INTERVAL_STR);	else	{		p = DatumGetCString(DirectFunctionCall1(abstimeout,							   AbsoluteTimeGetDatum(interval->data[0])));		strcat(i_str, p);		pfree(p);		strcat(i_str, "\" \"");		p = DatumGetCString(DirectFunctionCall1(abstimeout,							   AbsoluteTimeGetDatum(interval->data[1])));		strcat(i_str, p);		pfree(p);	}	strcat(i_str, "\"]");	PG_RETURN_CSTRING(i_str);}/* *		tintervalrecv			- converts external binary format to tinterval */Datumtintervalrecv(PG_FUNCTION_ARGS){	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);	TimeInterval interval;	interval = (TimeInterval) palloc(sizeof(TimeIntervalData));	interval->status = pq_getmsgint(buf, sizeof(interval->status));	if (!(interval->status == T_INTERVAL_INVAL ||		  interval->status == T_INTERVAL_VALID))		ereport(ERROR,				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),				 errmsg("invalid status in external \"tinterval\" value")));	interval->data[0] = pq_getmsgint(buf, sizeof(interval->data[0]));	interval->data[1] = pq_getmsgint(buf, sizeof(interval->data[1]));	PG_RETURN_TIMEINTERVAL(interval);}/* *		tintervalsend			- converts tinterval to binary format */Datumtintervalsend(PG_FUNCTION_ARGS){	TimeInterval interval = PG_GETARG_TIMEINTERVAL(0);	StringInfoData buf;	pq_begintypsend(&buf);	pq_sendint(&buf, interval->status, sizeof(interval->status));	pq_sendint(&buf, interval->data[0], sizeof(interval->data[0]));	pq_sendint(&buf, interval->data[1], sizeof(interval->data[1]));	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}/***************************************************************************** *	 PUBLIC ROUTINES														 * *****************************************************************************/Datuminterval_reltime(PG_FUNCTION_ARGS){	Interval   *interval = PG_GETARG_INTERVAL_P(0);	RelativeTime time;	int			year,				month;#ifdef HAVE_INT64_TIMESTAMP	int64		span;#else	double		span;#endif	if (interval->month == 0)	{		year = 0;		month = 0;	}	else if (abs(interval->month) >= 12)	{		year = (interval->month / 12);		month = (interval->month % 12);	}	else	{		year = 0;		month = interval->month;	}#ifdef HAVE_INT64_TIMESTAMP	span = ((((INT64CONST(365250000) * year) + (INT64CONST(30000000) * month))			 * INT64CONST(86400)) + interval->time);	span /= INT64CONST(1000000);#else	span = (((((double) 365.25 * year) + ((double) 30 * month)) * 86400) + interval->time);#endif	if ((span < INT_MIN) || (span > INT_MAX))		time = INVALID_RELTIME;	else		time = span;	PG_RETURN_RELATIVETIME(time);}Datumreltime_interval(PG_FUNCTION_ARGS){	RelativeTime reltime = PG_GETARG_RELATIVETIME(0);	Interval   *result;	int			year,				month;	result = (Interval *) palloc(sizeof(Interval));	switch (reltime)	{		case INVALID_RELTIME:			ereport(ERROR,					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),			  errmsg("cannot convert reltime \"invalid\" to interval")));			result->time = 0;			result->month = 0;			break;		default:#ifdef HAVE_INT64_TIMESTAMP			year = (reltime / (36525 * 864));			reltime -= (year * (36525 * 864));			month = (reltime / (30 * 86400));			reltime -= (month * (30 * 86400));			result->time = (reltime * INT64CONST(1000000));#else			TMODULO(reltime, year, (36525 * 864));			TMODULO(reltime, month, (30 * 86400));			result->time = reltime;#endif			result->month = ((12 * year) + month);			break;	}	PG_RETURN_INTERVAL_P(result);}/* *		mktinterval		- creates a time interval with endpoints t1 and t2 */Datummktinterval(PG_FUNCTION_ARGS){	AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);	AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);	AbsoluteTime tstart = ABSTIMEMIN(t1, t2);	AbsoluteTime tend = ABSTIMEMAX(t1, t2);	TimeInterval interval;	interval = (TimeInterval) palloc(sizeof(TimeIntervalData));	if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)		interval->status = T_INTERVAL_INVAL;	else	{		interval->status = T_INTERVAL_VALID;		interval->data[0] = tstart;		interval->data[1] = tend;	}	PG_RETURN_TIMEINTERVAL(interval);}/* *		timepl, timemi and abstimemi use the formula *				abstime + reltime = abstime *		so		abstime - reltime = abstime *		and		abstime - abstime = reltime *//* *		timepl			- returns the value of (abstime t1 + reltime t2) */Datumtimepl(PG_FUNCTION_ARGS){	AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);	RelativeTime t2 = PG_GETARG_RELATIVETIME(1);	if (AbsoluteTimeIsReal(t1) &&		RelativeTimeIsValid(t2) &&		((t2 > 0) ? (t1 < NOEND_ABSTIME - t2)		 : (t1 > NOSTART_ABSTIME - t2)))		/* prevent overflow */		PG_RETURN_ABSOLUTETIME(t1 + t2);	PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME);}/* *		timemi			- returns the value of (abstime t1 - reltime t2) */Datumtimemi(PG_FUNCTION_ARGS){	AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);	RelativeTime t2 = PG_GETARG_RELATIVETIME(1);	if (AbsoluteTimeIsReal(t1) &&		RelativeTimeIsValid(t2) &&		((t2 > 0) ? (t1 > NOSTART_ABSTIME + t2)		 : (t1 < NOEND_ABSTIME + t2)))	/* prevent overflow */		PG_RETURN_ABSOLUTETIME(t1 - t2);	PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME);}/* *		intinterval		- returns true iff absolute date is in the interval */Datumintinterval(PG_FUNCTION_ARGS){	AbsoluteTime t = PG_GETARG_ABSOLUTETIME(0);	TimeInterval interval = PG_GETARG_TIMEINTERVAL(1);	if (interval->status == T_INTERVAL_VALID && t != INVALID_ABSTIME)	{		if (DatumGetBool(DirectFunctionCall2(abstimege,											 AbsoluteTimeGetDatum(t),							 AbsoluteTimeGetDatum(interval->data[0]))) &&			DatumGetBool(DirectFunctionCall2(abstimele,											 AbsoluteTimeGetDatum(t),							   AbsoluteTimeGetDatum(interval->data[1]))))			PG_RETURN_BOOL(true);	}	PG_RETURN_BOOL(false);}/* *		tintervalrel		- returns  relative time corresponding to interval */Datumtintervalrel(PG_FUNCTION_ARGS){	TimeInterval interval = PG_GETARG_TIMEINTERVAL(0);	AbsoluteTime t1 = interval->data[0];

⌨️ 快捷键说明

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