10 #error -ffast-math is known to break this code
33 *fsec += rint(frac * 1000000);
48 extra_days = (int) frac;
60 if (!(isdigit((
unsigned char) *
str) || *
str ==
'-' || *
str ==
'.'))
65 if (*endptr ==
str || errno != 0)
68 if (val < INT_MIN || val > INT_MAX)
72 *ipart = (int) floor(
val);
74 *ipart = (int) -floor(-
val);
75 *fpart =
val - *ipart;
84 if (*fieldstart ==
'-')
86 return strspn(fieldstart,
"0123456789");
115 bool datepart =
true;
116 bool havefield =
false;
121 if (strlen(
str) < 2 ||
str[0] !=
'P')
331 bool is_before =
false;
346 for (
i = nf - 1;
i >= 0;
i--)
365 Assert(*field[
i] ==
'-' || *field[
i] ==
'+');
372 if (strchr(field[
i] + 1,
':') != NULL &&
374 &tmask,
tm, fsec) == 0)
376 if (*field[
i] ==
'-')
450 if (*field[
i] ==
'-')
458 fval = strtod(cp, &cp);
459 if (*cp !=
'\0' || errno != 0)
462 if (*field[
i] ==
'-')
465 else if (*cp ==
'\0')
475 *fsec += rint(
val + fval);
480 *fsec += rint((
val + fval) * 1000);
486 *fsec += rint(fval * 1000000);
628 bool more_signs =
false;
630 for (
i = 1;
i < nf;
i++)
632 if (*field[
i] ==
'-' || *field[
i] ==
'+')
681 bool *is_zero,
bool *is_before)
688 *is_before = (
value < 0);
695 return cp + strlen(cp);
701 bool *is_zero,
bool *is_before)
706 (!*is_zero) ?
" " :
"",
707 (*is_before &&
value > 0) ?
"+" :
"",
710 (
value != 1) ?
"s" :
"");
716 *is_before = (
value < 0);
718 return cp + strlen(cp);
728 return cp + strlen(cp);
745 sprintf(cp,
"%02d.%0*d", abs(sec), precision, abs(fsec));
747 sprintf(cp,
"%d.%0*d", abs(sec), precision, abs(fsec));
768 bool is_before =
false;
782 bool has_negative = year < 0 || mon < 0 ||
783 mday < 0 || hour < 0 ||
784 min < 0 || sec < 0 || fsec < 0;
785 bool has_positive = year > 0 || mon > 0 ||
786 mday > 0 || hour > 0 ||
787 min > 0 || sec > 0 || fsec > 0;
788 bool has_year_month = year != 0 || mon != 0;
789 bool has_day_time = mday != 0 || hour != 0 ||
790 min != 0 || sec != 0 || fsec != 0;
791 bool has_day = mday != 0;
792 bool sql_standard_value = !(has_negative && has_positive) &&
793 !(has_year_month && has_day_time);
799 if (has_negative && sql_standard_value)
811 if (!has_negative && !has_positive)
815 else if (!sql_standard_value)
822 char year_sign = (year < 0 || mon < 0) ?
'-' :
'+';
823 char day_sign = (mday < 0) ?
'-' :
'+';
824 char sec_sign = (hour < 0 || min < 0 ||
825 sec < 0 || fsec < 0) ?
'-' :
'+';
827 sprintf(cp,
"%c%d-%d %c%d %c%d:%02d:",
828 year_sign, abs(year), abs(mon),
830 sec_sign, abs(hour), abs(min));
834 else if (has_year_month)
836 sprintf(cp,
"%d-%d", year, mon);
840 sprintf(cp,
"%d %d:%02d:", mday, hour, min);
846 sprintf(cp,
"%d:%02d:", hour, min);
856 if (year == 0 && mon == 0 && mday == 0 &&
857 hour == 0 && min == 0 && sec == 0 && fsec == 0)
866 if (hour != 0 || min != 0 || sec != 0 || fsec != 0)
870 if (sec != 0 || fsec != 0)
872 if (sec < 0 || fsec < 0)
886 if (is_zero || hour != 0 || min != 0 || sec != 0 || fsec != 0)
888 bool minus = (hour < 0 || min < 0 || sec < 0 || fsec < 0);
892 (minus ?
"-" : (is_before ?
"+" :
"")),
893 abs(hour), abs(min));
909 if (sec != 0 || fsec != 0)
912 if (sec < 0 || (sec == 0 && fsec < 0))
925 (abs(sec) != 1 || fsec != 0) ?
"s" :
"");
1015 char **ptr = (endptr != NULL) ? endptr : &realptr;
int DecodeUnits(int field, const char *lowtoken, int *val)
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
static int DecodeTime(char *str, int fmask, int range, int *tmask, struct pg_tm *tm, fsec_t *fsec)
#define Assert(condition)
#define MAX_INTERVAL_PRECISION
void TrimTrailingZeros(char *str)
#define DTERR_FIELD_OVERFLOW
char * pgtypes_strdup(const char *str)
char * pgtypes_alloc(long size)
static char * AddPostgresIntPart(char *cp, int value, const char *units, bool *is_zero, bool *is_before)
void PGTYPESinterval_free(interval *intvl)
static char * AddISO8601IntPart(char *cp, int value, char units)
static char * AddVerboseIntPart(char *cp, int value, const char *units, bool *is_zero, bool *is_before)
char * PGTYPESinterval_to_asc(interval *span)
static void AdjustFractDays(double frac, struct tm *tm, fsec_t *fsec, int scale)
static int DecodeISO8601Interval(char *str, int *dtype, struct tm *tm, fsec_t *fsec)
int PGTYPESinterval_copy(interval *intvlsrc, interval *intvldest)
static int interval2tm(interval span, struct tm *tm, fsec_t *fsec)
static int tm2interval(struct tm *tm, fsec_t fsec, interval *span)
void EncodeInterval(struct tm *tm, fsec_t fsec, int style, char *str)
static int ParseISO8601Number(const char *str, char **endptr, int *ipart, double *fpart)
static void ClearPgTm(struct tm *tm, fsec_t *fsec)
static void AdjustFractSeconds(double frac, struct tm *tm, fsec_t *fsec, int scale)
static void AppendSeconds(char *cp, int sec, fsec_t fsec, int precision, bool fillzeros)
int DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm *tm, fsec_t *fsec)
interval * PGTYPESinterval_new(void)
interval * PGTYPESinterval_from_asc(char *str, char **endptr)
static int ISO8601IntegerWidth(const char *fieldstart)
#define INTSTYLE_SQL_STANDARD
#define INTSTYLE_POSTGRES_VERBOSE
#define INTSTYLE_ISO_8601
#define INTSTYLE_POSTGRES
#define PGTYPES_INTVL_BAD_INTERVAL
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
#define INTERVAL_FULL_RANGE