aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGreg Stark <stark@mit.edu>2015-09-06 04:02:57 +0100
committerGreg Stark <stark@mit.edu>2015-09-06 04:02:57 +0100
commit07cef3eb8a621690ff5e1a1d576656284957caf1 (patch)
treebae62fd50a2ba2800cabf6ee218639f5ae900518 /src
parent20d309a8f4c3c033b1d1202b77d1115a9d5bfb2b (diff)
downloadpostgresql-07cef3eb8a621690ff5e1a1d576656284957caf1.tar.gz
postgresql-07cef3eb8a621690ff5e1a1d576656284957caf1.zip
Move DTK_ISODOW DTK_DOW and DTK_DOY to be type UNITS rather than
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
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/datetime.c6
-rw-r--r--src/backend/utils/adt/timestamp.c79
2 files changed, 43 insertions, 42 deletions
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 569aebd12b3..0ccc2312d1f 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -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},
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index f2d631e0e70..da15eda681a 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -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),