Reject out-of-range dates in date_in().
authorTom Lane <[email protected]>
Thu, 9 Feb 2006 03:40:42 +0000 (03:40 +0000)
committerTom Lane <[email protected]>
Thu, 9 Feb 2006 03:40:42 +0000 (03:40 +0000)
Kris Jurka

doc/src/sgml/datatype.sgml
src/backend/utils/adt/date.c

index 02859de7b06b706650a15c153d41199e89e4dfff..ff521835986fa2bfb292bff2e3071bf2df7dca01 100644 (file)
@@ -1358,7 +1358,7 @@ SELECT b, char_length(b) FROM test2;
         <entry>4 bytes</entry>
         <entry>dates only</entry>
         <entry>4713 BC</entry>
-        <entry>32767 AD</entry>
+        <entry>5874897 AD</entry>
         <entry>1 day</entry>
        </row>
        <row>
@@ -1645,7 +1645,7 @@ SELECT b, char_length(b) FROM test2;
          </row>
          <row>
           <entry><literal>04:05 PM</literal></entry>
-          <entry>same as 16:05; input hour must be <= 12</entry>
+          <entry>same as 16:05; input hour must be &lt;= 12</entry>
          </row>
          <row>
           <entry><literal>04:05:06.789-8</literal></entry>
@@ -2367,7 +2367,7 @@ SELECT * FROM test1 WHERE a;
         <entry><type>circle</type></entry>
         <entry>24 bytes</entry>
         <entry>Circle</entry>
-        <entry><(x,y),r> (center and radius)</entry>
+        <entry>&lt;(x,y),r&gt; (center and radius)</entry>
        </row>
       </tbody>
      </tgroup>
index e7d36eec6400ba4e1498e0496b5227a0f94380c9..6a94674cf422de3f24205c1c61af7909235eba33 100644 (file)
@@ -65,12 +65,10 @@ date_in(PG_FUNCTION_ARGS)
        int                     dterr;
        char       *field[MAXDATEFIELDS];
        int                     ftype[MAXDATEFIELDS];
-       char            lowstr[MAXDATELEN + 1];
+       char            workbuf[MAXDATELEN + 1];
 
-       if (strlen(str) >= sizeof(lowstr))
-               dterr = DTERR_BAD_FORMAT;
-       else
-               dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
+       dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
+                                                 field, ftype, MAXDATEFIELDS, &nf);
        if (dterr == 0)
                dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp);
        if (dterr != 0)
@@ -98,6 +96,11 @@ date_in(PG_FUNCTION_ARGS)
                        break;
        }
 
+       if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                errmsg("date out of range: \"%s\"", str)));
+
        date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
 
        PG_RETURN_DATEADT(date);
@@ -894,15 +897,13 @@ time_in(PG_FUNCTION_ARGS)
        int                     tz;
        int                     nf;
        int                     dterr;
-       char            lowstr[MAXDATELEN + 1];
+       char            workbuf[MAXDATELEN + 1];
        char       *field[MAXDATEFIELDS];
        int                     dtype;
        int                     ftype[MAXDATEFIELDS];
 
-       if (strlen(str) >= sizeof(lowstr))
-               dterr = DTERR_BAD_FORMAT;
-       else
-               dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
+       dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
+                                                 field, ftype, MAXDATEFIELDS, &nf);
        if (dterr == 0)
                dterr = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz);
        if (dterr != 0)
@@ -1734,15 +1735,13 @@ timetz_in(PG_FUNCTION_ARGS)
        int                     tz;
        int                     nf;
        int                     dterr;
-       char            lowstr[MAXDATELEN + 1];
+       char            workbuf[MAXDATELEN + 1];
        char       *field[MAXDATEFIELDS];
        int                     dtype;
        int                     ftype[MAXDATEFIELDS];
 
-       if (strlen(str) >= sizeof(lowstr))
-               dterr = DTERR_BAD_FORMAT;
-       else
-               dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf);
+       dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
+                                                 field, ftype, MAXDATEFIELDS, &nf);
        if (dterr == 0)
                dterr = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz);
        if (dterr != 0)
@@ -1869,12 +1868,20 @@ timetz_scale(PG_FUNCTION_ARGS)
 static int
 timetz_cmp_internal(TimeTzADT *time1, TimeTzADT *time2)
 {
+       /* Primary sort is by true (GMT-equivalent) time */
+#ifdef HAVE_INT64_TIMESTAMP
+       int64           t1,
+                               t2;
+
+       t1 = time1->time + (time1->zone * INT64CONST(1000000));
+       t2 = time2->time + (time2->zone * INT64CONST(1000000));
+#else
        double          t1,
                                t2;
 
-       /* Primary sort is by true (GMT-equivalent) time */
        t1 = time1->time + time1->zone;
        t2 = time2->time + time2->zone;
+#endif
 
        if (t1 > t2)
                return 1;
@@ -2443,9 +2450,9 @@ timetz_part(PG_FUNCTION_ARGS)
        else if ((type == RESERV) && (val == DTK_EPOCH))
        {
 #ifdef HAVE_INT64_TIMESTAMP
-               result = ((time->time / 1000000e0) - time->zone);
+               result = ((time->time / 1000000e0) + time->zone);
 #else
-               result = (time->time - time->zone);
+               result = (time->time + time->zone);
 #endif
        }
        else