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

📄 date.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 4 页
字号:
		 * 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 TIMEADT_GT#undef TIMEADT_LT}/* timestamp_time() * Convert timestamp to time data type. */Datumtimestamp_time(PG_FUNCTION_ARGS){	Timestamp	timestamp = PG_GETARG_TIMESTAMP(0);	TimeADT		result;	struct pg_tm tt,			   *tm = &tt;	fsec_t		fsec;	if (TIMESTAMP_NOT_FINITE(timestamp))		PG_RETURN_NULL();	if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)		ereport(ERROR,				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),				 errmsg("timestamp out of range")));#ifdef HAVE_INT64_TIMESTAMP	/*	 * Could also do this with time = (timestamp / USECS_PER_DAY *	 * USECS_PER_DAY) - timestamp;	 */	result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *			  USECS_PER_SEC) + fsec;#else	result = ((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec + fsec;#endif	PG_RETURN_TIMEADT(result);}/* timestamptz_time() * Convert timestamptz to time data type. */Datumtimestamptz_time(PG_FUNCTION_ARGS){	TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);	TimeADT		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")));#ifdef HAVE_INT64_TIMESTAMP	/*	 * Could also do this with time = (timestamp / USECS_PER_DAY *	 * USECS_PER_DAY) - timestamp;	 */	result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *			  USECS_PER_SEC) + fsec;#else	result = ((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec + fsec;#endif	PG_RETURN_TIMEADT(result);}/* datetime_timestamp() * Convert date and time to timestamp data type. */Datumdatetime_timestamp(PG_FUNCTION_ARGS){	DateADT		date = PG_GETARG_DATEADT(0);	TimeADT		time = PG_GETARG_TIMEADT(1);	Timestamp	result;	result = DatumGetTimestamp(DirectFunctionCall1(date_timestamp,												   DateADTGetDatum(date)));	result += time;	PG_RETURN_TIMESTAMP(result);}/* time_interval() * Convert time to interval data type. */Datumtime_interval(PG_FUNCTION_ARGS){	TimeADT		time = PG_GETARG_TIMEADT(0);	Interval   *result;	result = (Interval *) palloc(sizeof(Interval));	result->time = time;	result->day = 0;	result->month = 0;	PG_RETURN_INTERVAL_P(result);}/* interval_time() * Convert interval to time data type. * * This is defined as producing the fractional-day portion of the interval. * Therefore, we can just ignore the months field.	It is not real clear * what to do with negative intervals, but we choose to subtract the floor, * so that, say, '-2 hours' becomes '22:00:00'. */Datuminterval_time(PG_FUNCTION_ARGS){	Interval   *span = PG_GETARG_INTERVAL_P(0);	TimeADT		result;#ifdef HAVE_INT64_TIMESTAMP	int64		days;	result = span->time;	if (result >= USECS_PER_DAY)	{		days = result / USECS_PER_DAY;		result -= days * USECS_PER_DAY;	}	else if (result < 0)	{		days = (-result + USECS_PER_DAY - 1) / USECS_PER_DAY;		result += days * USECS_PER_DAY;	}#else	result = span->time;	if (result >= (double) SECS_PER_DAY || result < 0)		result -= floor(result / (double) SECS_PER_DAY) * (double) SECS_PER_DAY;#endif	PG_RETURN_TIMEADT(result);}/* time_mi_time() * Subtract two times to produce an interval. */Datumtime_mi_time(PG_FUNCTION_ARGS){	TimeADT		time1 = PG_GETARG_TIMEADT(0);	TimeADT		time2 = PG_GETARG_TIMEADT(1);	Interval   *result;	result = (Interval *) palloc(sizeof(Interval));	result->month = 0;	result->day = 0;	result->time = time1 - time2;	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 / USECS_PER_DAY * USECS_PER_DAY;	if (result < INT64CONST(0))		result += USECS_PER_DAY;#else	TimeADT		time1;	result = time + span->time;	TMODULO(result, time1, (double) SECS_PER_DAY);	if (result < 0)		result += SECS_PER_DAY;#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 / USECS_PER_DAY * USECS_PER_DAY;	if (result < INT64CONST(0))		result += USECS_PER_DAY;#else	TimeADT		time1;	result = time - span->time;	TMODULO(result, time1, (double) SECS_PER_DAY);	if (result < 0)		result += SECS_PER_DAY;#endif	PG_RETURN_TIMEADT(result);}/* 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;	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)	{		fsec_t		fsec;		struct pg_tm tt,				   *tm = &tt;		time2tm(time, tm, &fsec);		switch (val)		{			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_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 / 1000000.0;#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 pg_tm * tm, fsec_t fsec, int tz, TimeTzADT *result){#ifdef HAVE_INT64_TIMESTAMP	result->time = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *					USECS_PER_SEC) + fsec;#else	result->time = ((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + 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 pg_tm tt,			   *tm = &tt;	int			tz;	int			nf;	int			dterr;	char		workbuf[MAXDATELEN + 1];	char	   *field[MAXDATEFIELDS];	int			dtype;	int			ftype[MAXDATEFIELDS];	dterr = ParseDateTime(str, workbuf, sizeof(workbuf),						  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 pg_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);#ifdef NOT_USED	Oid			typelem = PG_GETARG_OID(1);#endif	int32		typmod = PG_GETARG_INT32(2);	TimeTzADT  *result;	result = (TimeTzADT *) palloc(sizeof(TimeTzADT));#ifdef HAVE_INT64_TIMESTAMP	result->time = pq_getmsgint64(buf);#else	result->time = pq_getmsgfloat8(buf);#endif	result->zone = pq_getmsgint(buf, sizeof(result->zone));	AdjustTimeForTypmod(&(result->time), typmod);	PG_RETURN_TIMETZADT_P(result);}/* *		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 pg_tm * tm, fsec_t *fsec, int *tzp){#ifdef HAVE_INT64_TIMESTAMP	int64		trem = time->time;	tm->tm_hour = trem / USECS_PER_HOUR;	trem -= tm->tm_hour * USECS_PER_HOUR;	tm->tm_min = trem / USECS_PER_MINUTE;	trem -= tm->tm_min * USECS_PER_MINUTE;	tm->tm_sec = trem / USECS_PER_SEC;	*fsec = trem - tm->tm_sec * USECS_PER_SEC;#else	double		trem = time->time;recalc:	TMODULO(trem, tm->tm_hour, (double) SECS_PER_HOUR);	TMODULO(trem, tm->tm_min, (double) SECS_PER_MINUTE);	TMODULO(trem, tm->tm_sec, 1.0);	trem = TIMEROUND(trem);	/* roundoff may need to propagate to higher-order fields */	if (trem >= 1.0)	{		trem = ceil(time->time);		goto recalc;	}	*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){	/* Primary sort is by true (GMT-equivalent) time */#ifdef HAVE_INT64_TIMESTAMP	int64		t1,				t2;	t1 = time1->time + (time1->zone * USECS_PER_SEC);	t2 = time2->time + (time2->zone * USECS_PER_SEC);#else	double		t1,				t2;	t1 = time1->time + time1->zone;	t2 = time2->time + time2->zone;#endif	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);}

⌨️ 快捷键说明

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