]> 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:58:32 +0000 (03:58 +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 97a1a7d768f2fe8a81957debaa4f168642799537..5ea40b5c90f6e90f5fe98b1efa7cd9005129a335 100644 (file)
@@ -105,8 +105,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},
@@ -116,7 +116,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 3f7974de8f8b79f3d78dbe2404f1e4469fa971d2..3f77656e24f968fc7baabc57925fb949076aba99 100644 (file)
@@ -4051,6 +4051,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:
@@ -4074,26 +4094,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),
@@ -4265,6 +4265,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),
@@ -4286,26 +4306,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),