]> 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 01:04:37 +0000 (02:04 +0100)
committerGreg Stark <stark@mit.edu>
Sun, 6 Sep 2015 02:35:56 +0000 (03:35 +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 2a44b6e50375b353ab01676f7cb5407bef43171e..926358e6c981e63caf6d48ffd92735c245eb528e 100644 (file)
@@ -103,8 +103,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},
@@ -114,7 +114,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 23d3d2b65636ea72f79f237d614fe9f35e76acaf..0c39a1ac02b77aa49362362049dc12e51b39d378 100644 (file)
@@ -4458,6 +4458,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:
@@ -4481,26 +4501,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,
                                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -4672,6 +4672,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, 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, &tz, 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,
                                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -4693,26 +4713,6 @@ timestamptz_part(PG_FUNCTION_ARGS)
 #endif
                                break;
 
-                       case DTK_DOW:
-                       case DTK_ISODOW:
-                               if (timestamp2tm(timestamp, &tz, 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, &tz, 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,
                                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),