35 static int DecodeNumber(
int flen,
char *field,
bool haveTextMonth,
36 int fmask,
int *tmask,
39 int fmask,
int *tmask,
42 int *tmask,
struct pg_itm *itm);
48 static 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);
76 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0},
77 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}
80 const char *
const months[] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
81 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec", NULL};
83 const char *
const days[] = {
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
84 "Thursday",
"Friday",
"Saturday", NULL};
114 {
"august",
MONTH, 8},
118 {
"december",
MONTH, 12},
124 {
"february",
MONTH, 2},
133 {
"january",
MONTH, 1},
148 {
"november",
MONTH, 11},
151 {
"october",
MONTH, 10},
156 {
"saturday",
DOW, 6},
159 {
"september",
MONTH, 9},
166 {
"thursday",
DOW, 4},
173 {
"wednesday",
DOW, 3},
301 julian =
y * 365 - 32167;
302 julian +=
y / 4 - century + century / 4;
303 julian += 7834 * m / 256 + d;
309 j2date(
int jd,
int *year,
int *month,
int *day)
318 quad = julian / 146097;
319 extra = (julian - quad * 146097) * 4 + 3;
320 julian += 60 + quad * 3 + extra / 146097;
321 quad = julian / 1461;
322 julian -= quad * 1461;
323 y = julian * 4 / 1461;
324 julian = ((
y != 0) ? ((julian + 305) % 365) : ((julian + 306) % 366))
328 quad = julian * 2141 / 65536;
329 *day = julian - 7834 * quad / 256;
398 static pg_tz *cache_timezone = NULL;
399 static struct pg_tm cache_tm;
409 cache_timezone = NULL;
416 if (
timestamp2tm(cur_ts, &cache_tz, &cache_tm, &cache_fsec,
419 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
420 errmsg(
"timestamp out of range")));
459 char *end = &cp[precision + 1];
460 bool gotnonzero =
false;
475 remainder = oldval -
value * 10;
482 cp[precision] =
'0' + remainder;
484 end = &cp[precision];
555 else if (frac < -0.5)
581 extra_days = (int) frac;
635 if (val < INT_MIN || val > INT_MAX)
649 if (val < INT_MIN || val > INT_MAX)
664 if (val < INT_MIN || val > INT_MAX)
694 *frac = strtod(cp, &cp);
696 if (*cp !=
'\0' || errno != 0)
715 *fsec = rint(frac * 1000000);
753 char **field,
int *ftype,
int maxfields,
int *numfields)
756 const char *cp = timestr;
757 char *bufp = workbuf;
758 const char *bufend = workbuf + buflen;
766 #define APPEND_CHAR(bufptr, end, newchar) \
769 if (((bufptr) + 1) >= (end)) \
770 return DTERR_BAD_FORMAT; \
771 *(bufptr)++ = newchar; \
778 if (isspace((
unsigned char) *cp))
790 if (isdigit((
unsigned char) *cp))
793 while (isdigit((
unsigned char) *cp))
801 while (isdigit((
unsigned char) *cp) ||
802 (*cp ==
':') || (*cp ==
'.'))
806 else if (*cp ==
'-' || *cp ==
'/' || *cp ==
'.')
813 if (isdigit((
unsigned char) *cp))
816 while (isdigit((
unsigned char) *cp))
827 while (isdigit((
unsigned char) *cp) || *cp == delim)
834 while (isalnum((
unsigned char) *cp) || *cp == delim)
850 while (isdigit((
unsigned char) *cp))
859 else if (isalpha((
unsigned char) *cp))
865 while (isalpha((
unsigned char) *cp))
877 if (*cp ==
'-' || *cp ==
'/' || *cp ==
'.')
879 else if (*cp ==
'+' || isdigit((
unsigned char) *cp))
892 }
while (*cp ==
'+' || *cp ==
'-' ||
893 *cp ==
'/' || *cp ==
'_' ||
894 *cp ==
'.' || *cp ==
':' ||
895 isalnum((
unsigned char) *cp));
899 else if (*cp ==
'+' || *cp ==
'-')
903 while (isspace((
unsigned char) *cp))
907 if (isdigit((
unsigned char) *cp))
911 while (isdigit((
unsigned char) *cp) ||
912 *cp ==
':' || *cp ==
'.' || *cp ==
'-')
916 else if (isalpha((
unsigned char) *cp))
920 while (isalpha((
unsigned char) *cp))
928 else if (ispunct((
unsigned char) *cp))
984 bool haveTextMonth =
false;
985 bool isjulian =
false;
986 bool is2digits =
false;
988 pg_tz *namedTz = NULL;
989 pg_tz *abbrevTz = NULL;
1008 for (
i = 0;
i < nf;
i++)
1029 if (errno == ERANGE ||
val < 0)
1055 else if (ptype != 0 ||
1063 if (isdigit((
unsigned char) *field[
i]) || ptype != 0)
1083 if ((cp = strchr(field[
i],
'-')) == NULL)
1120 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1121 errmsg(
"time zone \"%s\" not recognized",
1131 &tmask, &is2digits,
tm);
1188 if (errno == ERANGE)
1206 else if (*cp !=
'\0')
1318 flen = strlen(field[
i]);
1319 cp = strchr(field[
i],
'.');
1325 &tmask, &is2digits,
tm);
1330 else if (cp != NULL && flen - strlen(cp) > 2)
1353 else if (flen >= 6 && (!(fmask &
DTK_DATE_M) ||
1366 haveTextMonth, fmask,
1443 if ((fmask &
DTK_M(
MONTH)) && !haveTextMonth &&
1450 haveTextMonth =
true;
1594 if (namedTz != NULL)
1607 if (abbrevTz != NULL)
1617 if (tzp != NULL && !(fmask &
DTK_M(
TZ)))
1679 long int before_gmtoff,
1701 if (mytime < 0 && day > 0)
1711 if (mytime < 0 && prevtime > 0)
1715 &before_gmtoff, &before_isdst,
1717 &after_gmtoff, &after_isdst,
1726 *tp = mytime - before_gmtoff;
1727 return -(int) before_gmtoff;
1733 beforetime = mytime - before_gmtoff;
1734 if ((before_gmtoff > 0 &&
1735 mytime < 0 && beforetime > 0) ||
1736 (before_gmtoff <= 0 &&
1737 mytime > 0 && beforetime < 0))
1739 aftertime = mytime - after_gmtoff;
1740 if ((after_gmtoff > 0 &&
1741 mytime < 0 && aftertime > 0) ||
1742 (after_gmtoff <= 0 &&
1743 mytime > 0 && aftertime < 0))
1751 if (beforetime < boundary && aftertime < boundary)
1755 return -(int) before_gmtoff;
1757 if (beforetime > boundary && aftertime >= boundary)
1761 return -(int) after_gmtoff;
1775 if (beforetime > aftertime)
1779 return -(int) before_gmtoff;
1783 return -(int) after_gmtoff;
1825 &abbr_offset, &abbr_isdst))
1847 pg_tz *tzp,
int *isdst)
1860 &abbr_offset, isdst))
1868 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1869 errmsg(
"timestamp out of range")));
1884 int *offset,
int *isdst)
1891 strlcpy(upabbr, abbr,
sizeof(upabbr));
1892 for (p = (
unsigned char *) upabbr; *p; p++)
1903 *offset = (int) -gmtoff;
1933 bool isjulian =
false;
1934 bool is2digits =
false;
1937 pg_tz *namedTz = NULL;
1938 pg_tz *abbrevTz = NULL;
1939 char *abbrev = NULL;
1953 for (
i = 0;
i < nf;
i++)
1967 if (
i == 0 && nf >= 2 &&
1971 &tmask, &is2digits,
tm);
1978 if (isdigit((
unsigned char) *field[
i]))
1992 if ((cp = strchr(field[
i],
'-')) == NULL)
2026 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2027 errmsg(
"time zone \"%s\" not recognized",
2086 if (errno == ERANGE)
2104 else if (*cp !=
'\0')
2217 flen = strlen(field[
i]);
2218 cp = strchr(field[
i],
'.');
2227 if (
i == 0 && nf >= 2 && ftype[nf - 1] ==
DTK_DATE)
2230 &tmask, &is2digits,
tm);
2235 else if (flen - strlen(cp) > 2)
2440 if (namedTz != NULL)
2451 *tzp = -(int) gmtoff;
2465 if (abbrevTz != NULL)
2495 if (tzp != NULL && !(fmask &
DTK_M(
TZ)))
2546 bool haveTextMonth =
false;
2558 while (*
str !=
'\0' && !isalnum((
unsigned char) *
str))
2565 if (isdigit((
unsigned char) *
str))
2567 while (isdigit((
unsigned char) *
str))
2570 else if (isalpha((
unsigned char) *
str))
2572 while (isalpha((
unsigned char) *
str))
2583 for (
i = 0;
i < nf;
i++)
2585 if (isalpha((
unsigned char) *field[
i]))
2596 haveTextMonth =
true;
2614 for (
i = 0;
i < nf;
i++)
2616 if (field[
i] == NULL)
2619 if ((
len = strlen(field[
i])) <= 0)
2731 int *tmask,
struct pg_itm *itm)
2741 if (errno == ERANGE)
2747 if (errno == ERANGE)
2762 else if (*cp ==
'.')
2774 else if (*cp ==
':')
2778 if (errno == ERANGE)
2786 else if (*cp !=
'\0')
2868 int *tmask,
struct pg_tm *
tm,
fsec_t *fsec,
bool *is2digits)
2878 if (errno == ERANGE)
2904 else if (*cp !=
'\0')
2985 if (flen >= 3 && *is2digits)
3038 *is2digits = (flen <= 2);
3053 int *tmask,
struct pg_tm *
tm,
fsec_t *fsec,
bool *is2digits)
3061 if ((cp = strchr(
str,
'.')) != NULL)
3077 frac = strtod(cp, NULL);
3080 *fsec = rint(frac * 1000000);
3098 *(
str + (
len - 2)) =
'\0';
3100 *(
str + (
len - 4)) =
'\0';
3156 if (*
str !=
'+' && *
str !=
'-')
3161 if (errno == ERANGE)
3169 if (errno == ERANGE)
3175 if (errno == ERANGE)
3180 else if (*cp ==
'\0' && strlen(
str) > 3)
3226 int *offset,
pg_tz **tz)
3258 *offset = tp->
value;
3336 bool force_negative =
false;
3337 bool is_before =
false;
3370 force_negative =
true;
3372 for (
i = 1;
i < nf;
i++)
3374 if (*field[
i] ==
'-' || *field[
i] ==
'+')
3376 force_negative =
false;
3383 for (
i = nf - 1;
i >= 0;
i--)
3392 if (force_negative &&
3405 Assert(*field[
i] ==
'-' || *field[
i] ==
'+');
3411 if (strchr(field[
i] + 1,
':') != NULL &&
3413 &tmask, itm_in) == 0)
3415 if (*field[
i] ==
'-')
3423 if (force_negative &&
3483 if (errno == ERANGE)
3497 if (*field[
i] ==
'-')
3505 else if (*cp ==
'.')
3510 if (*field[
i] ==
'-')
3513 else if (*cp ==
'\0')
3670 itm_in->
tm_mon == INT_MIN ||
3710 if (isdigit((
unsigned char) **endptr))
3714 if (**endptr ==
'.')
3721 if (isdigit((
unsigned char) *(*endptr + 1)))
3722 *fpart = strtod(*endptr, endptr) *
sign;
3731 if (*endptr ==
str || errno != 0)
3745 if (*fieldstart ==
'-')
3747 return strspn(fieldstart,
"0123456789");
3772 bool datepart =
true;
3773 bool havefield =
false;
3778 if (strlen(
str) < 2 ||
str[0] !=
'P')
4030 (
errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
4031 errmsg(
"date/time field value out of range: \"%s\"",
4037 (
errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
4038 errmsg(
"date/time field value out of range: \"%s\"",
4040 errhint(
"Perhaps you need a different \"datestyle\" setting.")));
4044 (
errcode(ERRCODE_INTERVAL_FIELD_OVERFLOW),
4045 errmsg(
"interval field value out of range: \"%s\"",
4050 (
errcode(ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE),
4051 errmsg(
"time zone displacement out of range: \"%s\"",
4057 (
errcode(ERRCODE_INVALID_DATETIME_FORMAT),
4058 errmsg(
"invalid input syntax for type %s: \"%s\"",
4073 const datetkn *last = base + nel - 1,
4077 while (last >= base)
4079 position = base + ((last - base) >> 1);
4081 result = (int)
key[0] - (
int) position->token[0];
4090 last = position - 1;
4092 base = position + 1;
4118 *
str++ = (tz <= 0 ?
'+' :
'-');
4212 memcpy(
str,
" BC", 3);
4416 memcpy(
str,
" BC", 3);
4434 return cp + strlen(cp);
4440 bool *is_zero,
bool *is_before)
4445 (!*is_zero) ?
" " :
"",
4446 (*is_before &&
value > 0) ?
"+" :
"",
4449 (
value != 1) ?
"s" :
"");
4455 *is_before = (
value < 0);
4457 return cp + strlen(cp);
4463 bool *is_zero,
bool *is_before)
4470 *is_before = (
value < 0);
4473 else if (*is_before)
4477 return cp + strlen(cp);
4511 bool is_before =
false;
4512 bool is_zero =
true;
4525 bool has_negative = year < 0 || mon < 0 ||
4526 mday < 0 || hour < 0 ||
4527 min < 0 || sec < 0 || fsec < 0;
4528 bool has_positive = year > 0 || mon > 0 ||
4529 mday > 0 || hour > 0 ||
4530 min > 0 || sec > 0 || fsec > 0;
4531 bool has_year_month = year != 0 || mon != 0;
4532 bool has_day_time = mday != 0 || hour != 0 ||
4533 min != 0 || sec != 0 || fsec != 0;
4534 bool has_day = mday != 0;
4535 bool sql_standard_value = !(has_negative && has_positive) &&
4536 !(has_year_month && has_day_time);
4542 if (has_negative && sql_standard_value)
4554 if (!has_negative && !has_positive)
4558 else if (!sql_standard_value)
4565 char year_sign = (year < 0 || mon < 0) ?
'-' :
'+';
4566 char day_sign = (mday < 0) ?
'-' :
'+';
4567 char sec_sign = (hour < 0 || min < 0 ||
4568 sec < 0 || fsec < 0) ?
'-' :
'+';
4570 sprintf(cp,
"%c%d-%d %c%lld %c%lld:%02d:",
4571 year_sign, abs(year), abs(mon),
4572 day_sign, (
long long)
Abs(mday),
4573 sec_sign, (
long long)
Abs(hour), abs(min));
4578 else if (has_year_month)
4580 sprintf(cp,
"%d-%d", year, mon);
4584 sprintf(cp,
"%lld %lld:%02d:",
4585 (
long long) mday, (
long long) hour, min);
4592 sprintf(cp,
"%lld:%02d:", (
long long) hour, min);
4603 if (year == 0 && mon == 0 && mday == 0 &&
4604 hour == 0 && min == 0 && sec == 0 && fsec == 0)
4613 if (hour != 0 || min != 0 || sec != 0 || fsec != 0)
4617 if (sec != 0 || fsec != 0)
4619 if (sec < 0 || fsec < 0)
4638 if (is_zero || hour != 0 || min != 0 || sec != 0 || fsec != 0)
4640 bool minus = (hour < 0 || min < 0 || sec < 0 || fsec < 0);
4642 sprintf(cp,
"%s%s%02lld:%02d:",
4644 (minus ?
"-" : (is_before ?
"+" :
"")),
4645 (
long long)
Abs(hour), abs(min));
4662 if (sec != 0 || fsec != 0)
4665 if (sec < 0 || (sec == 0 && fsec < 0))
4669 else if (!is_before)
4677 (abs(sec) != 1 || fsec != 0) ?
"s" :
"");
4700 for (
i = 0;
i < nel;
i++)
4706 elog(
LOG,
"token too long in %s table: \"%.*s\"",
4714 strcmp(base[
i - 1].token, base[
i].token) >= 0)
4716 elog(
LOG,
"ordering error in %s table: \"%s\" >= \"%s\"",
4772 if (new_precis < 0 || new_precis == max_precis ||
4773 (old_precis >= 0 && new_precis >= old_precis))
4800 for (
i = 0;
i < n;
i++)
4802 struct tzEntry *abbr = abbrevs +
i;
4804 if (abbr->
zone != NULL)
4809 strlen(abbr->
zone) + 1;
4826 for (
i = 0;
i < n;
i++)
4828 struct tzEntry *abbr = abbrevs +
i;
4833 if (abbr->
zone != NULL)
4848 strlen(abbr->
zone) + 1;
4895 if (dtza->
tz == NULL)
4903 if (dtza->
tz == NULL)
4905 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
4906 errmsg(
"time zone \"%s\" not recognized",
4908 errdetail(
"This time zone name appears in the configuration file for time zone abbreviation \"%s\".",
4951 pindex = (
int *)
palloc(
sizeof(
int));
4963 INTERVALOID, -1, 0);
4984 gmtoffset = tp->
value;
4988 gmtoffset = tp->
value;
5004 is_dst = (
bool) isdst;
5008 elog(
ERROR,
"unrecognized timezone type %d", (
int) tp->
type);
5014 MemSet(nulls, 0,
sizeof(nulls));
5021 for (p = (
unsigned char *) buffer; *p; p++)
5076 &tzoff, &
tm, &fsec, &tzn, tz) != 0)
5088 if (tzn && strlen(tzn) > 31)
5091 MemSet(nulls, 0,
sizeof(nulls));
static const datetkn * abbrevcache[MAXDATEFIELDS]
static int DecodeDate(char *str, int fmask, int *tmask, bool *is2digits, struct pg_tm *tm)
static int DetermineTimeZoneOffsetInternal(struct pg_tm *tm, pg_tz *tzp, pg_time_t *tp)
static char * AddVerboseIntPart(char *cp, int64 value, const char *units, bool *is_zero, bool *is_before)
#define APPEND_CHAR(bufptr, end, newchar)
static int DecodeNumberField(int len, char *str, int fmask, int *tmask, struct pg_tm *tm, fsec_t *fsec, bool *is2digits)
int DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp)
int DecodeTimezoneAbbrev(int field, char *lowtoken, int *offset, pg_tz **tz)
static char * AddPostgresIntPart(char *cp, int64 value, const char *units, bool *is_zero, bool *is_before)
static bool CheckDateTokenTable(const char *tablename, const datetkn *base, int nel)
int DecodeTimezone(char *str, int *tzp)
int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, pg_tz *tzp, int *isdst)
static int ParseFraction(char *cp, double *frac)
void InstallTimeZoneAbbrevs(TimeZoneAbbrevTable *tbl)
static const datetkn datetktbl[]
static bool int64_multiply_add(int64 val, int64 multiplier, int64 *sum)
static char * EncodeTimezone(char *str, int tz, int style)
static TimeZoneAbbrevTable * zoneabbrevtbl
static const datetkn * deltacache[MAXDATEFIELDS]
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
void EncodeInterval(struct pg_itm *itm, int style, char *str)
static bool AdjustDays(int64 val, int scale, struct pg_itm_in *itm_in)
static const datetkn * datecache[MAXDATEFIELDS]
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
static bool DetermineTimeZoneAbbrevOffsetInternal(pg_time_t t, const char *abbr, pg_tz *tzp, int *offset, int *isdst)
static char * AddISO8601IntPart(char *cp, int64 value, char units)
static int ParseFractionalSecond(char *cp, fsec_t *fsec)
static bool AdjustFractYears(double frac, int scale, struct pg_itm_in *itm_in)
static bool AdjustMicroseconds(int64 val, double fval, int64 scale, struct pg_itm_in *itm_in)
static int DecodeTimeCommon(char *str, int fmask, int range, int *tmask, struct pg_itm *itm)
int DecodeInterval(char **field, int *ftype, int nf, int range, int *dtype, struct pg_itm_in *itm_in)
int date2j(int y, int m, int d)
int DecodeSpecial(int field, char *lowtoken, int *val)
static int DecodeTimeForInterval(char *str, int fmask, int range, int *tmask, struct pg_itm_in *itm_in)
bool CheckDateTokenTables(void)
static const int szdeltatktbl
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Datum pg_timezone_names(PG_FUNCTION_ARGS)
void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str)
static int DecodeTime(char *str, int fmask, int range, int *tmask, struct pg_tm *tm, fsec_t *fsec)
static bool AdjustFractMicroseconds(double frac, int64 scale, struct pg_itm_in *itm_in)
int DecodeISO8601Interval(char *str, int *dtype, struct pg_itm_in *itm_in)
void DateTimeParseError(int dterr, const char *str, const char *datatype)
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
void j2date(int jd, int *year, int *month, int *day)
void GetCurrentDateTime(struct pg_tm *tm)
static int ISO8601IntegerWidth(char *fieldstart)
static bool AdjustYears(int64 val, int scale, struct pg_itm_in *itm_in)
Datum pg_timezone_abbrevs(PG_FUNCTION_ARGS)
TimeZoneAbbrevTable * ConvertTimeZoneAbbrevs(struct tzEntry *abbrevs, int n)
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
const char *const months[]
static bool AdjustMonths(int64 val, struct pg_itm_in *itm_in)
static char * AppendSeconds(char *cp, int sec, fsec_t fsec, int precision, bool fillzeros)
static const int szdatetktbl
static int DecodeNumber(int flen, char *field, bool haveTextMonth, int fmask, int *tmask, struct pg_tm *tm, fsec_t *fsec, bool *is2digits)
int DecodeUnits(int field, char *lowtoken, int *val)
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
static char * AppendTimestampSeconds(char *cp, struct pg_tm *tm, fsec_t fsec)
static const datetkn * datebsearch(const char *key, const datetkn *base, int nel)
static int ParseISO8601Number(char *str, char **endptr, int64 *ipart, double *fpart)
static pg_tz * FetchDynamicTimeZone(TimeZoneAbbrevTable *tbl, const datetkn *tp)
static bool AdjustFractDays(double frac, int scale, struct pg_itm_in *itm_in)
static void ClearPgItmIn(struct pg_itm_in *itm_in)
static const datetkn deltatktbl[]
void GetCurrentTimeUsec(struct pg_tm *tm, fsec_t *fsec, int *tzp)
Node * TemporalSimplify(int32 max_precis, Node *node)
int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp)
void dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
int itmin2interval(struct pg_itm_in *itm_in, Interval *span)
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Datum now(PG_FUNCTION_ARGS)
pg_time_t timestamptz_to_time_t(TimestampTz t)
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
#define offsetof(type, field)
#define strtoi64(str, endptr, base)
#define MemSet(start, val, len)