diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index 3d75edca765400580e58bec1e8897d803e068ae6..9bbd5146c2a6c51589729e4b4343330a1efddc4b 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -1,5 +1,5 @@ @@ -1297,8 +1297,7 @@ SELECT b, char_length(b) FROM test2; fractional digits retained in the seconds field. By default, there is no explicit bound on precision. The allowed range of p is from 0 to 6 for the - timestamp and interval types, 0 to 13 - for the time types. + timestamp and interval types. @@ -1314,6 +1313,12 @@ SELECT b, char_length(b) FROM test2; + + For the time types, the allowed range of + p is from 0 to 6 when eight-byte integer + storage is used, or from 0 to 10 when floating-point storage is used. + + Time zones, and time-zone conventions, are influenced by political decisions, not just earth geometry. Time zones around the @@ -1485,7 +1490,7 @@ SELECT b, char_length(b) FROM test2; The time type can be specified as time or as time without time zone. The optional precision - p should be between 0 and 13, and + p should be between 0 and 6, and defaults to the precision of the input time literal. diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index 11a58b417460a7c5b3e318e5829b80c8b34d6c30..90f41ad817d557d2577588bc5ad6825ab69a4c3c 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.76 2003/01/22 20:44:20 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.77 2003/01/29 01:08:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -619,7 +619,7 @@ static void AdjustTimeForTypmod(TimeADT *time, int32 typmod) { #ifdef HAVE_INT64_TIMESTAMP - static const int64 TimeScales[MAX_TIMESTAMP_PRECISION + 1] = { + static const int64 TimeScales[MAX_TIME_PRECISION + 1] = { INT64CONST(1000000), INT64CONST(100000), INT64CONST(10000), @@ -629,7 +629,7 @@ AdjustTimeForTypmod(TimeADT *time, int32 typmod) INT64CONST(1) }; - static const int64 TimeOffsets[MAX_TIMESTAMP_PRECISION + 1] = { + static const int64 TimeOffsets[MAX_TIME_PRECISION + 1] = { INT64CONST(500000), INT64CONST(50000), INT64CONST(5000), @@ -640,14 +640,19 @@ AdjustTimeForTypmod(TimeADT *time, int32 typmod) }; #else - static const double TimeScales[MAX_TIMESTAMP_PRECISION + 1] = { + /* note MAX_TIME_PRECISION differs in this case */ + static const double TimeScales[MAX_TIME_PRECISION + 1] = { 1, 10, 100, 1000, 10000, 100000, - 1000000 + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000 }; #endif diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 55e3e2a198450e770c4cbd3a1312e573c27c5b5b..b73554bf2e6433474b6c23c563f6ddb4530c3101 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.98 2003/01/16 00:26:45 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.99 2003/01/29 01:08:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -667,14 +667,13 @@ TrimTrailingZeros(char *str) } #endif - /* chop off trailing zeros... */ + /* chop off trailing zeros... but leave at least 2 fractional digits */ while ((*(str + len - 1) == '0') && (*(str + len - 3) != '.')) { len--; *(str + len) = '\0'; } - return; } @@ -3145,33 +3144,22 @@ EncodeDateOnly(struct tm * tm, int style, char *str) int EncodeTimeOnly(struct tm * tm, fsec_t fsec, int *tzp, int style, char *str) { -#ifndef HAVE_INT64_TIMESTAMP - fsec_t sec; -#endif - if ((tm->tm_hour < 0) || (tm->tm_hour > 24)) return -1; -#ifndef HAVE_INT64_TIMESTAMP - sec = (tm->tm_sec + fsec); -#endif - sprintf(str, "%02d:%02d", tm->tm_hour, tm->tm_min); /* - * If we have fractional seconds, then include a decimal point We will - * do up to 6 fractional digits, and we have rounded any inputs to - * eliminate anything to the right of 6 digits anyway. If there are no - * fractional seconds, then do not bother printing a decimal point at - * all. - thomas 2001-09-29 + * Print fractional seconds if any. The field widths here should be + * at least equal to the larger of MAX_TIME_PRECISION and + * MAX_TIMESTAMP_PRECISION. */ if (fsec != 0) { #ifdef HAVE_INT64_TIMESTAMP - sprintf((str + strlen(str)), ":%02d", tm->tm_sec); - sprintf((str + strlen(str)), ".%06d", fsec); + sprintf((str + strlen(str)), ":%02d.%06d", tm->tm_sec, fsec); #else - sprintf((str + strlen(str)), ":%013.10f", sec); + sprintf((str + strlen(str)), ":%013.10f", tm->tm_sec + fsec); #endif /* chop off trailing pairs of zeros... */ while ((strcmp((str + strlen(str) - 2), "00") == 0) @@ -3179,11 +3167,7 @@ EncodeTimeOnly(struct tm * tm, fsec_t fsec, int *tzp, int style, char *str) *(str + strlen(str) - 2) = '\0'; } else -#ifdef HAVE_INT64_TIMESTAMP sprintf((str + strlen(str)), ":%02d", tm->tm_sec); -#else - sprintf((str + strlen(str)), ":%02.0f", sec); -#endif if (tzp != NULL) { @@ -3217,20 +3201,12 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha hour, min; -#ifndef HAVE_INT64_TIMESTAMP - fsec_t sec; -#endif - /* * Why are we checking only the month field? Change this to an * assert... if ((tm->tm_mon < 1) || (tm->tm_mon > 12)) return -1; */ Assert((tm->tm_mon >= 1) && (tm->tm_mon <= 12)); -#ifndef HAVE_INT64_TIMESTAMP - sec = (tm->tm_sec + fsec); -#endif - switch (style) { case USE_ISO_DATES: @@ -3241,21 +3217,20 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min); /* - * If we have fractional seconds, then include a decimal point - * We will do up to 6 fractional digits, and we have rounded - * any inputs to eliminate anything to the right of 6 digits - * anyway. If there are no fractional seconds, then do not - * bother printing a decimal point at all. - thomas 2001-09-29 + * Print fractional seconds if any. The field widths here should + * be at least equal to MAX_TIMESTAMP_PRECISION. + * + * In float mode, don't print fractional seconds before 1 AD, + * since it's unlikely there's any precision left ... */ #ifdef HAVE_INT64_TIMESTAMP if (fsec != 0) { - sprintf((str + strlen(str)), ":%02d", tm->tm_sec); - sprintf((str + strlen(str)), ".%06d", fsec); + sprintf((str + strlen(str)), ":%02d.%06d", tm->tm_sec, fsec); #else if ((fsec != 0) && (tm->tm_year > 0)) { - sprintf((str + strlen(str)), ":%013.10f", sec); + sprintf((str + strlen(str)), ":%09.6f", tm->tm_sec + fsec); #endif TrimTrailingZeros(str); } @@ -3292,21 +3267,20 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha tm->tm_hour, tm->tm_min); /* - * If we have fractional seconds, then include a decimal point - * We will do up to 6 fractional digits, and we have rounded - * any inputs to eliminate anything to the right of 6 digits - * anyway. If there are no fractional seconds, then do not - * bother printing a decimal point at all. - thomas 2001-09-29 + * Print fractional seconds if any. The field widths here should + * be at least equal to MAX_TIMESTAMP_PRECISION. + * + * In float mode, don't print fractional seconds before 1 AD, + * since it's unlikely there's any precision left ... */ #ifdef HAVE_INT64_TIMESTAMP if (fsec != 0) { - sprintf((str + strlen(str)), ":%02d", tm->tm_sec); - sprintf((str + strlen(str)), ".%06d", fsec); + sprintf((str + strlen(str)), ":%02d.%06d", tm->tm_sec, fsec); #else if ((fsec != 0) && (tm->tm_year > 0)) { - sprintf((str + strlen(str)), ":%013.10f", sec); + sprintf((str + strlen(str)), ":%09.6f", tm->tm_sec + fsec); #endif TrimTrailingZeros(str); } @@ -3339,21 +3313,20 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha tm->tm_hour, tm->tm_min); /* - * If we have fractional seconds, then include a decimal point - * We will do up to 6 fractional digits, and we have rounded - * any inputs to eliminate anything to the right of 6 digits - * anyway. If there are no fractional seconds, then do not - * bother printing a decimal point at all. - thomas 2001-09-29 + * Print fractional seconds if any. The field widths here should + * be at least equal to MAX_TIMESTAMP_PRECISION. + * + * In float mode, don't print fractional seconds before 1 AD, + * since it's unlikely there's any precision left ... */ #ifdef HAVE_INT64_TIMESTAMP if (fsec != 0) { - sprintf((str + strlen(str)), ":%02d", tm->tm_sec); - sprintf((str + strlen(str)), ".%06d", fsec); + sprintf((str + strlen(str)), ":%02d.%06d", tm->tm_sec, fsec); #else if ((fsec != 0) && (tm->tm_year > 0)) { - sprintf((str + strlen(str)), ":%013.10f", sec); + sprintf((str + strlen(str)), ":%09.6f", tm->tm_sec + fsec); #endif TrimTrailingZeros(str); } @@ -3394,21 +3367,20 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha sprintf((str + 10), " %02d:%02d", tm->tm_hour, tm->tm_min); /* - * If we have fractional seconds, then include a decimal point - * We will do up to 6 fractional digits, and we have rounded - * any inputs to eliminate anything to the right of 6 digits - * anyway. If there are no fractional seconds, then do not - * bother printing a decimal point at all. - thomas 2001-09-29 + * Print fractional seconds if any. The field widths here should + * be at least equal to MAX_TIMESTAMP_PRECISION. + * + * In float mode, don't print fractional seconds before 1 AD, + * since it's unlikely there's any precision left ... */ #ifdef HAVE_INT64_TIMESTAMP if (fsec != 0) { - sprintf((str + strlen(str)), ":%02d", tm->tm_sec); - sprintf((str + strlen(str)), ".%06d", fsec); + sprintf((str + strlen(str)), ":%02d.%06d", tm->tm_sec, fsec); #else if ((fsec != 0) && (tm->tm_year > 0)) { - sprintf((str + strlen(str)), ":%013.10f", sec); + sprintf((str + strlen(str)), ":%09.6f", tm->tm_sec + fsec); #endif TrimTrailingZeros(str); } diff --git a/src/include/utils/date.h b/src/include/utils/date.h index eaaac77c16a34973b712096598950fa93d0f4aa7..cffa1d48749ac34604182e30297af8fb11323f34 100644 --- a/src/include/utils/date.h +++ b/src/include/utils/date.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: date.h,v 1.21 2002/09/04 20:31:45 momjian Exp $ + * $Id: date.h,v 1.22 2003/01/29 01:08:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -41,7 +41,7 @@ typedef struct #ifdef HAVE_INT64_TIMESTAMP #define MAX_TIME_PRECISION 6 #else -#define MAX_TIME_PRECISION 13 +#define MAX_TIME_PRECISION 10 #endif /*