aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/formatting.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-03-17 15:50:33 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2016-03-17 15:50:33 -0400
commit55c3a04d60ccea9e999088fb847ceeb9fd4dd927 (patch)
treebbbda6881db544b302da004324a8254b516fa95a /src/backend/utils/adt/formatting.c
parentf4ceed6ceba31a72ed7a726fef05d211641f283c (diff)
downloadpostgresql-55c3a04d60ccea9e999088fb847ceeb9fd4dd927.tar.gz
postgresql-55c3a04d60ccea9e999088fb847ceeb9fd4dd927.zip
Fix assorted breakage in to_char()'s OF format option.
In HEAD, fix incorrect field width for hours part of OF when tm_gmtoff is negative. This was introduced by commit 2d87eedc1d4468d3 as a result of falsely applying a pattern that's correct when + signs are omitted, which is not the case for OF. In 9.4, fix missing abs() call that allowed a sign to be attached to the minutes part of OF. This was fixed in 9.5 by 9b43d73b3f9bef27, but for inscrutable reasons not back-patched. In all three versions, ensure that the sign of tm_gmtoff is correctly reported even when the GMT offset is less than 1 hour. Add regression tests, which evidently we desperately need here. Thomas Munro and Tom Lane, per report from David Fetter
Diffstat (limited to 'src/backend/utils/adt/formatting.c')
-rw-r--r--src/backend/utils/adt/formatting.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 2b5622a9ee0..c90f48d00a6 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -2506,12 +2506,15 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
break;
case DCH_OF:
INVALID_FOR_INTERVAL;
- sprintf(s, "%+0*d", S_FM(n->suffix) ? 0 : (tm->tm_gmtoff >= 0) ? 3 : 4,
- (int) tm->tm_gmtoff / SECS_PER_HOUR);
+ sprintf(s, "%c%0*d",
+ (tm->tm_gmtoff >= 0) ? '+' : '-',
+ S_FM(n->suffix) ? 0 : 2,
+ abs((int) tm->tm_gmtoff) / SECS_PER_HOUR);
s += strlen(s);
- if ((int) tm->tm_gmtoff % SECS_PER_HOUR != 0)
+ if (abs((int) tm->tm_gmtoff) % SECS_PER_HOUR != 0)
{
- sprintf(s, ":%02d", abs((int) tm->tm_gmtoff % SECS_PER_HOUR) / SECS_PER_MINUTE);
+ sprintf(s, ":%02d",
+ (abs((int) tm->tm_gmtoff) % SECS_PER_HOUR) / SECS_PER_MINUTE);
s += strlen(s);
}
break;