36 int fmask,
int *tmask,
39 int fmask,
int *tmask,
42 int *tmask,
struct pg_itm *itm);
48static int DecodeDate(
char *
str,
int fmask,
int *tmask,
bool *is2digits,
51 int precision,
bool fillzeros);
69 const char *abbr,
pg_tz *tzp,
70 int *offset,
int *isdst);
77 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0},
78 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}
81const char *
const months[] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
82"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec", NULL};
84const char *
const days[] = {
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
85"Thursday",
"Friday",
"Saturday", NULL};
116 {
"august",
MONTH, 8},
120 {
"december",
MONTH, 12},
126 {
"february",
MONTH, 2},
135 {
"january",
MONTH, 1},
150 {
"november",
MONTH, 11},
153 {
"october",
MONTH, 10},
158 {
"saturday",
DOW, 6},
161 {
"september",
MONTH, 9},
168 {
"thursday",
DOW, 4},
175 {
"wednesday",
DOW, 3},
312 century = year / 100;
313 julian = year * 365 - 32167;
314 julian += year / 4 - century + century / 4;
315 julian += 7834 * month / 256 + day;
321j2date(
int jd,
int *year,
int *month,
int *day)
330 quad = julian / 146097;
331 extra = (julian - quad * 146097) * 4 + 3;
332 julian += 60 + quad * 3 + extra / 146097;
333 quad = julian / 1461;
334 julian -= quad * 1461;
335 y = julian * 4 / 1461;
336 julian = ((
y != 0) ? ((julian + 305) % 365) : ((julian + 306) % 366))
340 quad = julian * 2141 / 65536;
341 *day = julian - 7834 * quad / 256;
410 static pg_tz *cache_timezone = NULL;
411 static struct pg_tm cache_tm;
421 cache_timezone = NULL;
428 if (
timestamp2tm(cur_ts, &cache_tz, &cache_tm, &cache_fsec,
431 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
432 errmsg(
"timestamp out of range")));
471 char *end = &cp[precision + 1];
472 bool gotnonzero =
false;
487 remainder = oldval -
value * 10;
494 cp[precision] =
'0' + remainder;
496 end = &cp[precision];
567 else if (frac < -0.5)
593 extra_days = (int) frac;
647 if (val < INT_MIN || val > INT_MAX)
661 if (val < INT_MIN || val > INT_MAX)
676 if (val < INT_MIN || val > INT_MAX)
706 *frac = strtod(cp, &cp);
708 if (*cp !=
'\0' || errno != 0)
727 *fsec = rint(frac * 1000000);
765 char **field,
int *ftype,
int maxfields,
int *numfields)
768 const char *cp = timestr;
769 char *bufp = workbuf;
770 const char *bufend = workbuf + buflen;
778#define APPEND_CHAR(bufptr, end, newchar) \
781 if (((bufptr) + 1) >= (end)) \
782 return DTERR_BAD_FORMAT; \
783 *(bufptr)++ = newchar; \
790 if (isspace((
unsigned char) *cp))
802 if (isdigit((
unsigned char) *cp))
805 while (isdigit((
unsigned char) *cp))
813 while (isdigit((
unsigned char) *cp) ||
814 (*cp ==
':') || (*cp ==
'.'))
818 else if (*cp ==
'-' || *cp ==
'/' || *cp ==
'.')
825 if (isdigit((
unsigned char) *cp))
828 while (isdigit((
unsigned char) *cp))
839 while (isdigit((
unsigned char) *cp) || *cp == delim)
846 while (isalnum((
unsigned char) *cp) || *cp == delim)
862 while (isdigit((
unsigned char) *cp))
871 else if (isalpha((
unsigned char) *cp))
877 while (isalpha((
unsigned char) *cp))
889 if (*cp ==
'-' || *cp ==
'/' || *cp ==
'.')
891 else if (*cp ==
'+' || isdigit((
unsigned char) *cp))
904 }
while (*cp ==
'+' || *cp ==
'-' ||
905 *cp ==
'/' || *cp ==
'_' ||
906 *cp ==
'.' || *cp ==
':' ||
907 isalnum((
unsigned char) *cp));
911 else if (*cp ==
'+' || *cp ==
'-')
915 while (isspace((
unsigned char) *cp))
919 if (isdigit((
unsigned char) *cp))
923 while (isdigit((
unsigned char) *cp) ||
924 *cp ==
':' || *cp ==
'.' || *cp ==
'-')
928 else if (isalpha((
unsigned char) *cp))
932 while (isalpha((
unsigned char) *cp))
940 else if (ispunct((
unsigned char) *cp))
1000 bool haveTextMonth =
false;
1001 bool isjulian =
false;
1002 bool is2digits =
false;
1004 pg_tz *namedTz = NULL;
1005 pg_tz *abbrevTz = NULL;
1007 char *abbrev = NULL;
1008 struct pg_tm cur_tm;
1024 for (
i = 0;
i < nf;
i++)
1045 if (errno == ERANGE || jday < 0)
1071 else if (ptype != 0 ||
1079 if (isdigit((
unsigned char) *field[
i]) || ptype != 0)
1102 if ((cp = strchr(field[
i],
'-')) == NULL)
1143 &tmask, &is2digits,
tm);
1199 if (errno == ERANGE)
1201 if (*cp !=
'.' && *cp !=
'\0')
1255 flen = strlen(field[
i]);
1256 cp = strchr(field[
i],
'.');
1262 &tmask, &is2digits,
tm);
1267 else if (cp != NULL && flen - strlen(cp) > 2)
1290 else if (flen >= 6 && (!(fmask &
DTK_DATE_M) ||
1303 haveTextMonth, fmask,
1380 elog(
ERROR,
"unrecognized RESERV datetime token: %d",
1392 if ((fmask &
DTK_M(
MONTH)) && !haveTextMonth &&
1399 haveTextMonth =
true;
1542 if (namedTz != NULL)
1555 if (abbrevTz != NULL)
1565 if (tzp != NULL && !(fmask &
DTK_M(
TZ)))
1627 long int before_gmtoff,
1649 if (mytime < 0 && day > 0)
1659 if (mytime < 0 && prevtime > 0)
1663 &before_gmtoff, &before_isdst,
1665 &after_gmtoff, &after_isdst,
1674 *tp = mytime - before_gmtoff;
1675 return -(int) before_gmtoff;
1681 beforetime = mytime - before_gmtoff;
1682 if ((before_gmtoff > 0 &&
1683 mytime < 0 && beforetime > 0) ||
1684 (before_gmtoff <= 0 &&
1685 mytime > 0 && beforetime < 0))
1687 aftertime = mytime - after_gmtoff;
1688 if ((after_gmtoff > 0 &&
1689 mytime < 0 && aftertime > 0) ||
1690 (after_gmtoff <= 0 &&
1691 mytime > 0 && aftertime < 0))
1699 if (beforetime < boundary && aftertime < boundary)
1703 return -(int) before_gmtoff;
1705 if (beforetime > boundary && aftertime >= boundary)
1709 return -(int) after_gmtoff;
1723 if (beforetime > aftertime)
1727 return -(int) before_gmtoff;
1731 return -(int) after_gmtoff;
1773 &abbr_offset, &abbr_isdst))
1795 pg_tz *tzp,
int *isdst)
1808 &abbr_offset, isdst))
1816 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1817 errmsg(
"timestamp out of range")));
1832 int *offset,
int *isdst)
1839 strlcpy(upabbr, abbr,
sizeof(upabbr));
1840 for (p = (
unsigned char *) upabbr; *p; p++)
1851 *offset = (int) -gmtoff;
1866 bool *isfixed,
int *offset,
int *isdst)
1873 strlcpy(upabbr, abbr,
sizeof(upabbr));
1874 for (p = (
unsigned char *) upabbr; *p; p++)
1885 *offset = (int) -gmtoff;
1919 bool isjulian =
false;
1920 bool is2digits =
false;
1923 pg_tz *namedTz = NULL;
1924 pg_tz *abbrevTz = NULL;
1925 char *abbrev = NULL;
1939 for (
i = 0;
i < nf;
i++)
1953 if (
i == 0 && nf >= 2 &&
1957 &tmask, &is2digits,
tm);
1964 if (isdigit((
unsigned char) *field[
i]))
1978 if ((cp = strchr(field[
i],
'-')) == NULL)
2062 if (errno == ERANGE)
2064 if (*cp !=
'.' && *cp !=
'\0')
2121 flen = strlen(field[
i]);
2122 cp = strchr(field[
i],
'.');
2131 if (
i == 0 && nf >= 2 && ftype[nf - 1] ==
DTK_DATE)
2134 &tmask, &is2digits,
tm);
2139 else if (flen - strlen(cp) > 2)
2344 if (namedTz != NULL)
2355 *tzp = -(int) gmtoff;
2369 if (abbrevTz != NULL)
2399 if (tzp != NULL && !(fmask &
DTK_M(
TZ)))
2450 bool haveTextMonth =
false;
2462 while (*
str !=
'\0' && !isalnum((
unsigned char) *
str))
2469 if (isdigit((
unsigned char) *
str))
2471 while (isdigit((
unsigned char) *
str))
2474 else if (isalpha((
unsigned char) *
str))
2476 while (isalpha((
unsigned char) *
str))
2487 for (
i = 0;
i < nf;
i++)
2489 if (isalpha((
unsigned char) *field[
i]))
2500 haveTextMonth =
true;
2518 for (
i = 0;
i < nf;
i++)
2520 if (field[
i] == NULL)
2523 if ((
len = strlen(field[
i])) <= 0)
2635 int *tmask,
struct pg_itm *itm)
2645 if (errno == ERANGE)
2651 if (errno == ERANGE)
2666 else if (*cp ==
'.')
2678 else if (*cp ==
':')
2682 if (errno == ERANGE)
2690 else if (*cp !=
'\0')
2772 int *tmask,
struct pg_tm *
tm,
fsec_t *fsec,
bool *is2digits)
2782 if (errno == ERANGE)
2808 else if (*cp !=
'\0')
2889 if (flen >= 3 && *is2digits)
2942 *is2digits = (flen <= 2);
2957 int *tmask,
struct pg_tm *
tm,
fsec_t *fsec,
bool *is2digits)
2965 if ((cp = strchr(
str,
'.')) != NULL)
2981 frac = strtod(cp, NULL);
2984 *fsec = rint(frac * 1000000);
3002 *(
str + (
len - 2)) =
'\0';
3004 *(
str + (
len - 4)) =
'\0';
3060 if (*
str !=
'+' && *
str !=
'-')
3065 if (errno == ERANGE)
3073 if (errno == ERANGE)
3079 if (errno == ERANGE)
3084 else if (*cp ==
'\0' && strlen(
str) > 3)
3136 int *ftype,
int *offset,
pg_tz **tz,
3151 *ftype = tzc->
ftype;
3164 &isfixed, offset, &isdst))
3166 *ftype = (isfixed ? (isdst ?
DTZ :
TZ) :
DYNTZ);
3169 *offset = -(*offset);
3172 tzc->
ftype = *ftype;
3203 *offset = tp->
value;
3209 tzc->
ftype = *ftype;
3323 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3324 errmsg(
"time zone \"%s\" not recognized", tzname)));
3376 if (*
str ==
'\0' || !isalpha((
unsigned char) *
str))
3380 lowtoken[
len] =
'\0';
3398 &isfixed, offset, &isdst))
3403 *offset = -(*offset);
3437 *offset = tp->
value;
3443 lowtoken[--
len] =
'\0';
3483 bool force_negative =
false;
3484 bool is_before =
false;
3485 bool parsing_unit_val =
false;
3518 force_negative =
true;
3520 for (
i = 1;
i < nf;
i++)
3522 if (*field[
i] ==
'-' || *field[
i] ==
'+')
3524 force_negative =
false;
3531 for (
i = nf - 1;
i >= 0;
i--)
3540 if (force_negative &&
3544 parsing_unit_val =
false;
3554 Assert(*field[
i] ==
'-' || *field[
i] ==
'+');
3560 if (strchr(field[
i] + 1,
':') != NULL &&
3562 &tmask, itm_in) == 0)
3564 if (*field[
i] ==
'-')
3572 if (force_negative &&
3582 parsing_unit_val =
false;
3632 val = strtoi64(field[
i], &cp, 10);
3633 if (errno == ERANGE)
3647 if (*field[
i] ==
'-')
3655 else if (*cp ==
'.')
3660 if (*field[
i] ==
'-')
3663 else if (*cp ==
'\0')
3772 parsing_unit_val =
false;
3778 if (parsing_unit_val)
3791 parsing_unit_val =
true;
3846 if (parsing_unit_val)
3854 itm_in->
tm_mon == INT_MIN ||
3892 if (!(isdigit((
unsigned char) *
str) || *
str ==
'-' || *
str ==
'.'))
3895 val = strtod(
str, endptr);
3897 if (*endptr ==
str || errno != 0)
3900 if (isnan(
val) || val < -1.0e15 || val > 1.0e15)
3907 *fpart =
val - *ipart;
3909 Assert(*fpart > -1.0 && *fpart < 1.0);
3921 if (*fieldstart ==
'-')
3923 return strspn(fieldstart,
"0123456789");
3948 bool datepart =
true;
3949 bool havefield =
false;
3954 if (strlen(
str) < 2 ||
str[0] !=
'P')
4209 const char *
str,
const char *datatype,
4216 (
errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
4217 errmsg(
"date/time field value out of range: \"%s\"",
4223 (
errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
4224 errmsg(
"date/time field value out of range: \"%s\"",
4226 errhint(
"Perhaps you need a different \"DateStyle\" setting.")));
4230 (
errcode(ERRCODE_INTERVAL_FIELD_OVERFLOW),
4231 errmsg(
"interval field value out of range: \"%s\"",
4236 (
errcode(ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE),
4237 errmsg(
"time zone displacement out of range: \"%s\"",
4242 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4243 errmsg(
"time zone \"%s\" not recognized",
4248 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
4249 errmsg(
"time zone \"%s\" not recognized",
4251 errdetail(
"This time zone name appears in the configuration file for time zone abbreviation \"%s\".",
4257 (
errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4258 errmsg(
"invalid input syntax for type %s: \"%s\"",
4273 const datetkn *last = base + nel - 1,
4277 while (last >= base)
4279 position = base + ((last - base) >> 1);
4281 result = (int)
key[0] - (
int) position->token[0];
4290 last = position - 1;
4292 base = position + 1;
4318 *
str++ = (tz <= 0 ?
'+' :
'-');
4412 memcpy(
str,
" BC", 3);
4616 memcpy(
str,
" BC", 3);
4634 return cp + strlen(cp);
4640 bool *is_zero,
bool *is_before)
4645 (!*is_zero) ?
" " :
"",
4646 (*is_before &&
value > 0) ?
"+" :
"",
4649 (
value != 1) ?
"s" :
"");
4655 *is_before = (
value < 0);
4657 return cp + strlen(cp);
4663 bool *is_zero,
bool *is_before)
4670 *is_before = (
value < 0);
4673 else if (*is_before)
4677 return cp + strlen(cp);
4711 bool is_before =
false;
4712 bool is_zero =
true;
4725 bool has_negative = year < 0 || mon < 0 ||
4726 mday < 0 || hour < 0 ||
4727 min < 0 || sec < 0 || fsec < 0;
4728 bool has_positive = year > 0 || mon > 0 ||
4729 mday > 0 || hour > 0 ||
4730 min > 0 || sec > 0 || fsec > 0;
4731 bool has_year_month = year != 0 || mon != 0;
4732 bool has_day_time = mday != 0 || hour != 0 ||
4733 min != 0 || sec != 0 || fsec != 0;
4734 bool has_day = mday != 0;
4735 bool sql_standard_value = !(has_negative && has_positive) &&
4736 !(has_year_month && has_day_time);
4742 if (has_negative && sql_standard_value)
4754 if (!has_negative && !has_positive)
4758 else if (!sql_standard_value)
4765 char year_sign = (year < 0 || mon < 0) ?
'-' :
'+';
4766 char day_sign = (mday < 0) ?
'-' :
'+';
4767 char sec_sign = (hour < 0 || min < 0 ||
4768 sec < 0 || fsec < 0) ?
'-' :
'+';
4770 sprintf(cp,
"%c%d-%d %c%lld %c%lld:%02d:",
4771 year_sign, abs(year), abs(mon),
4772 day_sign, (
long long) i64abs(mday),
4773 sec_sign, (
long long) i64abs(hour), abs(min));
4778 else if (has_year_month)
4780 sprintf(cp,
"%d-%d", year, mon);
4784 sprintf(cp,
"%lld %lld:%02d:",
4785 (
long long) mday, (
long long) hour, min);
4792 sprintf(cp,
"%lld:%02d:", (
long long) hour, min);
4803 if (year == 0 && mon == 0 && mday == 0 &&
4804 hour == 0 && min == 0 && sec == 0 && fsec == 0)
4813 if (hour != 0 || min != 0 || sec != 0 || fsec != 0)
4817 if (sec != 0 || fsec != 0)
4819 if (sec < 0 || fsec < 0)
4838 if (is_zero || hour != 0 || min != 0 || sec != 0 || fsec != 0)
4840 bool minus = (hour < 0 || min < 0 || sec < 0 || fsec < 0);
4842 sprintf(cp,
"%s%s%02lld:%02d:",
4844 (minus ?
"-" : (is_before ?
"+" :
"")),
4845 (
long long) i64abs(hour), abs(min));
4862 if (sec != 0 || fsec != 0)
4865 if (sec < 0 || (sec == 0 && fsec < 0))
4869 else if (!is_before)
4877 (abs(sec) != 1 || fsec != 0) ?
"s" :
"");
4900 for (
i = 0;
i < nel;
i++)
4906 elog(
LOG,
"token too long in %s table: \"%.*s\"",
4916 elog(
LOG,
"ordering error in %s table: \"%s\" >= \"%s\"",
4972 if (new_precis < 0 || new_precis == max_precis ||
4973 (old_precis >= 0 && new_precis >= old_precis))
5000 for (
i = 0;
i < n;
i++)
5002 struct tzEntry *abbr = abbrevs +
i;
5004 if (abbr->
zone != NULL)
5009 strlen(abbr->
zone) + 1;