mirror of
https://github.com/postgres/postgres.git
synced 2025-06-11 20:28:21 +03:00
8.4 pgindent run, with new combined Linux/FreeBSD/MinGW typedef list
provided by Andrew.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.207 2009/06/10 05:05:03 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.208 2009/06/11 14:49:03 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -40,17 +40,17 @@ static int DecodeTime(char *str, int fmask, int range,
|
||||
int *tmask, struct pg_tm * tm, fsec_t *fsec);
|
||||
static int DecodeTimezone(char *str, int *tzp);
|
||||
static const datetkn *datebsearch(const char *key, const datetkn *base, int nel);
|
||||
static int DecodeDate(char *str, int fmask, int *tmask, bool *is2digits,
|
||||
struct pg_tm * tm);
|
||||
static int ValidateDate(int fmask, bool is2digits, bool bc,
|
||||
struct pg_tm * tm);
|
||||
static int DecodeDate(char *str, int fmask, int *tmask, bool *is2digits,
|
||||
struct pg_tm * tm);
|
||||
static int ValidateDate(int fmask, bool is2digits, bool bc,
|
||||
struct pg_tm * tm);
|
||||
static void TrimTrailingZeros(char *str);
|
||||
static void AppendSeconds(char *cp, int sec, fsec_t fsec,
|
||||
int precision, bool fillzeros);
|
||||
int precision, bool fillzeros);
|
||||
static void AdjustFractSeconds(double frac, struct pg_tm * tm, fsec_t *fsec,
|
||||
int scale);
|
||||
int scale);
|
||||
static void AdjustFractDays(double frac, struct pg_tm * tm, fsec_t *fsec,
|
||||
int scale);
|
||||
int scale);
|
||||
|
||||
|
||||
const int day_tab[2][13] =
|
||||
@ -266,7 +266,7 @@ static const datetkn *deltacache[MAXDATEFIELDS] = {NULL};
|
||||
static int
|
||||
strtoi(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
long val;
|
||||
long val;
|
||||
|
||||
val = strtol(nptr, endptr, base);
|
||||
#ifdef HAVE_LONG_INT_64
|
||||
@ -461,8 +461,8 @@ static void
|
||||
AppendTimestampSeconds(char *cp, struct pg_tm * tm, fsec_t fsec)
|
||||
{
|
||||
/*
|
||||
* In float mode, don't print fractional seconds before 1 AD,
|
||||
* since it's unlikely there's any precision left ...
|
||||
* In float mode, don't print fractional seconds before 1 AD, since it's
|
||||
* unlikely there's any precision left ...
|
||||
*/
|
||||
#ifndef HAVE_INT64_TIMESTAMP
|
||||
if (tm->tm_year <= 0)
|
||||
@ -478,18 +478,18 @@ AppendTimestampSeconds(char *cp, struct pg_tm * tm, fsec_t fsec)
|
||||
static void
|
||||
AdjustFractSeconds(double frac, struct pg_tm * tm, fsec_t *fsec, int scale)
|
||||
{
|
||||
int sec;
|
||||
int sec;
|
||||
|
||||
if (frac == 0)
|
||||
return;
|
||||
frac *= scale;
|
||||
sec = (int) frac;
|
||||
frac *= scale;
|
||||
sec = (int) frac;
|
||||
tm->tm_sec += sec;
|
||||
frac -= sec;
|
||||
frac -= sec;
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
*fsec += rint(frac * 1000000);
|
||||
*fsec += rint(frac * 1000000);
|
||||
#else
|
||||
*fsec += frac;
|
||||
*fsec += frac;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -497,14 +497,14 @@ AdjustFractSeconds(double frac, struct pg_tm * tm, fsec_t *fsec, int scale)
|
||||
static void
|
||||
AdjustFractDays(double frac, struct pg_tm * tm, fsec_t *fsec, int scale)
|
||||
{
|
||||
int extra_days;
|
||||
int extra_days;
|
||||
|
||||
if (frac == 0)
|
||||
return;
|
||||
frac *= scale;
|
||||
extra_days = (int) frac;
|
||||
frac *= scale;
|
||||
extra_days = (int) frac;
|
||||
tm->tm_mday += extra_days;
|
||||
frac -= extra_days;
|
||||
frac -= extra_days;
|
||||
AdjustFractSeconds(frac, tm, fsec, SECS_PER_DAY);
|
||||
}
|
||||
|
||||
@ -1358,7 +1358,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
|
||||
if (tmask & fmask)
|
||||
return DTERR_BAD_FORMAT;
|
||||
fmask |= tmask;
|
||||
} /* end loop over fields */
|
||||
} /* end loop over fields */
|
||||
|
||||
/* do final checking/adjustment of Y/M/D fields */
|
||||
dterr = ValidateDate(fmask, is2digits, bc, tm);
|
||||
@ -2042,7 +2042,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
|
||||
if (tmask & fmask)
|
||||
return DTERR_BAD_FORMAT;
|
||||
fmask |= tmask;
|
||||
} /* end loop over fields */
|
||||
} /* end loop over fields */
|
||||
|
||||
/* do final checking/adjustment of Y/M/D fields */
|
||||
dterr = ValidateDate(fmask, is2digits, bc, tm);
|
||||
@ -2059,7 +2059,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
|
||||
|
||||
if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_min > 59 ||
|
||||
tm->tm_sec < 0 || tm->tm_sec > 60 || tm->tm_hour > 24 ||
|
||||
/* test for > 24:00:00 */
|
||||
/* test for > 24:00:00 */
|
||||
(tm->tm_hour == 24 &&
|
||||
(tm->tm_min > 0 || tm->tm_sec > 0 || *fsec > 0)) ||
|
||||
#ifdef HAVE_INT64_TIMESTAMP
|
||||
@ -2262,7 +2262,7 @@ ValidateDate(int fmask, bool is2digits, bool bc, struct pg_tm * tm)
|
||||
else if (is2digits)
|
||||
{
|
||||
/* process 1 or 2-digit input as 1970-2069 AD, allow '0' and '00' */
|
||||
if (tm->tm_year < 0) /* just paranoia */
|
||||
if (tm->tm_year < 0) /* just paranoia */
|
||||
return DTERR_FIELD_OVERFLOW;
|
||||
if (tm->tm_year < 70)
|
||||
tm->tm_year += 2000;
|
||||
@ -2599,8 +2599,8 @@ DecodeNumberField(int len, char *str, int fmask,
|
||||
if ((cp = strchr(str, '.')) != NULL)
|
||||
{
|
||||
/*
|
||||
* Can we use ParseFractionalSecond here? Not clear whether
|
||||
* trailing junk should be rejected ...
|
||||
* Can we use ParseFractionalSecond here? Not clear whether trailing
|
||||
* junk should be rejected ...
|
||||
*/
|
||||
double frac;
|
||||
|
||||
@ -2805,16 +2805,16 @@ DecodeSpecial(int field, char *lowtoken, int *val)
|
||||
*
|
||||
* Zero out a pg_tm and associated fsec_t
|
||||
*/
|
||||
static inline void
|
||||
ClearPgTm(struct pg_tm *tm, fsec_t *fsec)
|
||||
static inline void
|
||||
ClearPgTm(struct pg_tm * tm, fsec_t *fsec)
|
||||
{
|
||||
tm->tm_year = 0;
|
||||
tm->tm_mon = 0;
|
||||
tm->tm_mon = 0;
|
||||
tm->tm_mday = 0;
|
||||
tm->tm_hour = 0;
|
||||
tm->tm_min = 0;
|
||||
tm->tm_sec = 0;
|
||||
*fsec = 0;
|
||||
tm->tm_min = 0;
|
||||
tm->tm_sec = 0;
|
||||
*fsec = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -2845,7 +2845,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
|
||||
*dtype = DTK_DELTA;
|
||||
type = IGNORE_DTF;
|
||||
ClearPgTm(tm,fsec);
|
||||
ClearPgTm(tm, fsec);
|
||||
|
||||
/* read through list backwards to pick up units before values */
|
||||
for (i = nf - 1; i >= 0; i--)
|
||||
@ -2863,16 +2863,16 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
case DTK_TZ:
|
||||
|
||||
/*
|
||||
* Timezone is a token with a leading sign character and
|
||||
* at least one digit; there could be ':', '.', '-'
|
||||
* embedded in it as well.
|
||||
* Timezone is a token with a leading sign character and at
|
||||
* least one digit; there could be ':', '.', '-' embedded in
|
||||
* it as well.
|
||||
*/
|
||||
Assert(*field[i] == '-' || *field[i] == '+');
|
||||
|
||||
/*
|
||||
* Try for hh:mm or hh:mm:ss. If not, fall through to
|
||||
* DTK_NUMBER case, which can handle signed float numbers
|
||||
* and signed year-month values.
|
||||
* DTK_NUMBER case, which can handle signed float numbers and
|
||||
* signed year-month values.
|
||||
*/
|
||||
if (strchr(field[i] + 1, ':') != NULL &&
|
||||
DecodeTime(field[i] + 1, fmask, INTERVAL_FULL_RANGE,
|
||||
@ -2944,7 +2944,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
if (*cp == '-')
|
||||
{
|
||||
/* SQL "years-months" syntax */
|
||||
int val2;
|
||||
int val2;
|
||||
|
||||
val2 = strtoi(cp + 1, &cp, 10);
|
||||
if (errno == ERANGE || val2 < 0 || val2 >= MONTHS_PER_YEAR)
|
||||
@ -3022,7 +3022,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
tm->tm_hour += val;
|
||||
AdjustFractSeconds(fval, tm, fsec, SECS_PER_HOUR);
|
||||
tmask = DTK_M(HOUR);
|
||||
type = DTK_DAY; /* set for next field */
|
||||
type = DTK_DAY; /* set for next field */
|
||||
break;
|
||||
|
||||
case DTK_DAY:
|
||||
@ -3133,7 +3133,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
|
||||
/*----------
|
||||
* The SQL standard defines the interval literal
|
||||
* '-1 1:00:00'
|
||||
* '-1 1:00:00'
|
||||
* to mean "negative 1 days and negative 1 hours", while Postgres
|
||||
* traditionally treats this as meaning "negative 1 days and positive
|
||||
* 1 hours". In SQL_STANDARD intervalstyle, we apply the leading sign
|
||||
@ -3143,14 +3143,14 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
* This protects us against misinterpreting postgres-style dump output,
|
||||
* since the postgres-style output code has always put an explicit sign on
|
||||
* all fields following a negative field. But note that SQL-spec output
|
||||
* is ambiguous and can be misinterpreted on load! (So it's best practice
|
||||
* is ambiguous and can be misinterpreted on load! (So it's best practice
|
||||
* to dump in postgres style, not SQL style.)
|
||||
*----------
|
||||
*/
|
||||
if (IntervalStyle == INTSTYLE_SQL_STANDARD && *field[0] == '-')
|
||||
{
|
||||
/* Check for additional explicit signs */
|
||||
bool more_signs = false;
|
||||
bool more_signs = false;
|
||||
|
||||
for (i = 1; i < nf; i++)
|
||||
{
|
||||
@ -3164,8 +3164,8 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
|
||||
if (!more_signs)
|
||||
{
|
||||
/*
|
||||
* Rather than re-determining which field was field[0], just
|
||||
* force 'em all negative.
|
||||
* Rather than re-determining which field was field[0], just force
|
||||
* 'em all negative.
|
||||
*/
|
||||
if (*fsec > 0)
|
||||
*fsec = -(*fsec);
|
||||
@ -3245,28 +3245,28 @@ ISO8601IntegerWidth(char *fieldstart)
|
||||
|
||||
|
||||
/* DecodeISO8601Interval()
|
||||
* Decode an ISO 8601 time interval of the "format with designators"
|
||||
* (section 4.4.3.2) or "alternative format" (section 4.4.3.3)
|
||||
* Examples: P1D for 1 day
|
||||
* PT1H for 1 hour
|
||||
* P2Y6M7DT1H30M for 2 years, 6 months, 7 days 1 hour 30 min
|
||||
* P0002-06-07T01:30:00 the same value in alternative format
|
||||
* Decode an ISO 8601 time interval of the "format with designators"
|
||||
* (section 4.4.3.2) or "alternative format" (section 4.4.3.3)
|
||||
* Examples: P1D for 1 day
|
||||
* PT1H for 1 hour
|
||||
* P2Y6M7DT1H30M for 2 years, 6 months, 7 days 1 hour 30 min
|
||||
* P0002-06-07T01:30:00 the same value in alternative format
|
||||
*
|
||||
* Returns 0 if successful, DTERR code if bogus input detected.
|
||||
* Note: error code should be DTERR_BAD_FORMAT if input doesn't look like
|
||||
* ISO8601, otherwise this could cause unexpected error messages.
|
||||
* dtype, tm, fsec are output parameters.
|
||||
*
|
||||
* A couple exceptions from the spec:
|
||||
* - a week field ('W') may coexist with other units
|
||||
* - allows decimals in fields other than the least significant unit.
|
||||
* A couple exceptions from the spec:
|
||||
* - a week field ('W') may coexist with other units
|
||||
* - allows decimals in fields other than the least significant unit.
|
||||
*/
|
||||
int
|
||||
DecodeISO8601Interval(char *str,
|
||||
int *dtype, struct pg_tm * tm, fsec_t *fsec)
|
||||
{
|
||||
bool datepart = true;
|
||||
bool havefield = false;
|
||||
bool datepart = true;
|
||||
bool havefield = false;
|
||||
|
||||
*dtype = DTK_DELTA;
|
||||
ClearPgTm(tm, fsec);
|
||||
@ -3277,13 +3277,13 @@ DecodeISO8601Interval(char *str,
|
||||
str++;
|
||||
while (*str)
|
||||
{
|
||||
char *fieldstart;
|
||||
int val;
|
||||
double fval;
|
||||
char unit;
|
||||
int dterr;
|
||||
char *fieldstart;
|
||||
int val;
|
||||
double fval;
|
||||
char unit;
|
||||
int dterr;
|
||||
|
||||
if (*str == 'T') /* T indicates the beginning of the time part */
|
||||
if (*str == 'T') /* T indicates the beginning of the time part */
|
||||
{
|
||||
datepart = false;
|
||||
havefield = false;
|
||||
@ -3297,14 +3297,14 @@ DecodeISO8601Interval(char *str,
|
||||
return dterr;
|
||||
|
||||
/*
|
||||
* Note: we could step off the end of the string here. Code below
|
||||
* Note: we could step off the end of the string here. Code below
|
||||
* *must* exit the loop if unit == '\0'.
|
||||
*/
|
||||
unit = *str++;
|
||||
|
||||
if (datepart)
|
||||
{
|
||||
switch (unit) /* before T: Y M W D */
|
||||
switch (unit) /* before T: Y M W D */
|
||||
{
|
||||
case 'Y':
|
||||
tm->tm_year += val;
|
||||
@ -3322,12 +3322,12 @@ DecodeISO8601Interval(char *str,
|
||||
tm->tm_mday += val;
|
||||
AdjustFractSeconds(fval, tm, fsec, SECS_PER_DAY);
|
||||
break;
|
||||
case 'T': /* ISO 8601 4.4.3.3 Alternative Format / Basic */
|
||||
case 'T': /* ISO 8601 4.4.3.3 Alternative Format / Basic */
|
||||
case '\0':
|
||||
if (ISO8601IntegerWidth(fieldstart) == 8 && !havefield)
|
||||
{
|
||||
tm->tm_year += val / 10000;
|
||||
tm->tm_mon += (val / 100) % 100;
|
||||
tm->tm_mon += (val / 100) % 100;
|
||||
tm->tm_mday += val % 100;
|
||||
AdjustFractSeconds(fval, tm, fsec, SECS_PER_DAY);
|
||||
if (unit == '\0')
|
||||
@ -3337,12 +3337,13 @@ DecodeISO8601Interval(char *str,
|
||||
continue;
|
||||
}
|
||||
/* Else fall through to extended alternative format */
|
||||
case '-': /* ISO 8601 4.4.3.3 Alternative Format, Extended */
|
||||
case '-': /* ISO 8601 4.4.3.3 Alternative Format,
|
||||
* Extended */
|
||||
if (havefield)
|
||||
return DTERR_BAD_FORMAT;
|
||||
|
||||
tm->tm_year += val;
|
||||
tm->tm_mon += (fval * 12);
|
||||
tm->tm_mon += (fval * 12);
|
||||
if (unit == '\0')
|
||||
return 0;
|
||||
if (unit == 'T')
|
||||
@ -3355,7 +3356,7 @@ DecodeISO8601Interval(char *str,
|
||||
dterr = ParseISO8601Number(str, &str, &val, &fval);
|
||||
if (dterr)
|
||||
return dterr;
|
||||
tm->tm_mon += val;
|
||||
tm->tm_mon += val;
|
||||
AdjustFractDays(fval, tm, fsec, DAYS_PER_MONTH);
|
||||
if (*str == '\0')
|
||||
return 0;
|
||||
@ -3368,7 +3369,7 @@ DecodeISO8601Interval(char *str,
|
||||
if (*str != '-')
|
||||
return DTERR_BAD_FORMAT;
|
||||
str++;
|
||||
|
||||
|
||||
dterr = ParseISO8601Number(str, &str, &val, &fval);
|
||||
if (dterr)
|
||||
return dterr;
|
||||
@ -3390,7 +3391,7 @@ DecodeISO8601Interval(char *str,
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (unit) /* after T: H M S */
|
||||
switch (unit) /* after T: H M S */
|
||||
{
|
||||
case 'H':
|
||||
tm->tm_hour += val;
|
||||
@ -3404,17 +3405,18 @@ DecodeISO8601Interval(char *str,
|
||||
tm->tm_sec += val;
|
||||
AdjustFractSeconds(fval, tm, fsec, 1);
|
||||
break;
|
||||
case '\0': /* ISO 8601 4.4.3.3 Alternative Format */
|
||||
if (ISO8601IntegerWidth(fieldstart) == 6 && !havefield)
|
||||
case '\0': /* ISO 8601 4.4.3.3 Alternative Format */
|
||||
if (ISO8601IntegerWidth(fieldstart) == 6 && !havefield)
|
||||
{
|
||||
tm->tm_hour += val / 10000;
|
||||
tm->tm_min += (val / 100) % 100;
|
||||
tm->tm_sec += val % 100;
|
||||
tm->tm_min += (val / 100) % 100;
|
||||
tm->tm_sec += val % 100;
|
||||
AdjustFractSeconds(fval, tm, fsec, 1);
|
||||
return 0;
|
||||
}
|
||||
/* Else fall through to extended alternative format */
|
||||
case ':': /* ISO 8601 4.4.3.3 Alternative Format, Extended */
|
||||
case ':': /* ISO 8601 4.4.3.3 Alternative Format,
|
||||
* Extended */
|
||||
if (havefield)
|
||||
return DTERR_BAD_FORMAT;
|
||||
|
||||
@ -3422,22 +3424,22 @@ DecodeISO8601Interval(char *str,
|
||||
AdjustFractSeconds(fval, tm, fsec, SECS_PER_HOUR);
|
||||
if (unit == '\0')
|
||||
return 0;
|
||||
|
||||
|
||||
dterr = ParseISO8601Number(str, &str, &val, &fval);
|
||||
if (dterr)
|
||||
return dterr;
|
||||
tm->tm_min += val;
|
||||
tm->tm_min += val;
|
||||
AdjustFractSeconds(fval, tm, fsec, SECS_PER_MINUTE);
|
||||
if (*str == '\0')
|
||||
return 0;
|
||||
if (*str != ':')
|
||||
return DTERR_BAD_FORMAT;
|
||||
str++;
|
||||
|
||||
|
||||
dterr = ParseISO8601Number(str, &str, &val, &fval);
|
||||
if (dterr)
|
||||
return dterr;
|
||||
tm->tm_sec += val;
|
||||
tm->tm_sec += val;
|
||||
AdjustFractSeconds(fval, tm, fsec, 1);
|
||||
if (*str == '\0')
|
||||
return 0;
|
||||
@ -3843,9 +3845,10 @@ AddPostgresIntPart(char *cp, int value, const char *units,
|
||||
value,
|
||||
units,
|
||||
(value != 1) ? "s" : "");
|
||||
|
||||
/*
|
||||
* Each nonzero field sets is_before for (only) the next one. This is
|
||||
* a tad bizarre but it's how it worked before...
|
||||
* Each nonzero field sets is_before for (only) the next one. This is a
|
||||
* tad bizarre but it's how it worked before...
|
||||
*/
|
||||
*is_before = (value < 0);
|
||||
*is_zero = FALSE;
|
||||
@ -3884,7 +3887,7 @@ AddVerboseIntPart(char *cp, int value, const char *units,
|
||||
* Actually, afaik, ISO 8601 does specify formats for "time
|
||||
* intervals...[of the]...format with time-unit designators", which
|
||||
* are pretty ugly. The format looks something like
|
||||
* P1Y1M1DT1H1M1.12345S
|
||||
* P1Y1M1DT1H1M1.12345S
|
||||
* but useful for exchanging data with computers instead of humans.
|
||||
* - ron 2003-07-14
|
||||
*
|
||||
@ -3897,11 +3900,11 @@ EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
|
||||
{
|
||||
char *cp = str;
|
||||
int year = tm->tm_year;
|
||||
int mon = tm->tm_mon;
|
||||
int mon = tm->tm_mon;
|
||||
int mday = tm->tm_mday;
|
||||
int hour = tm->tm_hour;
|
||||
int min = tm->tm_min;
|
||||
int sec = tm->tm_sec;
|
||||
int min = tm->tm_min;
|
||||
int sec = tm->tm_sec;
|
||||
bool is_before = FALSE;
|
||||
bool is_zero = TRUE;
|
||||
|
||||
@ -3913,21 +3916,21 @@ EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
|
||||
*/
|
||||
switch (style)
|
||||
{
|
||||
/* SQL Standard interval format */
|
||||
/* SQL Standard interval format */
|
||||
case INTSTYLE_SQL_STANDARD:
|
||||
{
|
||||
bool has_negative = year < 0 || mon < 0 ||
|
||||
mday < 0 || hour < 0 ||
|
||||
min < 0 || sec < 0 || fsec < 0;
|
||||
bool has_positive = year > 0 || mon > 0 ||
|
||||
mday > 0 || hour > 0 ||
|
||||
min > 0 || sec > 0 || fsec > 0;
|
||||
bool has_year_month = year != 0 || mon != 0;
|
||||
bool has_day_time = mday != 0 || hour != 0 ||
|
||||
min != 0 || sec != 0 || fsec != 0;
|
||||
bool has_day = mday != 0;
|
||||
bool sql_standard_value = !(has_negative && has_positive) &&
|
||||
!(has_year_month && has_day_time);
|
||||
bool has_negative = year < 0 || mon < 0 ||
|
||||
mday < 0 || hour < 0 ||
|
||||
min < 0 || sec < 0 || fsec < 0;
|
||||
bool has_positive = year > 0 || mon > 0 ||
|
||||
mday > 0 || hour > 0 ||
|
||||
min > 0 || sec > 0 || fsec > 0;
|
||||
bool has_year_month = year != 0 || mon != 0;
|
||||
bool has_day_time = mday != 0 || hour != 0 ||
|
||||
min != 0 || sec != 0 || fsec != 0;
|
||||
bool has_day = mday != 0;
|
||||
bool sql_standard_value = !(has_negative && has_positive) &&
|
||||
!(has_year_month && has_day_time);
|
||||
|
||||
/*
|
||||
* SQL Standard wants only 1 "<sign>" preceding the whole
|
||||
@ -3937,11 +3940,11 @@ EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
|
||||
{
|
||||
*cp++ = '-';
|
||||
year = -year;
|
||||
mon = -mon;
|
||||
mon = -mon;
|
||||
mday = -mday;
|
||||
hour = -hour;
|
||||
min = -min;
|
||||
sec = -sec;
|
||||
min = -min;
|
||||
sec = -sec;
|
||||
fsec = -fsec;
|
||||
}
|
||||
|
||||
@ -3952,15 +3955,14 @@ EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
|
||||
else if (!sql_standard_value)
|
||||
{
|
||||
/*
|
||||
* For non sql-standard interval values,
|
||||
* force outputting the signs to avoid
|
||||
* ambiguities with intervals with mixed
|
||||
* sign components.
|
||||
* For non sql-standard interval values, force outputting
|
||||
* the signs to avoid ambiguities with intervals with
|
||||
* mixed sign components.
|
||||
*/
|
||||
char year_sign = (year < 0 || mon < 0) ? '-' : '+';
|
||||
char day_sign = (mday < 0) ? '-' : '+';
|
||||
char sec_sign = (hour < 0 || min < 0 ||
|
||||
sec < 0 || fsec < 0) ? '-' : '+';
|
||||
char year_sign = (year < 0 || mon < 0) ? '-' : '+';
|
||||
char day_sign = (mday < 0) ? '-' : '+';
|
||||
char sec_sign = (hour < 0 || min < 0 ||
|
||||
sec < 0 || fsec < 0) ? '-' : '+';
|
||||
|
||||
sprintf(cp, "%c%d-%d %c%d %c%d:%02d:",
|
||||
year_sign, abs(year), abs(mon),
|
||||
@ -3988,23 +3990,23 @@ EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
|
||||
}
|
||||
break;
|
||||
|
||||
/* ISO 8601 "time-intervals by duration only" */
|
||||
/* ISO 8601 "time-intervals by duration only" */
|
||||
case INTSTYLE_ISO_8601:
|
||||
/* special-case zero to avoid printing nothing */
|
||||
if (year == 0 && mon == 0 && mday == 0 &&
|
||||
hour == 0 && min == 0 && sec == 0 && fsec == 0)
|
||||
hour == 0 && min == 0 && sec == 0 && fsec == 0)
|
||||
{
|
||||
sprintf(cp, "PT0S");
|
||||
break;
|
||||
}
|
||||
*cp++ = 'P';
|
||||
cp = AddISO8601IntPart(cp, year, 'Y');
|
||||
cp = AddISO8601IntPart(cp, mon , 'M');
|
||||
cp = AddISO8601IntPart(cp, mon, 'M');
|
||||
cp = AddISO8601IntPart(cp, mday, 'D');
|
||||
if (hour != 0 || min != 0 || sec != 0 || fsec != 0)
|
||||
*cp++ = 'T';
|
||||
cp = AddISO8601IntPart(cp, hour, 'H');
|
||||
cp = AddISO8601IntPart(cp, min , 'M');
|
||||
cp = AddISO8601IntPart(cp, min, 'M');
|
||||
if (sec != 0 || fsec != 0)
|
||||
{
|
||||
if (sec < 0 || fsec < 0)
|
||||
@ -4016,14 +4018,14 @@ EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
|
||||
}
|
||||
break;
|
||||
|
||||
/* Compatible with postgresql < 8.4 when DateStyle = 'iso' */
|
||||
/* Compatible with postgresql < 8.4 when DateStyle = 'iso' */
|
||||
case INTSTYLE_POSTGRES:
|
||||
cp = AddPostgresIntPart(cp, year, "year", &is_zero, &is_before);
|
||||
cp = AddPostgresIntPart(cp, mon, "mon", &is_zero, &is_before);
|
||||
cp = AddPostgresIntPart(cp, mday, "day", &is_zero, &is_before);
|
||||
if (is_zero || hour != 0 || min != 0 || sec != 0 || fsec != 0)
|
||||
{
|
||||
bool minus = (hour < 0 || min < 0 || sec < 0 || fsec < 0);
|
||||
bool minus = (hour < 0 || min < 0 || sec < 0 || fsec < 0);
|
||||
|
||||
sprintf(cp, "%s%s%02d:%02d:",
|
||||
is_zero ? "" : " ",
|
||||
@ -4034,7 +4036,7 @@ EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str)
|
||||
}
|
||||
break;
|
||||
|
||||
/* Compatible with postgresql < 8.4 when DateStyle != 'iso' */
|
||||
/* Compatible with postgresql < 8.4 when DateStyle != 'iso' */
|
||||
case INTSTYLE_POSTGRES_VERBOSE:
|
||||
default:
|
||||
strcpy(cp, "@");
|
||||
|
Reference in New Issue
Block a user