mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Allow interpretation of INTERVALs with more timezone-like syntax.
Define conversions to and from text for date, time, and timetz. Have millisecond and microsecond return full # of seconds in those units. Previously, only returned full fractional part in those units.
This commit is contained in:
		@@ -8,7 +8,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * IDENTIFICATION
 | 
			
		||||
 *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.51 2000/10/29 13:17:33 petere Exp $
 | 
			
		||||
 *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.52 2000/11/11 19:55:19 thomas Exp $
 | 
			
		||||
 *
 | 
			
		||||
 *-------------------------------------------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
@@ -339,6 +339,61 @@ abstime_date(PG_FUNCTION_ARGS)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* date_text()
 | 
			
		||||
 * Convert date to text data type.
 | 
			
		||||
 */
 | 
			
		||||
Datum
 | 
			
		||||
date_text(PG_FUNCTION_ARGS)
 | 
			
		||||
{
 | 
			
		||||
	/* Input is a Date, but may as well leave it in Datum form */
 | 
			
		||||
	Datum		date = PG_GETARG_DATUM(0);
 | 
			
		||||
	text	   *result;
 | 
			
		||||
	char	   *str;
 | 
			
		||||
	int			len;
 | 
			
		||||
 | 
			
		||||
	str = DatumGetCString(DirectFunctionCall1(date_out, date));
 | 
			
		||||
 | 
			
		||||
	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_date()
 | 
			
		||||
 * Convert text string to date.
 | 
			
		||||
 * Text type is not null terminated, so use temporary string
 | 
			
		||||
 *	then call the standard input routine.
 | 
			
		||||
 */
 | 
			
		||||
Datum
 | 
			
		||||
text_date(PG_FUNCTION_ARGS)
 | 
			
		||||
{
 | 
			
		||||
	text	   *str = PG_GETARG_TEXT_P(0);
 | 
			
		||||
	int			i;
 | 
			
		||||
	char	   *sp,
 | 
			
		||||
			   *dp,
 | 
			
		||||
				dstr[MAXDATELEN + 1];
 | 
			
		||||
 | 
			
		||||
	if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
 | 
			
		||||
		elog(ERROR, "Bad date external representation (too long)");
 | 
			
		||||
 | 
			
		||||
	sp = VARDATA(str);
 | 
			
		||||
	dp = dstr;
 | 
			
		||||
	for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)
 | 
			
		||||
		*dp++ = *sp++;
 | 
			
		||||
	*dp = '\0';
 | 
			
		||||
 | 
			
		||||
	return DirectFunctionCall1(date_in,
 | 
			
		||||
							   CStringGetDatum(dstr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 *	 Time ADT
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
@@ -576,6 +631,61 @@ time_interval(PG_FUNCTION_ARGS)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* time_text()
 | 
			
		||||
 * Convert time to text data type.
 | 
			
		||||
 */
 | 
			
		||||
Datum
 | 
			
		||||
time_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.
 | 
			
		||||
 */
 | 
			
		||||
Datum
 | 
			
		||||
text_time(PG_FUNCTION_ARGS)
 | 
			
		||||
{
 | 
			
		||||
	text	   *str = PG_GETARG_TEXT_P(0);
 | 
			
		||||
	int			i;
 | 
			
		||||
	char	   *sp,
 | 
			
		||||
			   *dp,
 | 
			
		||||
				dstr[MAXDATELEN + 1];
 | 
			
		||||
 | 
			
		||||
	if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
 | 
			
		||||
		elog(ERROR, "Bad time external representation (too long)");
 | 
			
		||||
 | 
			
		||||
	sp = VARDATA(str);
 | 
			
		||||
	dp = dstr;
 | 
			
		||||
	for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)
 | 
			
		||||
		*dp++ = *sp++;
 | 
			
		||||
	*dp = '\0';
 | 
			
		||||
 | 
			
		||||
	return DirectFunctionCall1(time_in,
 | 
			
		||||
							   CStringGetDatum(dstr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 *	 Time With Time Zone ADT
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
@@ -851,3 +961,58 @@ datetimetz_timestamp(PG_FUNCTION_ARGS)
 | 
			
		||||
 | 
			
		||||
	PG_RETURN_TIMESTAMP(result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* timetz_text()
 | 
			
		||||
 * Convert timetz to text data type.
 | 
			
		||||
 */
 | 
			
		||||
Datum
 | 
			
		||||
timetz_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.
 | 
			
		||||
 */
 | 
			
		||||
Datum
 | 
			
		||||
text_timetz(PG_FUNCTION_ARGS)
 | 
			
		||||
{
 | 
			
		||||
	text	   *str = PG_GETARG_TEXT_P(0);
 | 
			
		||||
	int			i;
 | 
			
		||||
	char	   *sp,
 | 
			
		||||
			   *dp,
 | 
			
		||||
				dstr[MAXDATELEN + 1];
 | 
			
		||||
 | 
			
		||||
	if (VARSIZE(str) - VARHDRSZ > MAXDATELEN)
 | 
			
		||||
		elog(ERROR, "Bad timetz external representation (too long)");
 | 
			
		||||
 | 
			
		||||
	sp = VARDATA(str);
 | 
			
		||||
	dp = dstr;
 | 
			
		||||
	for (i = 0; i < (VARSIZE(str) - VARHDRSZ); i++)
 | 
			
		||||
		*dp++ = *sp++;
 | 
			
		||||
	*dp = '\0';
 | 
			
		||||
 | 
			
		||||
	return DirectFunctionCall1(timetz_in,
 | 
			
		||||
							   CStringGetDatum(dstr));
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * IDENTIFICATION
 | 
			
		||||
 *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.55 2000/11/06 15:57:00 thomas Exp $
 | 
			
		||||
 *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.56 2000/11/11 19:55:19 thomas Exp $
 | 
			
		||||
 *
 | 
			
		||||
 *-------------------------------------------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
@@ -494,7 +494,7 @@ ParseDateTime(char *timestr, char *lowstr,
 | 
			
		||||
			{
 | 
			
		||||
				ftype[nf] = DTK_TZ;
 | 
			
		||||
				*lp++ = *cp++;
 | 
			
		||||
				while (isdigit((int) *cp) || (*cp == ':'))
 | 
			
		||||
				while (isdigit((int) *cp) || (*cp == ':') || (*cp == '.'))
 | 
			
		||||
					*lp++ = *cp++;
 | 
			
		||||
 | 
			
		||||
				/* special? */
 | 
			
		||||
@@ -1657,7 +1657,7 @@ DecodeDateDelta(char **field, int *ftype, int nf, int *dtype, struct tm * tm, do
 | 
			
		||||
 | 
			
		||||
	*dtype = DTK_DELTA;
 | 
			
		||||
 | 
			
		||||
	type = DTK_SECOND;
 | 
			
		||||
	type = IGNORE;
 | 
			
		||||
	tm->tm_year = 0;
 | 
			
		||||
	tm->tm_mon = 0;
 | 
			
		||||
	tm->tm_mday = 0;
 | 
			
		||||
@@ -1687,7 +1687,7 @@ DecodeDateDelta(char **field, int *ftype, int nf, int *dtype, struct tm * tm, do
 | 
			
		||||
				 * So, work this out to drop through to DTK_NUMBER, which *can* tolerate this.
 | 
			
		||||
				 */
 | 
			
		||||
				cp = field[i]+1;
 | 
			
		||||
				while ((*cp != '\0') && (*cp != ':'))
 | 
			
		||||
				while ((*cp != '\0') && (*cp != ':') && (*cp != '.'))
 | 
			
		||||
					cp++;
 | 
			
		||||
				if ((*cp == ':')
 | 
			
		||||
					&& (DecodeTime((field[i]+1), fmask, &tmask, tm, fsec) == 0)) {
 | 
			
		||||
@@ -1705,6 +1705,14 @@ DecodeDateDelta(char **field, int *ftype, int nf, int *dtype, struct tm * tm, do
 | 
			
		||||
					type = DTK_DAY;
 | 
			
		||||
					tmask = DTK_M(TZ);
 | 
			
		||||
					break;
 | 
			
		||||
				} else if (type == IGNORE) {
 | 
			
		||||
					if (*cp == '.') {
 | 
			
		||||
						/* Got a decimal point? Then assume some sort of seconds specification */
 | 
			
		||||
						type = DTK_SECOND;
 | 
			
		||||
					} else if (*cp == '\0') {
 | 
			
		||||
						/* Only a signed integer? Then must assume a timezone-like usage */
 | 
			
		||||
						type = DTK_HOUR;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				/* DROP THROUGH */
 | 
			
		||||
 | 
			
		||||
@@ -1714,6 +1722,8 @@ DecodeDateDelta(char **field, int *ftype, int nf, int *dtype, struct tm * tm, do
 | 
			
		||||
 | 
			
		||||
				if (*cp == '.')
 | 
			
		||||
				{
 | 
			
		||||
					if (type == IGNORE)
 | 
			
		||||
						type = DTK_SECOND;
 | 
			
		||||
					fval = strtod(cp, &cp);
 | 
			
		||||
					if (*cp != '\0')
 | 
			
		||||
						return -1;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * IDENTIFICATION
 | 
			
		||||
 *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.37 2000/11/06 15:57:00 thomas Exp $
 | 
			
		||||
 *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.38 2000/11/11 19:55:19 thomas Exp $
 | 
			
		||||
 *
 | 
			
		||||
 *-------------------------------------------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
@@ -2100,11 +2100,11 @@ interval_part(PG_FUNCTION_ARGS)
 | 
			
		||||
			switch (val)
 | 
			
		||||
			{
 | 
			
		||||
				case DTK_MICROSEC:
 | 
			
		||||
					result = (fsec * 1000000);
 | 
			
		||||
					result = ((tm->tm_sec + fsec) * 1000000);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case DTK_MILLISEC:
 | 
			
		||||
					result = (fsec * 1000);
 | 
			
		||||
					result = ((tm->tm_sec + fsec) * 1000);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case DTK_SECOND:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user