]> granicus.if.org Git - postgresql/commitdiff
Adjust date/time input parsing code to correctly distinguish the four
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 27 Aug 2003 23:29:29 +0000 (23:29 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 27 Aug 2003 23:29:29 +0000 (23:29 +0000)
SQLSTATE error codes required by SQL99 (invalid format, datetime field
overflow, interval field overflow, invalid time zone displacement value).
Also emit a HINT about DateStyle in cases where it seems appropriate.
Per recent gripes.

13 files changed:
src/backend/utils/adt/date.c
src/backend/utils/adt/datetime.c
src/backend/utils/adt/nabstime.c
src/backend/utils/adt/timestamp.c
src/include/utils/datetime.h
src/test/regress/expected/abstime-solaris-1947.out
src/test/regress/expected/abstime.out
src/test/regress/expected/date.out
src/test/regress/expected/horology-no-DST-before-1970.out
src/test/regress/expected/horology-solaris-1947.out
src/test/regress/expected/horology.out
src/test/regress/expected/timestamp.out
src/test/regress/expected/timestamptz.out

index 0f9fcaded9e8d2afcb54ed243d06d97d07ae2e17..60583fed7a65a8d8c54e3e8550649bb9f1b8f86b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.90 2003/08/08 00:10:31 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.91 2003/08/27 23:29:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -62,20 +62,19 @@ date_in(PG_FUNCTION_ARGS)
        int                     tzp;
        int                     dtype;
        int                     nf;
+       int                     dterr;
        char       *field[MAXDATEFIELDS];
        int                     ftype[MAXDATEFIELDS];
        char            lowstr[MAXDATELEN + 1];
 
        if (strlen(str) >= sizeof(lowstr))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                                errmsg("invalid input syntax for date: \"%s\"", str)));
-
-       if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
-        || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp) != 0))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                                errmsg("invalid input syntax for date: \"%s\"", str)));
+               dterr = DTERR_BAD_FORMAT;
+       else
+               dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
+       if (dterr == 0)
+               dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp);
+       if (dterr != 0)
+               DateTimeParseError(dterr, str, "date");
 
        switch (dtype)
        {
@@ -95,9 +94,8 @@ date_in(PG_FUNCTION_ARGS)
                        break;
 
                default:
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                                 errmsg("invalid input syntax for date: \"%s\"", str)));
+                       DateTimeParseError(DTERR_BAD_FORMAT, str, "date");
+                       break;
        }
 
        date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
@@ -559,21 +557,20 @@ time_in(PG_FUNCTION_ARGS)
                           *tm = &tt;
        int                     tz;
        int                     nf;
+       int                     dterr;
        char            lowstr[MAXDATELEN + 1];
        char       *field[MAXDATEFIELDS];
        int                     dtype;
        int                     ftype[MAXDATEFIELDS];
 
        if (strlen(str) >= sizeof(lowstr))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                                errmsg("invalid input syntax for time: \"%s\"", str)));
-
-       if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
-         || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                                errmsg("invalid input syntax for time: \"%s\"", str)));
+               dterr = DTERR_BAD_FORMAT;
+       else
+               dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
+       if (dterr == 0)
+               dterr = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz);
+       if (dterr != 0)
+               DateTimeParseError(dterr, str, "time");
 
        tm2time(tm, fsec, &result);
        AdjustTimeForTypmod(&result, typmod);
@@ -1424,23 +1421,20 @@ timetz_in(PG_FUNCTION_ARGS)
                           *tm = &tt;
        int                     tz;
        int                     nf;
+       int                     dterr;
        char            lowstr[MAXDATELEN + 1];
        char       *field[MAXDATEFIELDS];
        int                     dtype;
        int                     ftype[MAXDATEFIELDS];
 
        if (strlen(str) >= sizeof(lowstr))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                  errmsg("invalid input syntax for time with time zone: \"%s\"",
-                                 str)));
-
-       if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
-         || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                  errmsg("invalid input syntax for time with time zone: \"%s\"",
-                                 str)));
+               dterr = DTERR_BAD_FORMAT;
+       else
+               dterr = ParseDateTime(str, lowstr, 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);
index 3a06d63ed3da5449cd753434328a9b1c50003bfd..ca3bb2a22ea414ac4932974ca771c13138dd6cb5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.115 2003/08/25 23:30:27 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.116 2003/08/27 23:29:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -699,7 +699,7 @@ TrimTrailingZeros(char *str)
 
 /* ParseDateTime()
  *     Break string into tokens based on a date/time context.
- *     Returns 0 if successful, -1 if bogus input detected.
+ *     Returns 0 if successful, DTERR code if bogus input detected.
  *
  * timestr - the input string
  * lowstr - workspace for field string storage (must be large enough for
@@ -745,7 +745,7 @@ ParseDateTime(const char *timestr, char *lowstr,
 
                /* Record start of current field */
                if (nf >= maxfields)
-                       return -1;
+                       return DTERR_BAD_FORMAT;
                field[nf] = lp;
 
                /* leading digit? then date or time */
@@ -866,7 +866,7 @@ ParseDateTime(const char *timestr, char *lowstr,
                        }
                        /* otherwise something wrong... */
                        else
-                               return -1;
+                               return DTERR_BAD_FORMAT;
                }
                /* ignore other punctuation but use as delimiter */
                else if (ispunct((unsigned char) *cp))
@@ -876,7 +876,7 @@ ParseDateTime(const char *timestr, char *lowstr,
                }
                /* otherwise, something is not right... */
                else
-                       return -1;
+                       return DTERR_BAD_FORMAT;
 
                /* force in a delimiter after each field */
                *lp++ = '\0';
@@ -891,7 +891,9 @@ ParseDateTime(const char *timestr, char *lowstr,
 
 /* DecodeDateTime()
  * Interpret previously parsed fields for general date and time.
- * Return 0 if full date, 1 if only time, and -1 if problems.
+ * Return 0 if full date, 1 if only time, and negative DTERR code if problems.
+ * (Currently, all callers treat 1 as an error return too.)
+ *
  *             External format(s):
  *                             "<weekday> <month>-<day>-<year> <hour>:<minute>:<second>"
  *                             "Fri Feb-7-1997 15:23:27"
@@ -920,15 +922,16 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                                                 * format */
        int                     i;
        int                     val;
+       int                     dterr;
        int                     mer = HR24;
        int                     haveTextMonth = FALSE;
        int                     is2digits = FALSE;
        int                     bc = FALSE;
 
-       /***
+       /*
         * We'll insist on at least all of the date fields, but initialize the
         * remaining fields in case they are not set later...
-        ***/
+        */
        *dtype = DTK_DATE;
        tm->tm_hour = 0;
        tm->tm_min = 0;
@@ -955,14 +958,15 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                        int                     val;
 
                                        if (tzp == NULL)
-                                               return -1;
+                                               return DTERR_BAD_FORMAT;
 
                                        val = strtol(field[i], &cp, 10);
 
                                        j2date(val, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
                                        /* Get the time zone from the end of the string */
-                                       if (DecodeTimezone(cp, tzp) != 0)
-                                               return -1;
+                                       dterr = DecodeTimezone(cp, tzp);
+                                       if (dterr)
+                                               return dterr;
 
                                        tmask = DTK_DATE_M | DTK_TIME_M | DTK_M(TZ);
                                        ptype = 0;
@@ -979,7 +983,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                {
                                        /* No time zone accepted? Then quit... */
                                        if (tzp == NULL)
-                                               return -1;
+                                               return DTERR_BAD_FORMAT;
 
                                        if (isdigit((unsigned char) *field[i]) || ptype != 0)
                                        {
@@ -989,7 +993,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                                {
                                                        /* Sanity check; should not fail this test */
                                                        if (ptype != DTK_TIME)
-                                                               return -1;
+                                                               return DTERR_BAD_FORMAT;
                                                        ptype = 0;
                                                }
 
@@ -999,23 +1003,28 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                                 * time already...
                                                 */
                                                if ((fmask & DTK_TIME_M) == DTK_TIME_M)
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
 
                                                if ((cp = strchr(field[i], '-')) == NULL)
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
 
                                                /* Get the time zone from the end of the string */
-                                               if (DecodeTimezone(cp, tzp) != 0)
-                                                       return -1;
+                                               dterr = DecodeTimezone(cp, tzp);
+                                               if (dterr)
+                                                       return dterr;
                                                *cp = '\0';
 
                                                /*
                                                 * Then read the rest of the field as a
                                                 * concatenated time
                                                 */
-                                               if ((ftype[i] = DecodeNumberField(strlen(field[i]), field[i], fmask,
-                                                                         &tmask, tm, fsec, &is2digits)) < 0)
-                                                       return -1;
+                                               dterr = DecodeNumberField(strlen(field[i]), field[i],
+                                                                                                 fmask,
+                                                                                                 &tmask, tm,
+                                                                                                 fsec, &is2digits);
+                                               if (dterr < 0)
+                                                       return dterr;
+                                               ftype[i] = dterr;
 
                                                /*
                                                 * modify tmask after returning from
@@ -1025,27 +1034,33 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                        }
                                        else
                                        {
-                                               if (DecodePosixTimezone(field[i], tzp) != 0)
-                                                       return -1;
+                                               dterr = DecodePosixTimezone(field[i], tzp);
+                                               if (dterr)
+                                                       return dterr;
 
                                                ftype[i] = DTK_TZ;
                                                tmask = DTK_M(TZ);
                                        }
                                }
-                               else if (DecodeDate(field[i], fmask, &tmask, tm) != 0)
-                                       return -1;
+                               else
+                               {
+                                       dterr = DecodeDate(field[i], fmask, &tmask, tm);
+                                       if (dterr)
+                                               return dterr;
+                               }
                                break;
 
                        case DTK_TIME:
-                               if (DecodeTime(field[i], fmask, &tmask, tm, fsec) != 0)
-                                       return -1;
+                               dterr = DecodeTime(field[i], fmask, &tmask, tm, fsec);
+                               if (dterr)
+                                       return dterr;
 
                                /*
                                 * Check upper limit on hours; other limits checked in
                                 * DecodeTime()
                                 */
                                if (tm->tm_hour > 23)
-                                       return -1;
+                                       return DTERR_FIELD_OVERFLOW;
                                break;
 
                        case DTK_TZ:
@@ -1053,10 +1068,11 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                        int                     tz;
 
                                        if (tzp == NULL)
-                                               return -1;
+                                               return DTERR_BAD_FORMAT;
 
-                                       if (DecodeTimezone(field[i], &tz) != 0)
-                                               return -1;
+                                       dterr = DecodeTimezone(field[i], &tz);
+                                       if (dterr)
+                                               return dterr;
 
                                        /*
                                         * Already have a time zone? Then maybe this is the
@@ -1103,11 +1119,11 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                                        case DTK_SECOND:
                                                                break;
                                                        default:
-                                                               return 1;
+                                                               return DTERR_BAD_FORMAT;
                                                                break;
                                                }
                                        else if (*cp != '\0')
-                                               return -1;
+                                               return DTERR_BAD_FORMAT;
 
                                        switch (ptype)
                                        {
@@ -1159,7 +1175,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
 
                                                                frac = strtod(cp, &cp);
                                                                if (*cp != '\0')
-                                                                       return -1;
+                                                                       return DTERR_BAD_FORMAT;
 #ifdef HAVE_INT64_TIMESTAMP
                                                                *fsec = rint(frac * 1000000);
 #else
@@ -1170,8 +1186,9 @@ DecodeDateTime(char **field, int *ftype, int nf,
 
                                                case DTK_TZ:
                                                        tmask = DTK_M(TZ);
-                                                       if (DecodeTimezone(field[i], tzp) != 0)
-                                                               return -1;
+                                                       dterr = DecodeTimezone(field[i], tzp);
+                                                       if (dterr)
+                                                               return dterr;
                                                        break;
 
                                                case DTK_JULIAN:
@@ -1187,7 +1204,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
 
                                                                time = strtod(cp, &cp);
                                                                if (*cp != '\0')
-                                                                       return -1;
+                                                                       return DTERR_BAD_FORMAT;
 
                                                                tmask |= DTK_TIME_M;
 #ifdef HAVE_INT64_TIMESTAMP
@@ -1202,16 +1219,20 @@ DecodeDateTime(char **field, int *ftype, int nf,
 
                                                case DTK_TIME:
                                                        /* previous field was "t" for ISO time */
-                                                       if ((ftype[i] = DecodeNumberField(strlen(field[i]), field[i], (fmask | DTK_DATE_M),
-                                                                         &tmask, tm, fsec, &is2digits)) < 0)
-                                                               return -1;
+                                                       dterr = DecodeNumberField(strlen(field[i]), field[i],
+                                                                                                         (fmask | DTK_DATE_M),
+                                                                                                         &tmask, tm,
+                                                                                                         fsec, &is2digits);
+                                                       if (dterr < 0)
+                                                               return dterr;
+                                                       ftype[i] = dterr;
 
                                                        if (tmask != DTK_TIME_M)
-                                                               return -1;
+                                                               return DTERR_BAD_FORMAT;
                                                        break;
 
                                                default:
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
                                                        break;
                                        }
 
@@ -1229,8 +1250,9 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                        /* Embedded decimal and no date yet? */
                                        if ((cp != NULL) && !(fmask & DTK_DATE_M))
                                        {
-                                               if (DecodeDate(field[i], fmask, &tmask, tm) != 0)
-                                                       return -1;
+                                               dterr = DecodeDate(field[i], fmask, &tmask, tm);
+                                               if (dterr)
+                                                       return dterr;
                                        }
                                        /* embedded decimal and several digits before? */
                                        else if ((cp != NULL) && ((flen - strlen(cp)) > 2))
@@ -1240,20 +1262,31 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                                 * the type field to allow decoding other fields
                                                 * later. Example: 20011223 or 040506
                                                 */
-                                               if ((ftype[i] = DecodeNumberField(flen, field[i], fmask,
-                                                                         &tmask, tm, fsec, &is2digits)) < 0)
-                                                       return -1;
+                                               dterr = DecodeNumberField(flen, field[i], fmask,
+                                                                                                 &tmask, tm,
+                                                                                                 fsec, &is2digits);
+                                               if (dterr < 0)
+                                                       return dterr;
+                                               ftype[i] = dterr;
                                        }
                                        else if (flen > 4)
                                        {
-                                               if ((ftype[i] = DecodeNumberField(flen, field[i], fmask,
-                                                                         &tmask, tm, fsec, &is2digits)) < 0)
-                                                       return -1;
+                                               dterr = DecodeNumberField(flen, field[i], fmask,
+                                                                                                 &tmask, tm,
+                                                                                                 fsec, &is2digits);
+                                               if (dterr < 0)
+                                                       return dterr;
+                                               ftype[i] = dterr;
                                        }
                                        /* otherwise it is a single date/time field... */
-                                       else if (DecodeNumber(flen, field[i], fmask,
-                                                                         &tmask, tm, fsec, &is2digits) != 0)
-                                               return -1;
+                                       else
+                                       {
+                                               dterr = DecodeNumber(flen, field[i], fmask,
+                                                                                        &tmask, tm,
+                                                                                        fsec, &is2digits);
+                                               if (dterr)
+                                                       return dterr;
+                                       }
                                }
                                break;
 
@@ -1274,7 +1307,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                                                  errmsg("\"current\" is no longer supported")));
 
-                                                               return -1;
+                                                               return DTERR_BAD_FORMAT;
                                                                break;
 
                                                        case DTK_NOW:
@@ -1356,7 +1389,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                                tmask |= DTK_M(DTZ);
                                                tm->tm_isdst = 1;
                                                if (tzp == NULL)
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
                                                *tzp += val * 60;
                                                break;
 
@@ -1369,7 +1402,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                                tmask |= DTK_M(TZ);
                                                tm->tm_isdst = 1;
                                                if (tzp == NULL)
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
                                                *tzp = val * 60;
                                                ftype[i] = DTK_TZ;
                                                break;
@@ -1377,7 +1410,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                        case TZ:
                                                tm->tm_isdst = 0;
                                                if (tzp == NULL)
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
                                                *tzp = val * 60;
                                                ftype[i] = DTK_TZ;
                                                break;
@@ -1411,9 +1444,9 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                                 */
                                                tmask = 0;
 
-                                               /* No preceeding date? Then quit... */
+                                               /* No preceding date? Then quit... */
                                                if ((fmask & DTK_DATE_M) != DTK_DATE_M)
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
 
                                                /***
                                                 * We will need one of the following fields:
@@ -1425,22 +1458,22 @@ DecodeDateTime(char **field, int *ftype, int nf,
                                                        || ((ftype[i + 1] != DTK_NUMBER)
                                                                && (ftype[i + 1] != DTK_TIME)
                                                                && (ftype[i + 1] != DTK_DATE)))
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
 
                                                ptype = val;
                                                break;
 
                                        default:
-                                               return -1;
+                                               return DTERR_BAD_FORMAT;
                                }
                                break;
 
                        default:
-                               return -1;
+                               return DTERR_BAD_FORMAT;
                }
 
                if (tmask & fmask)
-                       return -1;
+                       return DTERR_BAD_FORMAT;
                fmask |= tmask;
        }
 
@@ -1477,18 +1510,18 @@ DecodeDateTime(char **field, int *ftype, int nf,
        if (fmask & DTK_M(MONTH))
        {
                if (tm->tm_mon < 1 || tm->tm_mon > 12)
-                       return -1;
+                       return DTERR_MD_FIELD_OVERFLOW;
        }
 
        /* minimal check for valid day */
        if (fmask & DTK_M(DAY))
        {
                if (tm->tm_mday < 1 || tm->tm_mday > 31)
-                       return -1;
+                       return DTERR_MD_FIELD_OVERFLOW;
        }
 
        if ((mer != HR24) && (tm->tm_hour > 12))
-               return -1;
+               return DTERR_FIELD_OVERFLOW;
        if ((mer == AM) && (tm->tm_hour == 12))
                tm->tm_hour = 0;
        else if ((mer == PM) && (tm->tm_hour != 12))
@@ -1498,14 +1531,19 @@ DecodeDateTime(char **field, int *ftype, int nf,
        if (*dtype == DTK_DATE)
        {
                if ((fmask & DTK_DATE_M) != DTK_DATE_M)
-                       return ((fmask & DTK_TIME_M) == DTK_TIME_M) ? 1 : -1;
+               {
+                       if ((fmask & DTK_TIME_M) == DTK_TIME_M)
+                               return 1;
+                       return DTERR_BAD_FORMAT;
+               }
 
                /*
-                * check for valid day of month, now that we know for sure the
-                * month and year...
+                * Check for valid day of month, now that we know for sure the
+                * month and year.  Note we don't use MD_FIELD_OVERFLOW here,
+                * since it seems unlikely that "Feb 29" is a YMD-order error.
                 */
                if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
-                       return -1;
+                       return DTERR_FIELD_OVERFLOW;
 
                /* timezone not specified? then find local timezone if possible */
                if ((tzp != NULL) && (!(fmask & DTK_M(TZ))))
@@ -1515,14 +1553,14 @@ DecodeDateTime(char **field, int *ftype, int nf,
                         * then error
                         */
                        if (fmask & DTK_M(DTZMOD))
-                               return -1;
+                               return DTERR_BAD_FORMAT;
 
                        *tzp = DetermineLocalTimeZone(tm);
                }
        }
 
        return 0;
-}      /* DecodeDateTime() */
+}
 
 
 /* DetermineLocalTimeZone()
@@ -1673,6 +1711,8 @@ DetermineLocalTimeZone(struct tm * tm)
 
 /* DecodeTimeOnly()
  * Interpret parsed string as time fields only.
+ * Returns 0 if successful, DTERR code if bogus input detected.
+ *
  * Note that support for time zone is here for
  * SQL92 TIME WITH TIME ZONE, but it reveals
  * bogosity with SQL92 date/time standards, since
@@ -1691,6 +1731,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
        int                     ptype = 0;              /* "prefix type" for ISO h04mm05s06 format */
        int                     i;
        int                     val;
+       int                     dterr;
        int                     is2digits = FALSE;
        int                     mer = HR24;
 
@@ -1716,15 +1757,16 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                 * time zones no matter what else!
                                 */
                                if (tzp == NULL)
-                                       return -1;
+                                       return DTERR_BAD_FORMAT;
 
                                /* Under limited circumstances, we will accept a date... */
                                if ((i == 0) && (nf >= 2)
                                        && ((ftype[nf - 1] == DTK_DATE)
                                                || (ftype[1] == DTK_TIME)))
                                {
-                                       if (DecodeDate(field[i], fmask, &tmask, tm) != 0)
-                                               return -1;
+                                       dterr = DecodeDate(field[i], fmask, &tmask, tm);
+                                       if (dterr)
+                                               return dterr;
                                }
                                /* otherwise, this is a time and/or time zone */
                                else
@@ -1739,34 +1781,40 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                                 * already...
                                                 */
                                                if ((fmask & DTK_TIME_M) == DTK_TIME_M)
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
 
                                                /*
                                                 * Should not get here and fail. Sanity check
                                                 * only...
                                                 */
                                                if ((cp = strchr(field[i], '-')) == NULL)
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
 
                                                /* Get the time zone from the end of the string */
-                                               if (DecodeTimezone(cp, tzp) != 0)
-                                                       return -1;
+                                               dterr = DecodeTimezone(cp, tzp);
+                                               if (dterr)
+                                                       return dterr;
                                                *cp = '\0';
 
                                                /*
                                                 * Then read the rest of the field as a
                                                 * concatenated time
                                                 */
-                                               if ((ftype[i] = DecodeNumberField(strlen(field[i]), field[i], (fmask | DTK_DATE_M),
-                                                                         &tmask, tm, fsec, &is2digits)) < 0)
-                                                       return -1;
+                                               dterr = DecodeNumberField(strlen(field[i]), field[i],
+                                                                                                 (fmask | DTK_DATE_M),
+                                                                                                 &tmask, tm,
+                                                                                                 fsec, &is2digits);
+                                               if (dterr < 0)
+                                                       return dterr;
+                                               ftype[i] = dterr;
 
                                                tmask |= DTK_M(TZ);
                                        }
                                        else
                                        {
-                                               if (DecodePosixTimezone(field[i], tzp) != 0)
-                                                       return -1;
+                                               dterr = DecodePosixTimezone(field[i], tzp);
+                                               if (dterr)
+                                                       return dterr;
 
                                                ftype[i] = DTK_TZ;
                                                tmask = DTK_M(TZ);
@@ -1775,19 +1823,22 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                break;
 
                        case DTK_TIME:
-                               if (DecodeTime(field[i], (fmask | DTK_DATE_M), &tmask, tm, fsec) != 0)
-                                       return -1;
+                               dterr = DecodeTime(field[i], (fmask | DTK_DATE_M),
+                                                                  &tmask, tm, fsec);
+                               if (dterr)
+                                       return dterr;
                                break;
 
                        case DTK_TZ:
-                               if (tzp == NULL)
-                                       return -1;
-
                                {
                                        int                     tz;
 
-                                       if (DecodeTimezone(field[i], &tz) != 0)
-                                               return -1;
+                                       if (tzp == NULL)
+                                               return DTERR_BAD_FORMAT;
+
+                                       dterr = DecodeTimezone(field[i], &tz);
+                                       if (dterr)
+                                               return dterr;
 
                                        /*
                                         * Already have a time zone? Then maybe this is the
@@ -1827,7 +1878,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                                case DTK_MONTH:
                                                case DTK_DAY:
                                                        if (tzp == NULL)
-                                                               return -1;
+                                                               return DTERR_BAD_FORMAT;
                                                default:
                                                        break;
                                        }
@@ -1846,11 +1897,11 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                                        case DTK_SECOND:
                                                                break;
                                                        default:
-                                                               return 1;
+                                                               return DTERR_BAD_FORMAT;
                                                                break;
                                                }
                                        else if (*cp != '\0')
-                                               return -1;
+                                               return DTERR_BAD_FORMAT;
 
                                        switch (ptype)
                                        {
@@ -1902,7 +1953,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
 
                                                                frac = strtod(cp, &cp);
                                                                if (*cp != '\0')
-                                                                       return -1;
+                                                                       return DTERR_BAD_FORMAT;
 #ifdef HAVE_INT64_TIMESTAMP
                                                                *fsec = rint(frac * 1000000);
 #else
@@ -1913,8 +1964,9 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
 
                                                case DTK_TZ:
                                                        tmask = DTK_M(TZ);
-                                                       if (DecodeTimezone(field[i], tzp) != 0)
-                                                               return -1;
+                                                       dterr = DecodeTimezone(field[i], tzp);
+                                                       if (dterr)
+                                                               return dterr;
                                                        break;
 
                                                case DTK_JULIAN:
@@ -1929,7 +1981,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
 
                                                                time = strtod(cp, &cp);
                                                                if (*cp != '\0')
-                                                                       return -1;
+                                                                       return DTERR_BAD_FORMAT;
 
                                                                tmask |= DTK_TIME_M;
 #ifdef HAVE_INT64_TIMESTAMP
@@ -1944,16 +1996,20 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
 
                                                case DTK_TIME:
                                                        /* previous field was "t" for ISO time */
-                                                       if ((ftype[i] = DecodeNumberField(strlen(field[i]), field[i], (fmask | DTK_DATE_M),
-                                                                         &tmask, tm, fsec, &is2digits)) < 0)
-                                                               return -1;
+                                                       dterr = DecodeNumberField(strlen(field[i]), field[i],
+                                                                                                         (fmask | DTK_DATE_M),
+                                                                                                         &tmask, tm,
+                                                                                                         fsec, &is2digits);
+                                                       if (dterr < 0)
+                                                               return dterr;
+                                                       ftype[i] = dterr;
 
                                                        if (tmask != DTK_TIME_M)
-                                                               return -1;
+                                                               return DTERR_BAD_FORMAT;
                                                        break;
 
                                                default:
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
                                                        break;
                                        }
 
@@ -1977,8 +2033,9 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                                 */
                                                if ((i == 0) && ((nf >= 2) && (ftype[nf - 1] == DTK_DATE)))
                                                {
-                                                       if (DecodeDate(field[i], fmask, &tmask, tm) != 0)
-                                                               return -1;
+                                                       dterr = DecodeDate(field[i], fmask, &tmask, tm);
+                                                       if (dterr)
+                                                               return dterr;
                                                }
                                                /* embedded decimal and several digits before? */
                                                else if ((flen - strlen(cp)) > 2)
@@ -1988,26 +2045,37 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                                         * Set the type field to allow decoding other
                                                         * fields later. Example: 20011223 or 040506
                                                         */
-                                                       if ((ftype[i] = DecodeNumberField(flen, field[i],
-                                                                                                                         (fmask | DTK_DATE_M),
-                                                                         &tmask, tm, fsec, &is2digits)) < 0)
-                                                               return -1;
+                                                       dterr = DecodeNumberField(flen, field[i],
+                                                                                                         (fmask | DTK_DATE_M),
+                                                                                                         &tmask, tm,
+                                                                                                         fsec, &is2digits);
+                                                       if (dterr < 0)
+                                                               return dterr;
+                                                       ftype[i] = dterr;
                                                }
                                                else
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
                                        }
                                        else if (flen > 4)
                                        {
-                                               if ((ftype[i] = DecodeNumberField(flen, field[i],
-                                                                                                                 (fmask | DTK_DATE_M),
-                                                                         &tmask, tm, fsec, &is2digits)) < 0)
-                                                       return -1;
+                                               dterr = DecodeNumberField(flen, field[i],
+                                                                                                 (fmask | DTK_DATE_M),
+                                                                                                 &tmask, tm,
+                                                                                                 fsec, &is2digits);
+                                               if (dterr < 0)
+                                                       return dterr;
+                                               ftype[i] = dterr;
                                        }
                                        /* otherwise it is a single date/time field... */
-                                       else if (DecodeNumber(flen, field[i],
-                                                                                 (fmask | DTK_DATE_M),
-                                                                         &tmask, tm, fsec, &is2digits) != 0)
-                                               return -1;
+                                       else
+                                       {
+                                               dterr = DecodeNumber(flen, field[i],
+                                                                                        (fmask | DTK_DATE_M),
+                                                                                        &tmask, tm,
+                                                                                        fsec, &is2digits);
+                                               if (dterr)
+                                                       return dterr;
+                                       }
                                }
                                break;
 
@@ -2027,7 +2095,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                                                ereport(ERROR,
                                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                                                  errmsg("\"current\" is no longer supported")));
-                                                               return -1;
+                                                               return DTERR_BAD_FORMAT;
                                                                break;
 
                                                        case DTK_NOW:
@@ -2046,7 +2114,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                                                break;
 
                                                        default:
-                                                               return -1;
+                                                               return DTERR_BAD_FORMAT;
                                                }
 
                                                break;
@@ -2060,7 +2128,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                                tmask |= DTK_M(DTZ);
                                                tm->tm_isdst = 1;
                                                if (tzp == NULL)
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
                                                *tzp += val * 60;
                                                break;
 
@@ -2073,7 +2141,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                                tmask |= DTK_M(TZ);
                                                tm->tm_isdst = 1;
                                                if (tzp == NULL)
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
                                                *tzp = val * 60;
                                                ftype[i] = DTK_TZ;
                                                break;
@@ -2081,7 +2149,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                        case TZ:
                                                tm->tm_isdst = 0;
                                                if (tzp == NULL)
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
                                                *tzp = val * 60;
                                                ftype[i] = DTK_TZ;
                                                break;
@@ -2111,27 +2179,27 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                                                        || ((ftype[i + 1] != DTK_NUMBER)
                                                                && (ftype[i + 1] != DTK_TIME)
                                                                && (ftype[i + 1] != DTK_DATE)))
-                                                       return -1;
+                                                       return DTERR_BAD_FORMAT;
 
                                                ptype = val;
                                                break;
 
                                        default:
-                                               return -1;
+                                               return DTERR_BAD_FORMAT;
                                }
                                break;
 
                        default:
-                               return -1;
+                               return DTERR_BAD_FORMAT;
                }
 
                if (tmask & fmask)
-                       return -1;
+                       return DTERR_BAD_FORMAT;
                fmask |= tmask;
        }
 
        if ((mer != HR24) && (tm->tm_hour > 12))
-               return -1;
+               return DTERR_FIELD_OVERFLOW;
        if ((mer == AM) && (tm->tm_hour == 12))
                tm->tm_hour = 0;
        else if ((mer == PM) && (tm->tm_hour != 12))
@@ -2142,17 +2210,17 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                || (tm->tm_min < 0) || (tm->tm_min > 59)
                || (tm->tm_sec < 0) || (tm->tm_sec > 60)
                || (*fsec < INT64CONST(0)) || (*fsec >= INT64CONST(1000000)))
-               return -1;
+               return DTERR_FIELD_OVERFLOW;
 #else
        if ((tm->tm_hour < 0) || (tm->tm_hour > 23)
                || (tm->tm_min < 0) || (tm->tm_min > 59)
                || (tm->tm_sec < 0) || (tm->tm_sec > 60)
                || (*fsec < 0) || (*fsec >= 1))
-               return -1;
+               return DTERR_FIELD_OVERFLOW;
 #endif
 
        if ((fmask & DTK_TIME_M) != DTK_TIME_M)
-               return -1;
+               return DTERR_BAD_FORMAT;
 
        /* timezone not specified? then find local timezone if possible */
        if ((tzp != NULL) && (!(fmask & DTK_M(TZ))))
@@ -2165,7 +2233,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
                 * error
                 */
                if (fmask & DTK_M(DTZMOD))
-                       return -1;
+                       return DTERR_BAD_FORMAT;
 
                if ((fmask & DTK_DATE_M) == 0)
                        GetCurrentDateTime(tmp);
@@ -2183,20 +2251,22 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
        }
 
        return 0;
-}      /* DecodeTimeOnly() */
+}
 
 /* DecodeDate()
  * Decode date string which includes delimiters.
+ * Return 0 if okay, a DTERR code if not.
+ *
  * Insist on a complete set of fields.
  */
 static int
 DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
 {
        fsec_t          fsec;
-
        int                     nf = 0;
        int                     i,
                                len;
+       int                     dterr;
        int                     bc = FALSE;
        int                     is2digits = FALSE;
        int                     type,
@@ -2232,7 +2302,7 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
 #if 0
        /* don't allow too many fields */
        if (nf > 3)
-               return -1;
+               return DTERR_BAD_FORMAT;
 #endif
 
        *tmask = 0;
@@ -2258,10 +2328,10 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
                                        break;
 
                                default:
-                                       return -1;
+                                       return DTERR_BAD_FORMAT;
                        }
                        if (fmask & dmask)
-                               return -1;
+                               return DTERR_BAD_FORMAT;
 
                        fmask |= dmask;
                        *tmask |= dmask;
@@ -2278,20 +2348,23 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
                        continue;
 
                if ((len = strlen(field[i])) <= 0)
-                       return -1;
+                       return DTERR_BAD_FORMAT;
 
-               if (DecodeNumber(len, field[i], fmask, &dmask, tm, &fsec, &is2digits) != 0)
-                       return -1;
+               dterr = DecodeNumber(len, field[i], fmask,
+                                                        &dmask, tm,
+                                                        &fsec, &is2digits);
+               if (dterr)
+                       return dterr;
 
                if (fmask & dmask)
-                       return -1;
+                       return DTERR_BAD_FORMAT;
 
                fmask |= dmask;
                *tmask |= dmask;
        }
 
        if ((fmask & ~(DTK_M(DOY) | DTK_M(TZ))) != DTK_DATE_M)
-               return -1;
+               return DTERR_BAD_FORMAT;
 
        /* there is no year zero in AD/BC notation; i.e. "1 BC" == year 0 */
        if (bc)
@@ -2321,19 +2394,24 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
 
        /* check for valid month */
        if (tm->tm_mon < 1 || tm->tm_mon > 12)
-               return -1;
+               return DTERR_MD_FIELD_OVERFLOW;
 
        /* check for valid day */
-       if (tm->tm_mday < 1 ||
-               tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
-               return -1;
+       if (tm->tm_mday < 1 || tm->tm_mday > 31)
+               return DTERR_MD_FIELD_OVERFLOW;
+
+       /* We don't want to hint about DateStyle for Feb 29 */
+       if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
+               return DTERR_FIELD_OVERFLOW;
 
        return 0;
-}      /* DecodeDate() */
+}
 
 
 /* DecodeTime()
  * Decode time string which includes delimiters.
+ * Return 0 if okay, a DTERR code if not.
+ *
  * Only check the lower limit on hours, since this same code
  *     can be used to represent time spans.
  */
@@ -2346,7 +2424,7 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
 
        tm->tm_hour = strtol(str, &cp, 10);
        if (*cp != ':')
-               return -1;
+               return DTERR_BAD_FORMAT;
        str = cp + 1;
        tm->tm_min = strtol(str, &cp, 10);
        if (*cp == '\0')
@@ -2355,7 +2433,7 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
                *fsec = 0;
        }
        else if (*cp != ':')
-               return -1;
+               return DTERR_BAD_FORMAT;
        else
        {
                str = cp + 1;
@@ -2369,7 +2447,7 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
                        str = cp;
                        frac = strtod(str, &cp);
                        if (*cp != '\0')
-                               return -1;
+                               return DTERR_BAD_FORMAT;
 #ifdef HAVE_INT64_TIMESTAMP
                        *fsec = rint(frac * 1000000);
 #else
@@ -2377,7 +2455,7 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
 #endif
                }
                else
-                       return -1;
+                       return DTERR_BAD_FORMAT;
        }
 
        /* do a sanity check */
@@ -2386,21 +2464,22 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
                || (tm->tm_min < 0) || (tm->tm_min > 59)
                || (tm->tm_sec < 0) || (tm->tm_sec > 60)
                || (*fsec < INT64CONST(0)) || (*fsec >= INT64CONST(1000000)))
-               return -1;
+               return DTERR_FIELD_OVERFLOW;
 #else
        if ((tm->tm_hour < 0)
                || (tm->tm_min < 0) || (tm->tm_min > 59)
                || (tm->tm_sec < 0) || (tm->tm_sec > 60)
                || (*fsec < 0) || (*fsec >= 1))
-               return -1;
+               return DTERR_FIELD_OVERFLOW;
 #endif
 
        return 0;
-}      /* DecodeTime() */
+}
 
 
 /* DecodeNumber()
  * Interpret plain numeric field as a date value in context.
+ * Return 0 if okay, a DTERR code if not.
  */
 static int
 DecodeNumber(int flen, char *str, int fmask,
@@ -2408,12 +2487,13 @@ DecodeNumber(int flen, char *str, int fmask,
 {
        int                     val;
        char       *cp;
+       int                     dterr;
 
        *tmask = 0;
 
        val = strtol(str, &cp, 10);
        if (cp == str)
-               return -1;
+               return DTERR_BAD_FORMAT;
 
        if (*cp == '.')
        {
@@ -2425,15 +2505,18 @@ DecodeNumber(int flen, char *str, int fmask,
                 */
                if ((cp - str) > 2)
                {
-                       if (DecodeNumberField(flen, str, (fmask | DTK_DATE_M),
-                                                                 tmask, tm, fsec, is2digits) < 0)
-                               return -1;
+                       dterr = DecodeNumberField(flen, str,
+                                                                         (fmask | DTK_DATE_M),
+                                                                         tmask, tm,
+                                                                         fsec, is2digits);
+                       if (dterr < 0)
+                               return dterr;
                        return 0;
                }
 
                frac = strtod(cp, &cp);
                if (*cp != '\0')
-                       return -1;
+                       return DTERR_BAD_FORMAT;
 #ifdef HAVE_INT64_TIMESTAMP
                *fsec = rint(frac * 1000000);
 #else
@@ -2441,7 +2524,7 @@ DecodeNumber(int flen, char *str, int fmask,
 #endif
        }
        else if (*cp != '\0')
-               return -1;
+               return DTERR_BAD_FORMAT;
 
        /* Special case for day of year */
        if ((flen == 3) &&
@@ -2515,14 +2598,16 @@ DecodeNumber(int flen, char *str, int fmask,
 
                case (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY)):
                        /* we have all the date, so it must be a time field */
-                       if (DecodeNumberField(flen, str, fmask,
-                                                                 tmask, tm, fsec, is2digits) < 0)
-                               return -1;
+                       dterr = DecodeNumberField(flen, str, fmask,
+                                                                         tmask, tm,
+                                                                         fsec, is2digits);
+                       if (dterr < 0)
+                               return dterr;
                        return 0;
 
                default:
                        /* Anything else is bogus input */
-                       return -1;
+                       return DTERR_BAD_FORMAT;
        }
 
        /*
@@ -2538,12 +2623,14 @@ DecodeNumber(int flen, char *str, int fmask,
 
 /* DecodeNumberField()
  * Interpret numeric string as a concatenated date or time field.
+ * Return a DTK token (>= 0) if successful, a DTERR code (< 0) if not.
+ *
  * Use the context of previously decoded fields to help with
  * the interpretation.
  */
 static int
 DecodeNumberField(int len, char *str, int fmask,
-                               int *tmask, struct tm * tm, fsec_t *fsec, int *is2digits)
+                                 int *tmask, struct tm * tm, fsec_t *fsec, int *is2digits)
 {
        char       *cp;
 
@@ -2623,14 +2710,14 @@ DecodeNumberField(int len, char *str, int fmask,
                }
        }
 
-       return -1;
-}      /* DecodeNumberField() */
+       return DTERR_BAD_FORMAT;
+}
 
 
 /* DecodeTimezone()
  * Interpret string as a numeric timezone.
  *
- * Return 0 if okay (and set *tzp), nonzero if not okay.
+ * Return 0 if okay (and set *tzp), a DTERR code if not okay.
  *
  * NB: this must *not* ereport on failure; see commands/variable.c.
  *
@@ -2644,11 +2731,10 @@ DecodeTimezone(char *str, int *tzp)
        int                     hr,
                                min;
        char       *cp;
-       int                     len;
 
        /* leading character must be "+" or "-" */
        if (*str != '+' && *str != '-')
-               return -1;
+               return DTERR_BAD_FORMAT;
 
        hr = strtol((str + 1), &cp, 10);
 
@@ -2656,28 +2742,30 @@ DecodeTimezone(char *str, int *tzp)
        if (*cp == ':')
                min = strtol((cp + 1), &cp, 10);
        /* otherwise, might have run things together... */
-       else if ((*cp == '\0') && ((len = strlen(str)) > 3))
+       else if ((*cp == '\0') && (strlen(str) > 3))
        {
-               min = strtol((str + len - 2), &cp, 10);
-               if ((min < 0) || (min >= 60))
-                       return -1;
-
-               *(str + len - 2) = '\0';
-               hr = strtol((str + 1), &cp, 10);
-               if ((hr < 0) || (hr > 13))
-                       return -1;
+               min = hr % 100;
+               hr = hr / 100;
        }
        else
                min = 0;
 
-       tz = (hr * 60 + min) * 60;
+       if ((hr < 0) || (hr > 13))
+               return DTERR_TZDISP_OVERFLOW;
+       if ((min < 0) || (min >= 60))
+               return DTERR_TZDISP_OVERFLOW;
 
+       tz = (hr * 60 + min) * 60;
        if (*str == '-')
                tz = -tz;
 
        *tzp = -tz;
-       return *cp != '\0';
-}      /* DecodeTimezone() */
+
+       if (*cp != '\0')
+               return DTERR_BAD_FORMAT;
+
+       return 0;
+}
 
 
 /* DecodePosixTimezone()
@@ -2687,7 +2775,7 @@ DecodeTimezone(char *str, int *tzp)
  *     PST
  * - thomas 2000-03-15
  *
- * Return 0 if okay (and set *tzp), nonzero if not okay.
+ * Return 0 if okay (and set *tzp), a DTERR code if not okay.
  *
  * NB: this must *not* ereport on failure; see commands/variable.c.
  */
@@ -2697,6 +2785,7 @@ DecodePosixTimezone(char *str, int *tzp)
        int                     val,
                                tz;
        int                     type;
+       int                     dterr;
        char       *cp;
        char            delim;
 
@@ -2708,8 +2797,9 @@ DecodePosixTimezone(char *str, int *tzp)
        /* decode offset, if present */
        if (*cp)
        {
-               if (DecodeTimezone(cp, &tz) != 0)
-                       return -1;
+               dterr = DecodeTimezone(cp, &tz);
+               if (dterr)
+                       return dterr;
        }
        else
                tz = 0;
@@ -2728,11 +2818,11 @@ DecodePosixTimezone(char *str, int *tzp)
                        break;
 
                default:
-                       return -1;
+                       return DTERR_BAD_FORMAT;
        }
 
        return 0;
-}      /* DecodePosixTimezone() */
+}
 
 
 /* DecodeSpecial()
@@ -2786,12 +2876,12 @@ DecodeSpecial(int field, char *lowtoken, int *val)
        }
 
        return type;
-}      /* DecodeSpecial() */
+}
 
 
 /* DecodeInterval()
  * Interpret previously parsed fields for general time interval.
- * Return 0 if decoded and -1 if problems.
+ * Returns 0 if successful, DTERR code if bogus input detected.
  *
  * Allow "date" field DTK_DATE since this could be just
  *     an unsigned floating point number. - thomas 1997-11-16
@@ -2803,12 +2893,12 @@ int
 DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fsec_t *fsec)
 {
        int                     is_before = FALSE;
-
        char       *cp;
        int                     fmask = 0,
                                tmask,
                                type;
        int                     i;
+       int                     dterr;
        int                     val;
        double          fval;
 
@@ -2829,8 +2919,9 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse
                switch (ftype[i])
                {
                        case DTK_TIME:
-                               if (DecodeTime(field[i], fmask, &tmask, tm, fsec) != 0)
-                                       return -1;
+                               dterr = DecodeTime(field[i], fmask, &tmask, tm, fsec);
+                               if (dterr)
+                                       return dterr;
                                type = DTK_DAY;
                                break;
 
@@ -2850,8 +2941,8 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse
                                cp = field[i] + 1;
                                while ((*cp != '\0') && (*cp != ':') && (*cp != '.'))
                                        cp++;
-                               if ((*cp == ':')
-                                       && (DecodeTime((field[i] + 1), fmask, &tmask, tm, fsec) == 0))
+                               if ((*cp == ':') &&
+                                       (DecodeTime(field[i] + 1, fmask, &tmask, tm, fsec) == 0))
                                {
                                        if (*field[i] == '-')
                                        {
@@ -2903,7 +2994,7 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse
                                {
                                        fval = strtod(cp, &cp);
                                        if (*cp != '\0')
-                                               return -1;
+                                               return DTERR_BAD_FORMAT;
 
                                        if (val < 0)
                                                fval = -(fval);
@@ -2911,7 +3002,7 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse
                                else if (*cp == '\0')
                                        fval = 0;
                                else
-                                       return -1;
+                                       return DTERR_BAD_FORMAT;
 
                                tmask = 0;              /* DTK_M(type); */
 
@@ -3062,7 +3153,7 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse
                                                break;
 
                                        default:
-                                               return -1;
+                                               return DTERR_BAD_FORMAT;
                                }
                                break;
 
@@ -3090,16 +3181,16 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse
                                                break;
 
                                        default:
-                                               return -1;
+                                               return DTERR_BAD_FORMAT;
                                }
                                break;
 
                        default:
-                               return -1;
+                               return DTERR_BAD_FORMAT;
                }
 
                if (tmask & fmask)
-                       return -1;
+                       return DTERR_BAD_FORMAT;
                fmask |= tmask;
        }
 
@@ -3128,8 +3219,11 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse
        }
 
        /* ensure that at least one time field has been found */
-       return (fmask != 0) ? 0 : -1;
-}      /* DecodeInterval() */
+       if (fmask == 0)
+               return DTERR_BAD_FORMAT;
+
+       return 0;
+}
 
 
 /* DecodeUnits()
@@ -3165,6 +3259,57 @@ DecodeUnits(int field, char *lowtoken, int *val)
        return type;
 }      /* DecodeUnits() */
 
+/*
+ * Report an error detected by one of the datetime input processing routines.
+ *
+ * dterr is the error code, str is the original input string, datatype is
+ * the name of the datatype we were trying to accept.
+ *
+ * Note: it might seem useless to distinguish DTERR_INTERVAL_OVERFLOW and
+ * DTERR_TZDISP_OVERFLOW from DTERR_FIELD_OVERFLOW, but SQL99 mandates three
+ * separate SQLSTATE codes, so ...
+ */
+void
+DateTimeParseError(int dterr, const char *str, const char *datatype)
+{
+       switch (dterr)
+       {
+               case DTERR_FIELD_OVERFLOW:
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
+                                        errmsg("date/time field value out of range: \"%s\"",
+                                                       str)));
+                       break;
+               case DTERR_MD_FIELD_OVERFLOW:
+                       /* <nanny>same as above, but add hint about DateStyle</nanny> */
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
+                                        errmsg("date/time field value out of range: \"%s\"",
+                                                       str),
+                                        errhint("Perhaps you need a different DateStyle setting.")));
+                       break;
+               case DTERR_INTERVAL_OVERFLOW:
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_INTERVAL_FIELD_OVERFLOW),
+                                        errmsg("interval field value out of range: \"%s\"",
+                                                       str)));
+                       break;
+               case DTERR_TZDISP_OVERFLOW:
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE),
+                                        errmsg("time zone displacement out of range: \"%s\"",
+                                                       str)));
+                       break;
+               case DTERR_BAD_FORMAT:
+               default:
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
+                                        /* translator: first %s is datatype name */
+                                        errmsg("invalid input syntax for %s: \"%s\"",
+                                                       datatype, str)));
+                       break;
+       }
+}
 
 /* datebsearch()
  * Binary search -- from Knuth (6.2.1) Algorithm B.  Special case like this
index f694349db7abe9db81b493deb55cff32b592bf71..8b758b51195e93cc3ac79f72bb21a0c77b5317a6 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.114 2003/08/17 19:58:05 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.115 2003/08/27 23:29:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -364,6 +364,7 @@ abstimein(PG_FUNCTION_ARGS)
        int                     tz = 0;
        struct tm       date,
                           *tm = &date;
+       int                     dterr;
        char       *field[MAXDATEFIELDS];
        char            lowstr[MAXDATELEN + 1];
        int                     dtype;
@@ -371,15 +372,13 @@ abstimein(PG_FUNCTION_ARGS)
                                ftype[MAXDATEFIELDS];
 
        if (strlen(str) >= sizeof(lowstr))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                          errmsg("invalid input syntax for abstime: \"%s\"", str)));
-
-       if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
-         || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                          errmsg("invalid input syntax for abstime: \"%s\"", str)));
+               dterr = DTERR_BAD_FORMAT;
+       else
+               dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
+       if (dterr == 0)
+               dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz);
+       if (dterr != 0)
+               DateTimeParseError(dterr, str, "abstime");
 
        switch (dtype)
        {
@@ -768,21 +767,24 @@ reltimein(PG_FUNCTION_ARGS)
                           *tm = &tt;
        fsec_t          fsec;
        int                     dtype;
+       int                     dterr;
        char       *field[MAXDATEFIELDS];
        int                     nf,
                                ftype[MAXDATEFIELDS];
        char            lowstr[MAXDATELEN + 1];
 
        if (strlen(str) >= sizeof(lowstr))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                          errmsg("invalid input syntax for reltime: \"%s\"", str)));
-
-       if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
-               || (DecodeInterval(field, ftype, nf, &dtype, tm, &fsec) != 0))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                          errmsg("invalid input syntax for reltime: \"%s\"", str)));
+               dterr = DTERR_BAD_FORMAT;
+       else
+               dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
+       if (dterr == 0)
+               dterr = DecodeInterval(field, ftype, nf, &dtype, tm, &fsec);
+       if (dterr != 0)
+       {
+               if (dterr == DTERR_FIELD_OVERFLOW)
+                       dterr = DTERR_INTERVAL_OVERFLOW;
+               DateTimeParseError(dterr, str, "reltime");
+       }
 
        switch (dtype)
        {
index ef998454ff9923f472c3123438853716379ba19d..961c70da81a205585dfc079cc4ff7c41bda9e1d2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.93 2003/08/26 21:31:11 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.94 2003/08/27 23:29:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -77,22 +77,19 @@ timestamp_in(PG_FUNCTION_ARGS)
        int                     tz;
        int                     dtype;
        int                     nf;
+       int                     dterr;
        char       *field[MAXDATEFIELDS];
        int                     ftype[MAXDATEFIELDS];
        char            lowstr[MAXDATELEN + MAXDATEFIELDS];
 
        if (strlen(str) >= sizeof(lowstr))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                                errmsg("invalid input syntax for timestamp: \"%s\"",
-                                               str)));
-
-       if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
-         || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                                errmsg("invalid input syntax for timestamp: \"%s\"",
-                                               str)));
+               dterr = DTERR_BAD_FORMAT;
+       else
+               dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
+       if (dterr == 0)
+               dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz);
+       if (dterr != 0)
+               DateTimeParseError(dterr, str, "timestamp");
 
        switch (dtype)
        {
@@ -306,22 +303,19 @@ timestamptz_in(PG_FUNCTION_ARGS)
        int                     tz;
        int                     dtype;
        int                     nf;
+       int                     dterr;
        char       *field[MAXDATEFIELDS];
        int                     ftype[MAXDATEFIELDS];
        char            lowstr[MAXDATELEN + MAXDATEFIELDS];
 
        if (strlen(str) >= sizeof(lowstr))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                                errmsg("invalid input syntax for timestamp with time zone: \"%s\"",
-                                               str)));
-
-       if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
-         || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                                errmsg("invalid input syntax for timestamp with time zone: \"%s\"",
-                                               str)));
+               dterr = DTERR_BAD_FORMAT;
+       else
+               dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
+       if (dterr == 0)
+               dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz);
+       if (dterr != 0)
+               DateTimeParseError(dterr, str, "timestamp with time zone");
 
        switch (dtype)
        {
@@ -468,6 +462,7 @@ interval_in(PG_FUNCTION_ARGS)
                           *tm = &tt;
        int                     dtype;
        int                     nf;
+       int                     dterr;
        char       *field[MAXDATEFIELDS];
        int                     ftype[MAXDATEFIELDS];
        char            lowstr[MAXDATELEN + MAXDATEFIELDS];
@@ -481,17 +476,17 @@ interval_in(PG_FUNCTION_ARGS)
        fsec = 0;
 
        if (strlen(str) >= sizeof(lowstr))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                                errmsg("invalid input syntax for interval: \"%s\"",
-                                               str)));
-
-       if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
-               || (DecodeInterval(field, ftype, nf, &dtype, tm, &fsec) != 0))
-               ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
-                                errmsg("invalid input syntax for interval: \"%s\"",
-                                               str)));
+               dterr = DTERR_BAD_FORMAT;
+       else
+               dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
+       if (dterr == 0)
+               dterr = DecodeInterval(field, ftype, nf, &dtype, tm, &fsec);
+       if (dterr != 0)
+       {
+               if (dterr == DTERR_FIELD_OVERFLOW)
+                       dterr = DTERR_INTERVAL_OVERFLOW;
+               DateTimeParseError(dterr, str, "interval");
+       }
 
        result = (Interval *) palloc(sizeof(Interval));
 
index d5facdd8e00f11e97dce8e6bb8c852e8085b7182..cda63ebe6de0322269c42d8eb557c068cad0616b 100644 (file)
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: datetime.h,v 1.44 2003/08/05 18:30:21 tgl Exp $
+ * $Id: datetime.h,v 1.45 2003/08/27 23:29:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -204,7 +204,7 @@ typedef struct
  */
 #define FMODULO(t,q,u) \
 do { \
-       q = ((t < 0) ? ceil(t / u): floor(t / u)); \
+       q = ((t < 0) ? ceil(t / u) : floor(t / u)); \
        if (q != 0) t -= rint(q * u); \
 } while(0)
 
@@ -222,7 +222,7 @@ do { \
 #else
 #define TMODULO(t,q,u) \
 do { \
-       q = ((t < 0) ? ceil(t / u): floor(t / u)); \
+       q = ((t < 0) ? ceil(t / u) : floor(t / u)); \
        if (q != 0) t -= rint(q * u); \
 } while(0)
 #endif
@@ -253,6 +253,15 @@ extern int day_tab[2][13];
   || (((m) == JULIAN_MINMONTH) && ((d) >= JULIAN_MINDAY))))) \
  && ((y) < JULIAN_MAXYEAR))
 
+/* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */
+#define UNIX_EPOCH_JDATE               2440588 /* == date2j(1970, 1, 1) */
+#define POSTGRES_EPOCH_JDATE   2451545 /* == date2j(2000, 1, 1) */
+
+/*
+ * Info about limits of the Unix time_t data type.  We assume that time_t
+ * is a signed int32 with origin 1970-01-01.  Note this is only relevant
+ * when we use the C library's time routines for timezone processing.
+ */
 #define UTIME_MINYEAR (1901)
 #define UTIME_MINMONTH (12)
 #define UTIME_MINDAY (14)
@@ -267,9 +276,17 @@ extern int day_tab[2][13];
  || (((y) == UTIME_MAXYEAR) && (((m) < UTIME_MAXMONTH) \
   || (((m) == UTIME_MAXMONTH) && ((d) <= UTIME_MAXDAY))))))
 
-/* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */
-#define UNIX_EPOCH_JDATE               2440588 /* == date2j(1970, 1, 1) */
-#define POSTGRES_EPOCH_JDATE   2451545 /* == date2j(2000, 1, 1) */
+/*
+ * Datetime input parsing routines (ParseDateTime, DecodeDateTime, etc)
+ * return zero or a positive value on success.  On failure, they return
+ * one of these negative code values.  DateTimeParseError may be used to
+ * produce a correct ereport.
+ */
+#define DTERR_BAD_FORMAT               (-1)
+#define DTERR_FIELD_OVERFLOW   (-2)
+#define DTERR_MD_FIELD_OVERFLOW        (-3)    /* triggers hint about DateStyle */
+#define DTERR_INTERVAL_OVERFLOW        (-4)
+#define DTERR_TZDISP_OVERFLOW  (-5)
 
 
 extern void GetCurrentDateTime(struct tm * tm);
@@ -283,14 +300,14 @@ extern int ParseDateTime(const char *timestr, char *lowstr,
 extern int DecodeDateTime(char **field, int *ftype,
                           int nf, int *dtype,
                           struct tm * tm, fsec_t *fsec, int *tzp);
-
 extern int DecodeTimeOnly(char **field, int *ftype,
                           int nf, int *dtype,
                           struct tm * tm, fsec_t *fsec, int *tzp);
-
 extern int DecodeInterval(char **field, int *ftype,
                           int nf, int *dtype,
                           struct tm * tm, fsec_t *fsec);
+extern void DateTimeParseError(int dterr, const char *str,
+                                                          const char *datatype);
 
 extern int     DetermineLocalTimeZone(struct tm * tm);
 
index ecfdb9f0548af984817cf904857f902700013200..41a0861e3a183218ec0a186e917662093f6c9dba 100644 (file)
@@ -28,9 +28,10 @@ INSERT INTO ABSTIME_TBL (f1) VALUES (abstime '-infinity');
 INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'May 10, 1947 23:59:12');
 -- what happens if we specify slightly misformatted abstime? 
 INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 35, 1946 10:00:00');
-ERROR:  invalid input syntax for abstime: "Feb 35, 1946 10:00:00"
+ERROR:  date/time field value out of range: "Feb 35, 1946 10:00:00"
+HINT:  Perhaps you need a different DateStyle setting.
 INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 28, 1984 25:08:10');
-ERROR:  invalid input syntax for abstime: "Feb 28, 1984 25:08:10"
+ERROR:  date/time field value out of range: "Feb 28, 1984 25:08:10"
 -- badly formatted abstimes:  these should result in invalid abstimes 
 INSERT INTO ABSTIME_TBL (f1) VALUES ('bad date format');
 ERROR:  invalid input syntax for abstime: "bad date format"
index abece85133ddf11c5c4b2c054511368b46f24355..b73004693900c024d1e8240d808c0ae2a9828ede 100644 (file)
@@ -28,9 +28,10 @@ INSERT INTO ABSTIME_TBL (f1) VALUES (abstime '-infinity');
 INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'May 10, 1947 23:59:12');
 -- what happens if we specify slightly misformatted abstime? 
 INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 35, 1946 10:00:00');
-ERROR:  invalid input syntax for abstime: "Feb 35, 1946 10:00:00"
+ERROR:  date/time field value out of range: "Feb 35, 1946 10:00:00"
+HINT:  Perhaps you need a different DateStyle setting.
 INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 28, 1984 25:08:10');
-ERROR:  invalid input syntax for abstime: "Feb 28, 1984 25:08:10"
+ERROR:  date/time field value out of range: "Feb 28, 1984 25:08:10"
 -- badly formatted abstimes:  these should result in invalid abstimes 
 INSERT INTO ABSTIME_TBL (f1) VALUES ('bad date format');
 ERROR:  invalid input syntax for abstime: "bad date format"
index ce1f76785d4b220cb325cc426bcf91c34962b678..84bdcf232b90a6e68ca4bf8317648d8c2c1929bd 100644 (file)
@@ -10,7 +10,7 @@ INSERT INTO DATE_TBL VALUES ('1996-03-01');
 INSERT INTO DATE_TBL VALUES ('1996-03-02');
 INSERT INTO DATE_TBL VALUES ('1997-02-28');
 INSERT INTO DATE_TBL VALUES ('1997-02-29');
-ERROR:  invalid input syntax for date: "1997-02-29"
+ERROR:  date/time field value out of range: "1997-02-29"
 INSERT INTO DATE_TBL VALUES ('1997-03-01');
 INSERT INTO DATE_TBL VALUES ('1997-03-02');
 INSERT INTO DATE_TBL VALUES ('2000-04-01');
index 0aa1da407f461aa5fc1ef684cd96eac94c99ac16..379e17e0a0f99d92091e9ad6740e0e234411cbcf 100644 (file)
@@ -81,7 +81,8 @@ SELECT timestamp with time zone '12/27/2001 04:05:06.789-08';
 
 -- should fail in mdy mode:
 SELECT timestamp with time zone '27/12/2001 04:05:06.789-08';
-ERROR:  invalid input syntax for timestamp with time zone: "27/12/2001 04:05:06.789-08"
+ERROR:  date/time field value out of range: "27/12/2001 04:05:06.789-08"
+HINT:  Perhaps you need a different DateStyle setting.
 set datestyle to dmy;
 SELECT timestamp with time zone '27/12/2001 04:05:06.789-08';
            timestamptz            
index cdb9c7f1d867b29aac0d1cc3ac13d9db78b04fb0..c5c70779a1312bc112ba810d9b919fac08339f9c 100644 (file)
@@ -81,7 +81,8 @@ SELECT timestamp with time zone '12/27/2001 04:05:06.789-08';
 
 -- should fail in mdy mode:
 SELECT timestamp with time zone '27/12/2001 04:05:06.789-08';
-ERROR:  invalid input syntax for timestamp with time zone: "27/12/2001 04:05:06.789-08"
+ERROR:  date/time field value out of range: "27/12/2001 04:05:06.789-08"
+HINT:  Perhaps you need a different DateStyle setting.
 set datestyle to dmy;
 SELECT timestamp with time zone '27/12/2001 04:05:06.789-08';
            timestamptz            
index 984e75e8b4c6a97df9a4b1e1a1cc839748b3072b..940707e90fcf05c4a3dad692583e110501921043 100644 (file)
@@ -81,7 +81,8 @@ SELECT timestamp with time zone '12/27/2001 04:05:06.789-08';
 
 -- should fail in mdy mode:
 SELECT timestamp with time zone '27/12/2001 04:05:06.789-08';
-ERROR:  invalid input syntax for timestamp with time zone: "27/12/2001 04:05:06.789-08"
+ERROR:  date/time field value out of range: "27/12/2001 04:05:06.789-08"
+HINT:  Perhaps you need a different DateStyle setting.
 set datestyle to dmy;
 SELECT timestamp with time zone '27/12/2001 04:05:06.789-08';
            timestamptz            
index 0b45bb9c1a71f3c5544b6426e8b8b70251298b6b..2ea2371c6880f4094f9d8540fa3b64fa4b5cf356 100644 (file)
@@ -128,7 +128,7 @@ INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1996');
 INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 1997');
 INSERT INTO TIMESTAMP_TBL VALUES ('Feb 28 17:32:01 1997');
 INSERT INTO TIMESTAMP_TBL VALUES ('Feb 29 17:32:01 1997');
-ERROR:  invalid input syntax for timestamp: "Feb 29 17:32:01 1997"
+ERROR:  date/time field value out of range: "Feb 29 17:32:01 1997"
 INSERT INTO TIMESTAMP_TBL VALUES ('Mar 01 17:32:01 1997');
 INSERT INTO TIMESTAMP_TBL VALUES ('Dec 30 17:32:01 1997');
 INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1997');
@@ -138,7 +138,7 @@ INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 2000');
 INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 2001');
 -- Currently unsupported syntax and ranges
 INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 -0097');
-ERROR:  invalid input syntax for timestamp: "Feb 16 17:32:01 -0097"
+ERROR:  time zone displacement out of range: "Feb 16 17:32:01 -0097"
 INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 5097 BC');
 ERROR:  timestamp out of range: "Feb 16 17:32:01 5097 BC"
 SELECT '' AS "64", d1 FROM TIMESTAMP_TBL; 
index 49525518c7be580c29a29b5cf7df300e4655275b..9214ae76e88fe5956d3c75849139c3c5a4e86055 100644 (file)
@@ -123,7 +123,7 @@ INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1996');
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 1997');
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 28 17:32:01 1997');
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 29 17:32:01 1997');
-ERROR:  invalid input syntax for timestamp with time zone: "Feb 29 17:32:01 1997"
+ERROR:  date/time field value out of range: "Feb 29 17:32:01 1997"
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mar 01 17:32:01 1997');
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 30 17:32:01 1997');
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1997');
@@ -133,7 +133,7 @@ INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 2000');
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 2001');
 -- Currently unsupported syntax and ranges
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 -0097');
-ERROR:  invalid input syntax for timestamp with time zone: "Feb 16 17:32:01 -0097"
+ERROR:  time zone displacement out of range: "Feb 16 17:32:01 -0097"
 INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 5097 BC');
 ERROR:  timestamp out of range: "Feb 16 17:32:01 5097 BC"
 SELECT '' AS "64", d1 FROM TIMESTAMPTZ_TBL;