summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/parser/gram.y24
-rw-r--r--src/backend/utils/adt/datetime.c73
-rw-r--r--src/backend/utils/adt/nabstime.c20
-rw-r--r--src/backend/utils/adt/timestamp.c26
-rw-r--r--src/test/regress/expected/horology.out4
-rw-r--r--src/test/regress/expected/timestamptz.out24
6 files changed, 114 insertions, 57 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 59db3b180ce..4f5f5d6b7e8 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.264 2001/10/18 23:16:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.265 2001/10/20 01:02:14 thomas Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -887,13 +887,18 @@ zone_value: Sconst
| ConstInterval Sconst opt_interval
{
A_Const *n = (A_Const *) makeStringConst($2, $1);
- n->typename->typmod = (($3 << 16) | 0xFFFF);
+ if ($3 != -1)
+ n->typename->typmod = (($3 << 16) | 0xFFFF);
$$ = (Node *)n;
}
| ConstInterval '(' Iconst ')' Sconst opt_interval
{
A_Const *n = (A_Const *) makeStringConst($5, $1);
- n->typename->typmod = (($3 << 16) | $6);
+ if ($6 != -1)
+ n->typename->typmod = (($6 << 16) | $3);
+ else
+ n->typename->typmod = ((0x7FFF << 16) | $3);
+
$$ = (Node *)n;
}
| FCONST
@@ -4044,12 +4049,13 @@ SimpleTypename: ConstTypename
| ConstInterval opt_interval
{
$$ = $1;
- $$->typmod = (($2 << 16) | 0xFFFF);
+ if ($2 != -1)
+ $$->typmod = ((($2 & 0x7FFF) << 16) | 0xFFFF);
}
| ConstInterval '(' Iconst ')' opt_interval
{
$$ = $1;
- $$->typmod = (($5 << 16) | $3);
+ $$->typmod = ((($5 & 0x7FFF) << 16) | $3);
}
;
@@ -5625,7 +5631,9 @@ AexprConst: Iconst
n->typename = $1;
n->val.type = T_String;
n->val.val.str = $2;
- n->typename->typmod = (($3 << 16) | 0xFFFF);
+ /* precision is not specified, but fields may be... */
+ if ($3 != -1)
+ n->typename->typmod = ((($3 & 0x7FFF) << 16) | 0xFFFF);
$$ = (Node *)n;
}
| ConstInterval '(' Iconst ')' Sconst opt_interval
@@ -5634,7 +5642,9 @@ AexprConst: Iconst
n->typename = $1;
n->val.type = T_String;
n->val.val.str = $5;
- n->typename->typmod = (($6 << 16) | $3);
+ /* precision specified, and fields may be... */
+ n->typename->typmod = ((($6 & 0x7FFF) << 16) | $3);
+
$$ = (Node *)n;
}
| ParamNo
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 275231983ee..6d6fbd6b456 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.73 2001/10/18 17:30:15 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.74 2001/10/20 01:02:18 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -385,17 +385,22 @@ j2day(int date)
} /* j2day() */
+/* TrimTrailingZeros()
+ * ... resulting from printing numbers with full precision.
+ */
void
TrimTrailingZeros(char *str)
{
int len = strlen(str);
+#if 0
/* chop off trailing one to cope with interval rounding */
if (strcmp((str + len - 4), "0001") == 0)
{
len -= 4;
*(str + len) = '\0';
}
+#endif
/* chop off trailing zeros... */
while ((*(str + len - 1) == '0')
@@ -905,11 +910,12 @@ DecodeDateTime(char **field, int *ftype, int nf,
break;
case UNITS:
- ptype = val;
tmask = 0;
+ ptype = val;
break;
case DTK_ISO_TIME:
+ tmask = 0;
if ((i < 1) || (i >= (nf-1))
|| (ftype[i-1] != DTK_DATE)
|| (ftype[i+1] != DTK_TIME))
@@ -2267,10 +2273,10 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
}
/* tzp == NULL indicates that we don't want *any* time zone info in the output string.
- * *tzn != NULL indicates that we *have* time zone info available.
+ * *tzn != NULL indicates that we have alpha time zone info available.
* tm_isdst != -1 indicates that we have a valid time zone translation.
*/
- if ((tzp != NULL) && (*tzn != NULL) && (tm->tm_isdst >= 0))
+ if ((tzp != NULL) && (tm->tm_isdst >= 0))
{
hour = -(*tzp / 3600);
min = ((abs(*tzp) / 60) % 60);
@@ -2315,14 +2321,18 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
sprintf((str + strlen(str)), ":%02.0f", sec);
}
- if ((*tzn != NULL) && (tm->tm_isdst >= 0))
- sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn);
-
- else if (tzp != NULL)
+ if ((tzp != NULL) && (tm->tm_isdst >= 0))
{
- hour = -(*tzp / 3600);
- min = ((abs(*tzp) / 60) % 60);
- sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
+ if (*tzn != NULL)
+ {
+ sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn);
+ }
+ else
+ {
+ hour = -(*tzp / 3600);
+ min = ((abs(*tzp) / 60) % 60);
+ sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
+ }
}
}
else
@@ -2353,14 +2363,18 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
sprintf((str + strlen(str)), ":%02.0f", sec);
}
- if ((*tzn != NULL) && (tm->tm_isdst >= 0))
- sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn);
-
- else if (tzp != NULL)
+ if ((tzp != NULL) && (tm->tm_isdst >= 0))
{
- hour = -(*tzp / 3600);
- min = ((abs(*tzp) / 60) % 60);
- sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
+ if (*tzn != NULL)
+ {
+ sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn);
+ }
+ else
+ {
+ hour = -(*tzp / 3600);
+ min = ((abs(*tzp) / 60) % 60);
+ sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
+ }
}
}
else
@@ -2403,14 +2417,23 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
sprintf((str + strlen(str)), " %04d", tm->tm_year);
- if ((tzp != NULL) && (*tzn != NULL) && (tm->tm_isdst >= 0))
- sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn);
-
- else if (HasCTZSet && (tzp != NULL))
+ if ((tzp != NULL) && (tm->tm_isdst >= 0))
{
- hour = -(*tzp / 3600);
- min = ((abs(*tzp) / 60) % 60);
- sprintf((str + strlen(str)), ((min != 0) ? "%+03d:%02d" : "%+03d"), hour, min);
+ if (*tzn != NULL)
+ {
+ sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn);
+ }
+ else
+ {
+ /* We have a time zone, but no string version.
+ * Use the numeric form, but be sure to include a leading space
+ * to avoid formatting something which would be rejected by the
+ * date/time parser later. - thomas 2001-10-19
+ */
+ hour = -(*tzp / 3600);
+ min = ((abs(*tzp) / 60) % 60);
+ sprintf((str + strlen(str)), ((min != 0) ? " %+03d:%02d" : " %+03d"), hour, min);
+ }
}
}
else
diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c
index 55642a1c096..29608aa78db 100644
--- a/src/backend/utils/adt/nabstime.c
+++ b/src/backend/utils/adt/nabstime.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.89 2001/10/18 19:52:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.90 2001/10/20 01:02:18 thomas Exp $
*
* NOTES
*
@@ -256,7 +256,7 @@ GetCurrentAbsoluteTimeUsec(int *usec)
};
return (AbsoluteTime) now;
-} /* GetCurrentAbsoluteTime() */
+} /* GetCurrentAbsoluteTimeUsec() */
void
@@ -344,7 +344,7 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
{
*tzp = CTimeZone;
tm->tm_gmtoff = CTimeZone;
- tm->tm_isdst = -1;
+ tm->tm_isdst = 0;
tm->tm_zone = NULL;
if (tzn != NULL)
*tzn = NULL;
@@ -366,6 +366,10 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
}
}
}
+ else
+ {
+ tm->tm_isdst = -1;
+ }
#elif defined(HAVE_INT_TIMEZONE)
if (tzp != NULL)
{
@@ -376,7 +380,7 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
if (HasCTZSet)
{
*tzp = CTimeZone;
- tm->tm_isdst = -1;
+ tm->tm_isdst = 0;
if (tzn != NULL)
*tzn = NULL;
}
@@ -397,6 +401,10 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
}
}
}
+ else
+ {
+ tm->tm_isdst = -1;
+ }
#endif
#else /* not (HAVE_TM_ZONE || HAVE_INT_TIMEZONE) */
if (tzp != NULL)
@@ -426,6 +434,10 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
}
}
}
+ else
+ {
+ tm->tm_isdst = -1;
+ }
#endif
return;
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index efe4a501463..f39e85b235e 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.57 2001/10/18 19:54:59 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.58 2001/10/20 01:02:18 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@@ -374,14 +374,14 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
{
if (typmod != -1)
{
- int range = ((typmod >> 16) & 0xFFFF);
+ int range = ((typmod >> 16) & 0x7FFF);
int precision = (typmod & 0xFFFF);
- if (range == 0xFFFF)
+ if (range == 0x7FFF)
{
/* Do nothing... */
}
- if (range == MASK(YEAR))
+ else if (range == MASK(YEAR))
{
interval->month = ((interval->month / 12) * 12);
interval->time = 0;
@@ -483,7 +483,18 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
IntervalScale = pow(10.0, IntervalTypmod);
}
- interval->time = (rint(interval->time * IntervalScale) / IntervalScale);
+ /* Hmm. For the time field, we can get to a large value
+ * since we store everything related to an absolute interval
+ * (e.g. years worth of days) in this one field. So we have
+ * precision problems doing rint() on this field if the field
+ * is too large. This resulted in an annoying "...0001" appended
+ * to the printed result on my Linux box.
+ * I hate doing an expensive math operation like log10()
+ * to avoid this, but what else can we do??
+ * - thomas 2001-10-19
+ */
+ if ((log10(interval->time) + IntervalTypmod) <= 13)
+ interval->time = (rint(interval->time * IntervalScale) / IntervalScale);
}
}
@@ -671,14 +682,15 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, double *fsec, char **tzn)
else
{
*tzp = 0;
- tm->tm_isdst = 0;
+ /* Mark this as *no* time zone available */
+ tm->tm_isdst = -1;
if (tzn != NULL)
*tzn = NULL;
}
}
else
{
- tm->tm_isdst = 0;
+ tm->tm_isdst = -1;
if (tzn != NULL)
*tzn = NULL;
}
diff --git a/src/test/regress/expected/horology.out b/src/test/regress/expected/horology.out
index c0dec193906..f911fc368fd 100644
--- a/src/test/regress/expected/horology.out
+++ b/src/test/regress/expected/horology.out
@@ -359,7 +359,7 @@ SELECT '' AS "64", d1 + interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL;
| Tue Feb 10 17:32:01 1998 PST
| Tue Feb 10 17:32:01 1998 PST
| Wed Jun 10 17:32:01 1998 PDT
- | Sun Sep 22 11:19:20 2002 PDT
+ | Sun Sep 22 18:19:20 2002 PDT
| Thu Mar 15 08:14:01 2001 PST
| Thu Mar 15 04:14:02 2001 PST
| Thu Mar 15 02:14:03 2001 PST
@@ -428,7 +428,7 @@ SELECT '' AS "64", d1 - interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL;
| Sat Feb 10 17:32:01 1996 PST
| Sat Feb 10 17:32:01 1996 PST
| Mon Jun 10 17:32:01 1996 PDT
- | Fri Sep 22 11:19:20 2000 PDT
+ | Fri Sep 22 18:19:20 2000 PDT
| Mon Mar 15 08:14:01 1999 PST
| Mon Mar 15 04:14:02 1999 PST
| Mon Mar 15 02:14:03 1999 PST
diff --git a/src/test/regress/expected/timestamptz.out b/src/test/regress/expected/timestamptz.out
index dd7ef75ce8f..70325aac85c 100644
--- a/src/test/regress/expected/timestamptz.out
+++ b/src/test/regress/expected/timestamptz.out
@@ -152,7 +152,7 @@ SELECT '' AS "64", d1 FROM TIMESTAMPTZ_TBL;
| Mon Feb 10 17:32:01 1997 PST
| Mon Feb 10 17:32:01 1997 PST
| Tue Jun 10 17:32:01 1997 PDT
- | Sat Sep 22 11:19:20 2001 PDT
+ | Sat Sep 22 18:19:20 2001 PDT
| Wed Mar 15 08:14:01 2000 PST
| Wed Mar 15 04:14:02 2000 PST
| Wed Mar 15 02:14:03 2000 PST
@@ -220,7 +220,7 @@ SELECT '' AS "48", d1 FROM TIMESTAMPTZ_TBL
| Mon Feb 10 17:32:01 1997 PST
| Mon Feb 10 17:32:01 1997 PST
| Tue Jun 10 17:32:01 1997 PDT
- | Sat Sep 22 11:19:20 2001 PDT
+ | Sat Sep 22 18:19:20 2001 PDT
| Wed Mar 15 08:14:01 2000 PST
| Wed Mar 15 04:14:02 2000 PST
| Wed Mar 15 02:14:03 2000 PST
@@ -304,7 +304,7 @@ SELECT '' AS "63", d1 FROM TIMESTAMPTZ_TBL
| Mon Feb 10 17:32:01 1997 PST
| Mon Feb 10 17:32:01 1997 PST
| Tue Jun 10 17:32:01 1997 PDT
- | Sat Sep 22 11:19:20 2001 PDT
+ | Sat Sep 22 18:19:20 2001 PDT
| Wed Mar 15 08:14:01 2000 PST
| Wed Mar 15 04:14:02 2000 PST
| Wed Mar 15 02:14:03 2000 PST
@@ -394,7 +394,7 @@ SELECT '' AS "49", d1 FROM TIMESTAMPTZ_TBL
| Mon Feb 10 17:32:01 1997 PST
| Mon Feb 10 17:32:01 1997 PST
| Tue Jun 10 17:32:01 1997 PDT
- | Sat Sep 22 11:19:20 2001 PDT
+ | Sat Sep 22 18:19:20 2001 PDT
| Wed Mar 15 08:14:01 2000 PST
| Wed Mar 15 04:14:02 2000 PST
| Wed Mar 15 02:14:03 2000 PST
@@ -449,7 +449,7 @@ SELECT '' AS "54", d1 - timestamp with time zone '1997-01-02' AS diff
| @ 39 days 17 hours 32 mins 1 sec
| @ 39 days 17 hours 32 mins 1 sec
| @ 159 days 16 hours 32 mins 1 sec
- | @ 1724 days 10 hours 19 mins 20 secs
+ | @ 1724 days 17 hours 19 mins 20 secs
| @ 1168 days 8 hours 14 mins 1 sec
| @ 1168 days 4 hours 14 mins 2 secs
| @ 1168 days 2 hours 14 mins 3 secs
@@ -511,7 +511,7 @@ SELECT '' AS "54", d1 - timestamp with time zone '1997-01-02' AS diff
| @ 39 days 17 hours 32 mins 1 sec
| @ 39 days 17 hours 32 mins 1 sec
| @ 159 days 16 hours 32 mins 1 sec
- | @ 1724 days 10 hours 19 mins 20 secs
+ | @ 1724 days 17 hours 19 mins 20 secs
| @ 1168 days 8 hours 14 mins 1 sec
| @ 1168 days 4 hours 14 mins 2 secs
| @ 1168 days 2 hours 14 mins 3 secs
@@ -574,7 +574,7 @@ SELECT '' AS "54", d1 as timestamptz,
| Mon Feb 10 17:32:01 1997 PST | 1997 | 2 | 10 | 17 | 32 | 1
| Mon Feb 10 17:32:01 1997 PST | 1997 | 2 | 10 | 17 | 32 | 1
| Tue Jun 10 17:32:01 1997 PDT | 1997 | 6 | 10 | 17 | 32 | 1
- | Sat Sep 22 11:19:20 2001 PDT | 2001 | 9 | 22 | 11 | 19 | 20
+ | Sat Sep 22 18:19:20 2001 PDT | 2001 | 9 | 22 | 18 | 19 | 20
| Wed Mar 15 08:14:01 2000 PST | 2000 | 3 | 15 | 8 | 14 | 1
| Wed Mar 15 04:14:02 2000 PST | 2000 | 3 | 15 | 4 | 14 | 2
| Wed Mar 15 02:14:03 2000 PST | 2000 | 3 | 15 | 2 | 14 | 3
@@ -636,7 +636,7 @@ SELECT '' AS "54", d1 as timestamptz,
| Mon Feb 10 17:32:01 1997 PST | 1 | 0 | 0
| Mon Feb 10 17:32:01 1997 PST | 1 | 0 | 0
| Tue Jun 10 17:32:01 1997 PDT | 2 | 0 | 0
- | Sat Sep 22 11:19:20 2001 PDT | 3 | 0 | 0
+ | Sat Sep 22 18:19:20 2001 PDT | 3 | 0 | 0
| Wed Mar 15 08:14:01 2000 PST | 1 | 0 | 0
| Wed Mar 15 04:14:02 2000 PST | 1 | 0 | 0
| Wed Mar 15 02:14:03 2000 PST | 1 | 0 | 0
@@ -982,7 +982,7 @@ SELECT '' AS to_char_5, to_char(d1, 'HH HH12 HH24 MI SS SSSS')
| 05 05 17 32 01 63121
| 05 05 17 32 01 63121
| 05 05 17 32 01 63121
- | 11 11 11 19 20 40760
+ | 06 06 18 19 20 65960
| 08 08 08 14 01 29641
| 04 04 04 14 02 15242
| 02 02 02 14 03 8043
@@ -1052,7 +1052,7 @@ SELECT '' AS to_char_6, to_char(d1, '"HH:MI:SS is" HH:MI:SS "\\"text between quo
| HH:MI:SS is 05:32:01 "text between quote marks"
| HH:MI:SS is 05:32:01 "text between quote marks"
| HH:MI:SS is 05:32:01 "text between quote marks"
- | HH:MI:SS is 11:19:20 "text between quote marks"
+ | HH:MI:SS is 06:19:20 "text between quote marks"
| HH:MI:SS is 08:14:01 "text between quote marks"
| HH:MI:SS is 04:14:02 "text between quote marks"
| HH:MI:SS is 02:14:03 "text between quote marks"
@@ -1123,7 +1123,7 @@ SELECT '' AS to_char_7, to_char(d1, 'HH24--text--MI--text--SS')
| 17--text--32--text--01
| 17--text--32--text--01
| 17--text--32--text--01
- | 11--text--19--text--20
+ | 18--text--19--text--20
| 08--text--14--text--01
| 04--text--14--text--02
| 02--text--14--text--03
@@ -1264,7 +1264,7 @@ SELECT '' AS to_char_9, to_char(d1, 'YYYY A.D. YYYY a.d. YYYY bc HH:MI:SS P.M. H
| 1997 A.D. 1997 a.d. 1997 ad 05:32:01 P.M. 05:32:01 p.m. 05:32:01 pm
| 1997 A.D. 1997 a.d. 1997 ad 05:32:01 P.M. 05:32:01 p.m. 05:32:01 pm
| 1997 A.D. 1997 a.d. 1997 ad 05:32:01 P.M. 05:32:01 p.m. 05:32:01 pm
- | 2001 A.D. 2001 a.d. 2001 ad 11:19:20 A.M. 11:19:20 a.m. 11:19:20 am
+ | 2001 A.D. 2001 a.d. 2001 ad 06:19:20 P.M. 06:19:20 p.m. 06:19:20 pm
| 2000 A.D. 2000 a.d. 2000 ad 08:14:01 A.M. 08:14:01 a.m. 08:14:01 am
| 2000 A.D. 2000 a.d. 2000 ad 04:14:02 A.M. 04:14:02 a.m. 04:14:02 am
| 2000 A.D. 2000 a.d. 2000 ad 02:14:03 A.M. 02:14:03 a.m. 02:14:03 am