diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2022-12-09 13:30:43 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2022-12-09 13:30:47 -0500 |
commit | 2661469d862239ea8b9e3a1cf5352d833f6f0fec (patch) | |
tree | ec0c5ac6086a3d1850af80a6e2104b8f0dace218 /src/include | |
parent | fc7852c6cb89a5384e0b4ad30874de92f63f88be (diff) | |
download | postgresql-2661469d862239ea8b9e3a1cf5352d833f6f0fec.tar.gz postgresql-2661469d862239ea8b9e3a1cf5352d833f6f0fec.zip |
Allow DateTimeParseError to handle bad-timezone error messages.
Pay down some ancient technical debt (dating to commit 022fd9966):
fix a couple of places in datetime parsing that were throwing
ereport's immediately instead of returning a DTERR code that could be
interpreted by DateTimeParseError. The reason for that was that there
was no mechanism for passing any auxiliary data (such as a zone name)
to DateTimeParseError, and these errors seemed to really need it.
Up to now it didn't matter that much just where the error got thrown,
but now we'd like to have a hard policy that datetime parse errors
get thrown from just the one place.
Hence, invent a "DateTimeErrorExtra" struct that can be used to
carry any extra values needed for specific DTERR codes. Perhaps
in the future somebody will be motivated to use this to improve
the specificity of other DateTimeParseError messages, but for now
just deal with the timezone-error cases.
This is on the way to making the datetime input functions report
parse errors softly; but it's really an independent change, so
commit separately.
Discussion: https://postgr.es/m/3bbbb0df-7382-bf87-9737-340ba096e034@postgrespro.ru
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/utils/datetime.h | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h index 934cb56a3a5..bb70b754491 100644 --- a/src/include/utils/datetime.h +++ b/src/include/utils/datetime.h @@ -276,13 +276,25 @@ extern PGDLLIMPORT const int day_tab[2][13]; * Datetime input parsing routines (ParseDateTime, DecodeDateTime, etc) * return zero or a positive value on success. On failure, they return * one of these negative code values. DateTimeParseError may be used to - * produce a correct ereport. + * produce a suitable error report. For some of these codes, + * DateTimeParseError requires additional information, which is carried + * in struct DateTimeErrorExtra. */ #define DTERR_BAD_FORMAT (-1) #define DTERR_FIELD_OVERFLOW (-2) #define DTERR_MD_FIELD_OVERFLOW (-3) /* triggers hint about DateStyle */ #define DTERR_INTERVAL_OVERFLOW (-4) #define DTERR_TZDISP_OVERFLOW (-5) +#define DTERR_BAD_TIMEZONE (-6) +#define DTERR_BAD_ZONE_ABBREV (-7) + +typedef struct DateTimeErrorExtra +{ + /* Needed for DTERR_BAD_TIMEZONE and DTERR_BAD_ZONE_ABBREV: */ + const char *dtee_timezone; /* incorrect time zone name */ + /* Needed for DTERR_BAD_ZONE_ABBREV: */ + const char *dtee_abbrev; /* relevant time zone abbreviation */ +} DateTimeErrorExtra; extern void GetCurrentDateTime(struct pg_tm *tm); @@ -293,19 +305,20 @@ extern int date2j(int year, int month, int day); extern int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields); -extern int DecodeDateTime(char **field, int *ftype, - int nf, int *dtype, - struct pg_tm *tm, fsec_t *fsec, int *tzp); +extern int DecodeDateTime(char **field, int *ftype, int nf, + int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, + DateTimeErrorExtra *extra); extern int DecodeTimezone(const char *str, int *tzp); -extern int DecodeTimeOnly(char **field, int *ftype, - int nf, int *dtype, - struct pg_tm *tm, fsec_t *fsec, int *tzp); +extern int DecodeTimeOnly(char **field, int *ftype, int nf, + int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, + DateTimeErrorExtra *extra); extern int DecodeInterval(char **field, int *ftype, int nf, int range, int *dtype, struct pg_itm_in *itm_in); extern int DecodeISO8601Interval(char *str, int *dtype, struct pg_itm_in *itm_in); -extern void DateTimeParseError(int dterr, const char *str, +extern void DateTimeParseError(int dterr, DateTimeErrorExtra *extra, + const char *str, const char *datatype) pg_attribute_noreturn(); extern int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp); @@ -323,7 +336,8 @@ extern int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm); extern int DecodeTimezoneAbbrev(int field, const char *lowtoken, - int *offset, pg_tz **tz); + int *ftype, int *offset, pg_tz **tz, + DateTimeErrorExtra *extra); extern int DecodeSpecial(int field, const char *lowtoken, int *val); extern int DecodeUnits(int field, const char *lowtoken, int *val); |