]> granicus.if.org Git - postgresql/commitdiff
Move DTK_ISODOW DTK_DOW and DTK_DOY to be type UNITS rather than
authorGreg Stark <stark@mit.edu>
Sun, 6 Sep 2015 03:02:57 +0000 (04:02 +0100)
committerGreg Stark <stark@mit.edu>
Sun, 6 Sep 2015 03:05:20 +0000 (04:05 +0100)
    RESERV. RESERV is meant for tokens like "now" and having them in that
    category throws errors like these when used as an input date:

    stark=# SELECT 'doy'::timestamptz;
    ERROR:  unexpected dtype 33 while parsing timestamptz "doy"
    LINE 1: SELECT 'doy'::timestamptz;
                   ^
    stark=# SELECT 'dow'::timestamptz;
    ERROR:  unexpected dtype 32 while parsing timestamptz "dow"
    LINE 1: SELECT 'dow'::timestamptz;
                   ^

    Found by LLVM's Libfuzzer

src/backend/utils/adt/datetime.c
src/backend/utils/adt/timestamp.c

index 73ec2006f685719d177eb3a727ba6b28b6735a9a..bb3442d1d719749a22758745df6315864ba8d07d 100644 (file)
@@ -104,8 +104,8 @@ static const datetkn datetktbl[] = {
        {"d", UNITS, DTK_DAY},          /* "day of month" for ISO input */
        {"dec", MONTH, 12},
        {"december", MONTH, 12},
-       {"dow", RESERV, DTK_DOW},       /* day of week */
-       {"doy", RESERV, DTK_DOY},       /* day of year */
+       {"dow", UNITS, DTK_DOW},        /* day of week */
+       {"doy", UNITS, DTK_DOY},        /* day of year */
        {"dst", DTZMOD, SECS_PER_HOUR},
        {EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */
        {"feb", MONTH, 2},
@@ -115,7 +115,7 @@ static const datetkn datetktbl[] = {
        {"h", UNITS, DTK_HOUR},         /* "hour" */
        {LATE, RESERV, DTK_LATE},       /* "infinity" reserved for "late time" */
        {INVALID, RESERV, DTK_INVALID},         /* "invalid" reserved for bad time */
-       {"isodow", RESERV, DTK_ISODOW},         /* ISO day of week, Sunday == 7 */
+       {"isodow", UNITS, DTK_ISODOW},          /* ISO day of week, Sunday == 7 */
        {"isoyear", UNITS, DTK_ISOYEAR},        /* year in terms of the ISO week date */
        {"j", UNITS, DTK_JULIAN},
        {"jan", MONTH, 1},
index cabd148e2bbb074bc4401e93ce4f865c0fbc0e16..14eaabff68f8d207a2138d91e2dc6799631234d9 100644 (file)
@@ -3953,6 +3953,26 @@ timestamp_part(PG_FUNCTION_ARGS)
                                result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
                                break;
 
+                       case DTK_DOW:
+                       case DTK_ISODOW:
+                               if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                                        errmsg("timestamp out of range")));
+                               result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
+                               if (val == DTK_ISODOW && result == 0)
+                                       result = 7;
+                               break;
+
+                       case DTK_DOY:
+                               if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                                        errmsg("timestamp out of range")));
+                               result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
+                                                 - date2j(tm->tm_year, 1, 1) + 1);
+                               break;
+
                        case DTK_TZ:
                        case DTK_TZ_MINUTE:
                        case DTK_TZ_HOUR:
@@ -3995,25 +4015,6 @@ timestamp_part(PG_FUNCTION_ARGS)
 #endif
                                        break;
                                }
-                       case DTK_DOW:
-                       case DTK_ISODOW:
-                               if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
-                                       ereport(ERROR,
-                                                       (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
-                                                        errmsg("timestamp out of range")));
-                               result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
-                               if (val == DTK_ISODOW && result == 0)
-                                       result = 7;
-                               break;
-
-                       case DTK_DOY:
-                               if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
-                                       ereport(ERROR,
-                                                       (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
-                                                        errmsg("timestamp out of range")));
-                               result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
-                                                 - date2j(tm->tm_year, 1, 1) + 1);
-                               break;
 
                        default:
                                ereport(ERROR,
@@ -4187,6 +4188,26 @@ timestamptz_part(PG_FUNCTION_ARGS)
                                result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
                                break;
 
+                       case DTK_DOW:
+                       case DTK_ISODOW:
+                               if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                                        errmsg("timestamp out of range")));
+                               result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
+                               if (val == DTK_ISODOW && result == 0)
+                                       result = 7;
+                               break;
+
+                       case DTK_DOY:
+                               if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                                        errmsg("timestamp out of range")));
+                               result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
+                                                 - date2j(tm->tm_year, 1, 1) + 1);
+                               break;
+
                        default:
                                ereport(ERROR,
                                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -4208,26 +4229,6 @@ timestamptz_part(PG_FUNCTION_ARGS)
 #endif
                                break;
 
-                       case DTK_DOW:
-                       case DTK_ISODOW:
-                               if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
-                                       ereport(ERROR,
-                                                       (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
-                                                        errmsg("timestamp out of range")));
-                               result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
-                               if (val == DTK_ISODOW && result == 0)
-                                       result = 7;
-                               break;
-
-                       case DTK_DOY:
-                               if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
-                                       ereport(ERROR,
-                                                       (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
-                                                        errmsg("timestamp out of range")));
-                               result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
-                                                 - date2j(tm->tm_year, 1, 1) + 1);
-                               break;
-
                        default:
                                ereport(ERROR,
                                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),