Commit 258ee1b6 authored by Greg Stark's avatar Greg Stark

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
parent 9270d8db
...@@ -103,8 +103,8 @@ static const datetkn datetktbl[] = { ...@@ -103,8 +103,8 @@ static const datetkn datetktbl[] = {
{"d", UNITS, DTK_DAY}, /* "day of month" for ISO input */ {"d", UNITS, DTK_DAY}, /* "day of month" for ISO input */
{"dec", MONTH, 12}, {"dec", MONTH, 12},
{"december", MONTH, 12}, {"december", MONTH, 12},
{"dow", RESERV, DTK_DOW}, /* day of week */ {"dow", UNITS, DTK_DOW}, /* day of week */
{"doy", RESERV, DTK_DOY}, /* day of year */ {"doy", UNITS, DTK_DOY}, /* day of year */
{"dst", DTZMOD, SECS_PER_HOUR}, {"dst", DTZMOD, SECS_PER_HOUR},
{EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */ {EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */
{"feb", MONTH, 2}, {"feb", MONTH, 2},
...@@ -114,7 +114,7 @@ static const datetkn datetktbl[] = { ...@@ -114,7 +114,7 @@ static const datetkn datetktbl[] = {
{"h", UNITS, DTK_HOUR}, /* "hour" */ {"h", UNITS, DTK_HOUR}, /* "hour" */
{LATE, RESERV, DTK_LATE}, /* "infinity" reserved for "late time" */ {LATE, RESERV, DTK_LATE}, /* "infinity" reserved for "late time" */
{INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for bad 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 */ {"isoyear", UNITS, DTK_ISOYEAR}, /* year in terms of the ISO week date */
{"j", UNITS, DTK_JULIAN}, {"j", UNITS, DTK_JULIAN},
{"jan", MONTH, 1}, {"jan", MONTH, 1},
......
...@@ -4458,6 +4458,26 @@ timestamp_part(PG_FUNCTION_ARGS) ...@@ -4458,6 +4458,26 @@ timestamp_part(PG_FUNCTION_ARGS)
result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday); result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
break; 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:
case DTK_TZ_MINUTE: case DTK_TZ_MINUTE:
case DTK_TZ_HOUR: case DTK_TZ_HOUR:
...@@ -4481,26 +4501,6 @@ timestamp_part(PG_FUNCTION_ARGS) ...@@ -4481,26 +4501,6 @@ timestamp_part(PG_FUNCTION_ARGS)
#endif #endif
break; 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: default:
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
...@@ -4672,6 +4672,26 @@ timestamptz_part(PG_FUNCTION_ARGS) ...@@ -4672,6 +4672,26 @@ timestamptz_part(PG_FUNCTION_ARGS)
result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday); result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
break; 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: default:
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
...@@ -4693,26 +4713,6 @@ timestamptz_part(PG_FUNCTION_ARGS) ...@@ -4693,26 +4713,6 @@ timestamptz_part(PG_FUNCTION_ARGS)
#endif #endif
break; 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: default:
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment