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

📄 date.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 4 页
字号:
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	result->time = time->time + span->time;	result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;	if (result->time < INT64CONST(0))		result->time += USECS_PER_DAY;#else	result->time = time->time + span->time;	TMODULO(result->time, time1.time, (double) SECS_PER_DAY);	if (result->time < 0)		result->time += SECS_PER_DAY;#endif	result->zone = time->zone;	PG_RETURN_TIMETZADT_P(result);}/* timetz_mi_interval() * Subtract interval from timetz. */Datumtimetz_mi_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	result->time = time->time - span->time;	result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;	if (result->time < INT64CONST(0))		result->time += USECS_PER_DAY;#else	result->time = time->time - span->time;	TMODULO(result->time, time1.time, (double) SECS_PER_DAY);	if (result->time < 0)		result->time += SECS_PER_DAY;#endif	result->zone = time->zone;	PG_RETURN_TIMETZADT_P(result);}/* overlaps_timetz() --- 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_timetz(PG_FUNCTION_ARGS){	/*	 * The arguments are TimeTzADT *, but we leave them as generic Datums for	 * convenience of notation --- and to avoid dereferencing nulls.	 */	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 TIMETZ_GT(t1,t2) \	DatumGetBool(DirectFunctionCall2(timetz_gt,t1,t2))#define TIMETZ_LT(t1,t2) \	DatumGetBool(DirectFunctionCall2(timetz_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 (TIMETZ_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 (TIMETZ_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 (TIMETZ_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 (TIMETZ_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 (TIMETZ_LT(ts1, ts2))	{		/* This case is ts2 < te1 OR te2 < te1 */		if (te1IsNull)			PG_RETURN_NULL();		if (TIMETZ_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 TIMETZ_GT#undef TIMETZ_LT}Datumtimetz_time(PG_FUNCTION_ARGS){	TimeTzADT  *timetz = PG_GETARG_TIMETZADT_P(0);	TimeADT		result;	/* swallow the time zone and just return the time */	result = timetz->time;	PG_RETURN_TIMEADT(result);}Datumtime_timetz(PG_FUNCTION_ARGS){	TimeADT		time = PG_GETARG_TIMEADT(0);	TimeTzADT  *result;	struct pg_tm tt,			   *tm = &tt;	fsec_t		fsec;	int			tz;	GetCurrentDateTime(tm);	time2tm(time, tm, &fsec);	tz = DetermineTimeZoneOffset(tm, global_timezone);	result = (TimeTzADT *) palloc(sizeof(TimeTzADT));	result->time = time;	result->zone = tz;	PG_RETURN_TIMETZADT_P(result);}/* timestamptz_timetz() * Convert timestamp to timetz data type. */Datumtimestamptz_timetz(PG_FUNCTION_ARGS){	TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);	TimeTzADT  *result;	struct pg_tm tt,			   *tm = &tt;	int			tz;	fsec_t		fsec;	char	   *tzn;	if (TIMESTAMP_NOT_FINITE(timestamp))		PG_RETURN_NULL();	if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)		ereport(ERROR,				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),				 errmsg("timestamp out of range")));	result = (TimeTzADT *) palloc(sizeof(TimeTzADT));	tm2timetz(tm, fsec, tz, result);	PG_RETURN_TIMETZADT_P(result);}/* datetimetz_timestamptz() * Convert date and timetz to timestamp with time zone data type. * Timestamp is stored in GMT, so add the time zone * stored with the timetz to the result. * - thomas 2000-03-10 */Datumdatetimetz_timestamptz(PG_FUNCTION_ARGS){	DateADT		date = PG_GETARG_DATEADT(0);	TimeTzADT  *time = PG_GETARG_TIMETZADT_P(1);	TimestampTz result;#ifdef HAVE_INT64_TIMESTAMP	result = date * USECS_PER_DAY + time->time + time->zone * USECS_PER_SEC;#else	result = date * (double) SECS_PER_DAY + time->time + time->zone;#endif	PG_RETURN_TIMESTAMP(result);}/* timetz_text() * Convert timetz to text data type. */Datumtimetz_text(PG_FUNCTION_ARGS){	/* Input is a Timetz, but may as well leave it in Datum form */	Datum		timetz = PG_GETARG_DATUM(0);	text	   *result;	char	   *str;	int			len;	str = DatumGetCString(DirectFunctionCall1(timetz_out, timetz));	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_timetz() * Convert text string to timetz. * Text type is not null terminated, so use temporary string *	then call the standard input routine. */Datumtext_timetz(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 with time zone: \"%s\"",				 VARDATA(str))));	sp = VARDATA(str);	dp = dstr;	for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)		*dp++ = *sp++;	*dp = '\0';	return DirectFunctionCall3(timetz_in,							   CStringGetDatum(dstr),							   ObjectIdGetDatum(InvalidOid),							   Int32GetDatum(-1));}/* timetz_part() * Extract specified field from time type. */Datumtimetz_part(PG_FUNCTION_ARGS){	text	   *units = PG_GETARG_TEXT_P(0);	TimeTzADT  *time = PG_GETARG_TIMETZADT_P(1);	float8		result;	int			type,				val;	char	   *lowunits;	lowunits = downcase_truncate_identifier(VARDATA(units),											VARSIZE(units) - VARHDRSZ,											false);	type = DecodeUnits(0, lowunits, &val);	if (type == UNKNOWN_FIELD)		type = DecodeSpecial(0, lowunits, &val);	if (type == UNITS)	{		double		dummy;		int			tz;		fsec_t		fsec;		struct pg_tm tt,				   *tm = &tt;		timetz2tm(time, tm, &fsec, &tz);		switch (val)		{			case DTK_TZ:				result = -tz;				break;			case DTK_TZ_MINUTE:				result = -tz;				result /= SECS_PER_MINUTE;				FMODULO(result, dummy, (double) SECS_PER_MINUTE);				break;			case DTK_TZ_HOUR:				dummy = -tz;				FMODULO(dummy, result, (double) SECS_PER_HOUR);				break;			case DTK_MICROSEC:#ifdef HAVE_INT64_TIMESTAMP				result = tm->tm_sec * USECS_PER_SEC + 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 / USECS_PER_SEC;#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_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 with time zone\" units \"%s\" not recognized",					   DatumGetCString(DirectFunctionCall1(textout,												 PointerGetDatum(units))))));				result = 0;		}	}	else if (type == RESERV && val == DTK_EPOCH)	{#ifdef HAVE_INT64_TIMESTAMP		result = time->time / 1000000.0 + time->zone;#else		result = time->time + time->zone;#endif	}	else	{		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("\"time with time zone\" units \"%s\" not recognized",						DatumGetCString(DirectFunctionCall1(textout,												 PointerGetDatum(units))))));		result = 0;	}	PG_RETURN_FLOAT8(result);}/* timetz_zone() * Encode time with time zone type with specified time zone. * Applies DST rules as of the current date. */Datumtimetz_zone(PG_FUNCTION_ARGS){	text	   *zone = PG_GETARG_TEXT_P(0);	TimeTzADT  *t = PG_GETARG_TIMETZADT_P(1);	TimeTzADT  *result;	int			tz;	char		tzname[TZ_STRLEN_MAX + 1];	int			len;	pg_tz	   *tzp;	/*	 * Look up the requested timezone.	First we look in the timezone database	 * (to handle cases like "America/New_York"), and if that fails, we look	 * in the date token table (to handle cases like "EST").	 */	len = Min(VARSIZE(zone) - VARHDRSZ, TZ_STRLEN_MAX);	memcpy(tzname, VARDATA(zone), len);	tzname[len] = '\0';	tzp = pg_tzset(tzname);	if (tzp)	{		/* Get the offset-from-GMT that is valid today for the selected zone */		pg_time_t	now;		struct pg_tm *tm;		now = time(NULL);		tm = pg_localtime(&now, tzp);		tz = -tm->tm_gmtoff;	}	else	{		char	   *lowzone;		int			type,					val;		lowzone = downcase_truncate_identifier(VARDATA(zone),											   VARSIZE(zone) - VARHDRSZ,											   false);		type = DecodeSpecial(0, lowzone, &val);		if (type == TZ || type == DTZ)			tz = val * 60;		else		{			ereport(ERROR,					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),					 errmsg("time zone \"%s\" not recognized", tzname)));			tz = 0;				/* keep compiler quiet */		}	}	result = (TimeTzADT *) palloc(sizeof(TimeTzADT));#ifdef HAVE_INT64_TIMESTAMP	result->time = t->time + (t->zone - tz) * USECS_PER_SEC;	while (result->time < INT64CONST(0))		result->time += USECS_PER_DAY;	while (result->time >= USECS_PER_DAY)		result->time -= USECS_PER_DAY;#else	result->time = t->time + (t->zone - tz);	while (result->time < 0)		result->time += SECS_PER_DAY;	while (result->time >= SECS_PER_DAY)		result->time -= SECS_PER_DAY;#endif	result->zone = tz;	PG_RETURN_TIMETZADT_P(result);}/* timetz_izone() * Encode time with time zone type with specified time interval as time zone. */Datumtimetz_izone(PG_FUNCTION_ARGS){	Interval   *zone = PG_GETARG_INTERVAL_P(0);	TimeTzADT  *time = PG_GETARG_TIMETZADT_P(1);	TimeTzADT  *result;	int			tz;	if (zone->month != 0)		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("\"interval\" time zone \"%s\" not valid",						DatumGetCString(DirectFunctionCall1(interval_out,												  PointerGetDatum(zone))))));#ifdef HAVE_INT64_TIMESTAMP	tz = -(zone->time / USECS_PER_SEC);#else	tz = -(zone->time);#endif	result = (TimeTzADT *) palloc(sizeof(TimeTzADT));#ifdef HAVE_INT64_TIMESTAMP	result->time = time->time + (time->zone - tz) * USECS_PER_SEC;	while (result->time < INT64CONST(0))		result->time += USECS_PER_DAY;	while (result->time >= USECS_PER_DAY)		result->time -= USECS_PER_DAY;#else	result->time = time->time + (time->zone - tz);	while (result->time < 0)		result->time += SECS_PER_DAY;	while (result->time >= SECS_PER_DAY)		result->time -= SECS_PER_DAY;#endif	result->zone = tz;	PG_RETURN_TIMETZADT_P(result);}

⌨️ 快捷键说明

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