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

📄 timestamp.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 5 页
字号:
}/* interval2tm() * Convert a interval data type to a tm structure. */intinterval2tm(Interval span, struct tm * tm, fsec_t *fsec){#ifdef HAVE_INT64_TIMESTAMP	int64		time;#else	double		time;#endif	if (span.month != 0)	{		tm->tm_year = span.month / 12;		tm->tm_mon = span.month % 12;	}	else	{		tm->tm_year = 0;		tm->tm_mon = 0;	}	time = span.time;#ifdef HAVE_INT64_TIMESTAMP	tm->tm_mday = (time / INT64CONST(86400000000));	time -= (tm->tm_mday * INT64CONST(86400000000));	tm->tm_hour = (time / INT64CONST(3600000000));	time -= (tm->tm_hour * INT64CONST(3600000000));	tm->tm_min = (time / INT64CONST(60000000));	time -= (tm->tm_min * INT64CONST(60000000));	tm->tm_sec = (time / INT64CONST(1000000));	*fsec = (time - (tm->tm_sec * INT64CONST(1000000)));#else	TMODULO(time, tm->tm_mday, 86400e0);	TMODULO(time, tm->tm_hour, 3600e0);	TMODULO(time, tm->tm_min, 60e0);	TMODULO(time, tm->tm_sec, 1e0);	*fsec = time;#endif	return 0;}inttm2interval(struct tm * tm, fsec_t fsec, Interval *span){	span->month = ((tm->tm_year * 12) + tm->tm_mon);#ifdef HAVE_INT64_TIMESTAMP	span->time = ((((((((tm->tm_mday * INT64CONST(24))						+ tm->tm_hour) * INT64CONST(60))					  + tm->tm_min) * INT64CONST(60))					+ tm->tm_sec) * INT64CONST(1000000)) + fsec);#else	span->time = ((((((tm->tm_mday * 24.0)					  + tm->tm_hour) * 60.0)					+ tm->tm_min) * 60.0)				  + tm->tm_sec);	span->time = JROUND(span->time + fsec);#endif	return 0;}#ifdef HAVE_INT64_TIMESTAMPstatic int64time2t(const int hour, const int min, const int sec, const fsec_t fsec){	return ((((((hour * 60) + min) * 60) + sec) * INT64CONST(1000000)) + fsec);}	/* time2t() */#elsestatic doubletime2t(const int hour, const int min, const int sec, const fsec_t fsec){	return ((((hour * 60) + min) * 60) + sec + fsec);}	/* time2t() */#endifstatic Timestampdt2local(Timestamp dt, int tz){#ifdef HAVE_INT64_TIMESTAMP	dt -= (tz * INT64CONST(1000000));#else	dt -= tz;	dt = JROUND(dt);#endif	return dt;}	/* dt2local() *//***************************************************************************** *	 PUBLIC ROUTINES														 * *****************************************************************************/Datumtimestamp_finite(PG_FUNCTION_ARGS){	Timestamp	timestamp = PG_GETARG_TIMESTAMP(0);	PG_RETURN_BOOL(!TIMESTAMP_NOT_FINITE(timestamp));}Datuminterval_finite(PG_FUNCTION_ARGS){	PG_RETURN_BOOL(true);}/*---------------------------------------------------------- *	Relational operators for timestamp. *---------------------------------------------------------*/voidGetEpochTime(struct tm * tm){	struct tm  *t0;	time_t		epoch = 0;	t0 = gmtime(&epoch);	tm->tm_year = t0->tm_year;	tm->tm_mon = t0->tm_mon;	tm->tm_mday = t0->tm_mday;	tm->tm_hour = t0->tm_hour;	tm->tm_min = t0->tm_min;	tm->tm_sec = t0->tm_sec;	if (tm->tm_year < 1900)		tm->tm_year += 1900;	tm->tm_mon++;	return;}	/* GetEpochTime() */TimestampSetEpochTimestamp(void){	Timestamp	dt;	struct tm	tt,			   *tm = &tt;	GetEpochTime(tm);	/* we don't bother to test for failure ... */	tm2timestamp(tm, 0, NULL, &dt);	return dt;}	/* SetEpochTimestamp() *//* * We are currently sharing some code between timestamp and timestamptz. * The comparison functions are among them. - thomas 2001-09-25 * *		timestamp_relop - is timestamp1 relop timestamp2 * *		collate invalid timestamp at the end */static inttimestamp_cmp_internal(Timestamp dt1, Timestamp dt2){#ifdef HAVE_INT64_TIMESTAMP	return ((dt1 < dt2) ? -1 : ((dt1 > dt2) ? 1 : 0));#else	/*	 * When using float representation, we have to be wary of NaNs.	 *	 * We consider all NANs to be equal and larger than any non-NAN. This is	 * somewhat arbitrary; the important thing is to have a consistent	 * sort order.	 */	if (isnan(dt1))	{		if (isnan(dt2))			return 0;			/* NAN = NAN */		else			return 1;			/* NAN > non-NAN */	}	else if (isnan(dt2))	{		return -1;				/* non-NAN < NAN */	}	else	{		if (dt1 > dt2)			return 1;		else if (dt1 < dt2)			return -1;		else			return 0;	}#endif}Datumtimestamp_eq(PG_FUNCTION_ARGS){	Timestamp	dt1 = PG_GETARG_TIMESTAMP(0);	Timestamp	dt2 = PG_GETARG_TIMESTAMP(1);	PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);}Datumtimestamp_ne(PG_FUNCTION_ARGS){	Timestamp	dt1 = PG_GETARG_TIMESTAMP(0);	Timestamp	dt2 = PG_GETARG_TIMESTAMP(1);	PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);}Datumtimestamp_lt(PG_FUNCTION_ARGS){	Timestamp	dt1 = PG_GETARG_TIMESTAMP(0);	Timestamp	dt2 = PG_GETARG_TIMESTAMP(1);	PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);}Datumtimestamp_gt(PG_FUNCTION_ARGS){	Timestamp	dt1 = PG_GETARG_TIMESTAMP(0);	Timestamp	dt2 = PG_GETARG_TIMESTAMP(1);	PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);}Datumtimestamp_le(PG_FUNCTION_ARGS){	Timestamp	dt1 = PG_GETARG_TIMESTAMP(0);	Timestamp	dt2 = PG_GETARG_TIMESTAMP(1);	PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);}Datumtimestamp_ge(PG_FUNCTION_ARGS){	Timestamp	dt1 = PG_GETARG_TIMESTAMP(0);	Timestamp	dt2 = PG_GETARG_TIMESTAMP(1);	PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);}Datumtimestamp_cmp(PG_FUNCTION_ARGS){	Timestamp	dt1 = PG_GETARG_TIMESTAMP(0);	Timestamp	dt2 = PG_GETARG_TIMESTAMP(1);	PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));}/* *		interval_relop	- is interval1 relop interval2 * *		collate invalid interval at the end */static intinterval_cmp_internal(Interval *interval1, Interval *interval2){#ifdef HAVE_INT64_TIMESTAMP	int64		span1,				span2;#else	double		span1,				span2;#endif	span1 = interval1->time;	span2 = interval2->time;#ifdef HAVE_INT64_TIMESTAMP	if (interval1->month != 0)		span1 += ((interval1->month * INT64CONST(30) * INT64CONST(86400000000)));	if (interval2->month != 0)		span2 += ((interval2->month * INT64CONST(30) * INT64CONST(86400000000)));#else	if (interval1->month != 0)		span1 += (interval1->month * (30.0 * 86400));	if (interval2->month != 0)		span2 += (interval2->month * (30.0 * 86400));#endif	return ((span1 < span2) ? -1 : (span1 > span2) ? 1 : 0);}Datuminterval_eq(PG_FUNCTION_ARGS){	Interval   *interval1 = PG_GETARG_INTERVAL_P(0);	Interval   *interval2 = PG_GETARG_INTERVAL_P(1);	PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) == 0);}Datuminterval_ne(PG_FUNCTION_ARGS){	Interval   *interval1 = PG_GETARG_INTERVAL_P(0);	Interval   *interval2 = PG_GETARG_INTERVAL_P(1);	PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) != 0);}Datuminterval_lt(PG_FUNCTION_ARGS){	Interval   *interval1 = PG_GETARG_INTERVAL_P(0);	Interval   *interval2 = PG_GETARG_INTERVAL_P(1);	PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) < 0);}Datuminterval_gt(PG_FUNCTION_ARGS){	Interval   *interval1 = PG_GETARG_INTERVAL_P(0);	Interval   *interval2 = PG_GETARG_INTERVAL_P(1);	PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) > 0);}Datuminterval_le(PG_FUNCTION_ARGS){	Interval   *interval1 = PG_GETARG_INTERVAL_P(0);	Interval   *interval2 = PG_GETARG_INTERVAL_P(1);	PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) <= 0);}Datuminterval_ge(PG_FUNCTION_ARGS){	Interval   *interval1 = PG_GETARG_INTERVAL_P(0);	Interval   *interval2 = PG_GETARG_INTERVAL_P(1);	PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) >= 0);}Datuminterval_cmp(PG_FUNCTION_ARGS){	Interval   *interval1 = PG_GETARG_INTERVAL_P(0);	Interval   *interval2 = PG_GETARG_INTERVAL_P(1);	PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));}/* * interval, being an unusual size, needs a specialized hash function. */Datuminterval_hash(PG_FUNCTION_ARGS){	Interval   *key = PG_GETARG_INTERVAL_P(0);	/*	 * Specify hash length as sizeof(double) + sizeof(int4), not as	 * sizeof(Interval), 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->month));}/* overlaps_timestamp() --- implements the SQL92 OVERLAPS operator. * * Algorithm is per SQL92 spec.  This is much harder than you'd think * because the spec requires us to deliver a non-null answer in some cases * where some of the inputs are null. */Datumoverlaps_timestamp(PG_FUNCTION_ARGS){	/*	 * The arguments are Timestamps, but we leave them as generic Datums	 * to avoid unnecessary conversions between value and reference forms	 * --- not to mention possible dereferences of null pointers.	 */	Datum		ts1 = PG_GETARG_DATUM(0);	Datum		te1 = PG_GETARG_DATUM(1);	Datum		ts2 = PG_GETARG_DATUM(2);	Datum		te2 = PG_GETARG_DATUM(3);	bool		ts1IsNull = PG_ARGISNULL(0);	bool		te1IsNull = PG_ARGISNULL(1);	bool		ts2IsNull = PG_ARGISNULL(2);	bool		te2IsNull = PG_ARGISNULL(3);#define TIMESTAMP_GT(t1,t2) \	DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))#define TIMESTAMP_LT(t1,t2) \	DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))	/*	 * If both endpoints of interval 1 are null, the result is null	 * (unknown). If just one endpoint is null, take ts1 as the non-null	 * one. Otherwise, take ts1 as the lesser endpoint.	 */	if (ts1IsNull)	{		if (te1IsNull)			PG_RETURN_NULL();		/* swap null for non-null */		ts1 = te1;		te1IsNull = true;	}	else if (!te1IsNull)	{		if (TIMESTAMP_GT(ts1, te1))		{			Datum		tt = ts1;			ts1 = te1;			te1 = tt;		}	}	/* Likewise for interval 2. */	if (ts2IsNull)	{		if (te2IsNull)			PG_RETURN_NULL();		/* swap null for non-null */		ts2 = te2;		te2IsNull = true;	}	else if (!te2IsNull)	{		if (TIMESTAMP_GT(ts2, te2))		{			Datum		tt = ts2;			ts2 = te2;			te2 = tt;		}	}	/*	 * At this point neither ts1 nor ts2 is null, so we can consider three	 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2	 */	if (TIMESTAMP_GT(ts1, ts2))	{		/*		 * This case is ts1 < te2 OR te1 < te2, which may look redundant		 * but in the presence of nulls it's not quite completely so.		 */		if (te2IsNull)			PG_RETURN_NULL();		if (TIMESTAMP_LT(ts1, te2))			PG_RETURN_BOOL(true);		if (te1IsNull)			PG_RETURN_NULL();		/*		 * If te1 is not null then we had ts1 <= te1 above, and we just		 * found ts1 >= te2, hence te1 >= te2.		 */		PG_RETURN_BOOL(false);	}	else if (TIMESTAMP_LT(ts1, ts2))	{		/* This case is ts2 < te1 OR te2 < te1 */		if (te1IsNull)			PG_RETURN_NULL();		if (TIMESTAMP_LT(ts2, te1))			PG_RETURN_BOOL(true);		if (te2IsNull)			PG_RETURN_NULL();		/*		 * If te2 is not null then we had ts2 <= te2 above, and we just		 * found ts2 >= te1, hence te2 >= te1.		 */		PG_RETURN_BOOL(false);	}	else	{		/*		 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a		 * rather silly way of saying "true if both are nonnull, else		 * null".		 */		if (te1IsNull || te2IsNull)			PG_RETURN_NULL();		PG_RETURN_BOOL(true);	}#undef TIMESTAMP_GT#undef TIMESTAMP_LT}/*---------------------------------------------------------- *	"Arithmetic" operators on date/times. *---------------------------------------------------------*/Datumtimestamp_smaller(PG_FUNCTION_ARGS){	Timestamp	dt1 = PG_GETARG_TIMESTAMP(0);	Timestamp	dt2 = PG_GETARG_TIMESTAMP(1);	Timestamp	result;	/* use timestamp_cmp_internal to be sure this agrees with comparisons */	if (timestamp_cmp_internal(dt1, dt2) < 0)		result = dt1;	else		result = dt2;	PG_RETURN_TIMESTAMP(result);}Datumtimestamp_larger(PG_FUNCTION_ARGS){	Timestamp	dt1 = PG_GETARG_TIMESTAMP(0);	Timestamp	dt2 = PG_GETARG_TIMESTAMP(1);	Timestamp	result;	if (timestamp_cmp_internal(dt1, dt2) > 0)		result = dt1;	else		result = dt2;	PG_RETURN_TIMESTAMP(result);}Datumtimestamp_mi(PG_FUNCTION_ARGS){	Timestamp	dt1 = PG_GETARG_TIMESTAMP(0);	Timestamp	dt2 = PG_GETARG_TIMESTAMP(1);	Interval   *result;	result = (Interval *) palloc(sizeof(Interval));	if (TIMESTAMP_NOT_FINITE(dt1) || TIMESTAMP_NOT_FINITE(dt2))	{		ereport(ERROR,				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),				 errmsg("cannot subtract infinite timestamps")));		result->time = 0;	}	else#ifdef HAVE_INT64_TIMESTAMP		result->time = (dt1 - dt2);#else		result->time = JROUND(dt1 - dt2);#endif	result->month = 0;

⌨️ 快捷键说明

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