Skip to content

Commit eae5184

Browse files
committed
Hi,
the to_char() source code is large, here are regression tests for numeric/timestamp/int8 part. It is probably enough test for formatting code in the formatting.c module. The others (float4/float8/int4) types share this formatting code and eventual bugs for these types aren't few probable. Patch fix timestamp_to_char() for infinity/invalid timestamp too. Karel
1 parent 0c54229 commit eae5184

File tree

7 files changed

+1344
-15
lines changed

7 files changed

+1344
-15
lines changed

src/backend/utils/adt/formatting.c

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* -----------------------------------------------------------------------
22
* formatting.c
33
*
4-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.4 2000/02/16 17:24:48 thomas Exp $
4+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.5 2000/03/08 01:34:36 momjian Exp $
55
*
66
*
77
* Portions Copyright (c) 1999-2000, PostgreSQL, Inc
@@ -630,7 +630,7 @@ static FormatNode *NUM_cache( int len, char *CacheStr, FormatNode *CacheFormat,
630630
static char *int_to_roman(int number);
631631
static void NUM_prepare_locale(NUMProc *Np);
632632
static char *get_last_relevant_decnum(char *num);
633-
static void NUM_numpart_from_char(NUMProc *Np, int id);
633+
static void NUM_numpart_from_char(NUMProc *Np, int id, int plen);
634634
static void NUM_numpart_to_char(NUMProc *Np, int id);
635635
static char *NUM_processor (FormatNode *node, NUMDesc *Num, char *inout, char *number,
636636
int plen, int sign, int type);
@@ -1798,14 +1798,14 @@ timestamp_to_char(Timestamp *dt, text *fmt)
17981798
char *str;
17991799
double fsec;
18001800
char *tzn;
1801-
int len=0, tz;
1801+
int len=0, tz, x=0;
18021802

18031803
if ((!PointerIsValid(dt)) || (!PointerIsValid(fmt)))
18041804
return NULL;
18051805

18061806
len = VARSIZE(fmt) - VARHDRSZ;
18071807

1808-
if (!len)
1808+
if ((!len) || (TIMESTAMP_NOT_FINITE(*dt)))
18091809
return textin("");
18101810

18111811
tm->tm_sec =0; tm->tm_year =0;
@@ -1814,16 +1814,19 @@ timestamp_to_char(Timestamp *dt, text *fmt)
18141814
tm->tm_mday =1; tm->tm_isdst =0;
18151815
tm->tm_mon =1;
18161816

1817-
if (TIMESTAMP_IS_EPOCH(*dt))
1818-
{
1819-
timestamp2tm(SetTimestamp(*dt), NULL, tm, &fsec, NULL);
1817+
if (TIMESTAMP_IS_EPOCH(*dt)) {
1818+
x = timestamp2tm(SetTimestamp(*dt), NULL, tm, &fsec, NULL);
1819+
18201820
} else if (TIMESTAMP_IS_CURRENT(*dt)) {
1821-
timestamp2tm(SetTimestamp(*dt), &tz, tm, &fsec, &tzn);
1821+
x = timestamp2tm(SetTimestamp(*dt), &tz, tm, &fsec, &tzn);
1822+
18221823
} else {
1823-
if (timestamp2tm(*dt, &tz, tm, &fsec, &tzn) != 0)
1824-
elog(ERROR, "to_char(): Unable to convert timestamp to tm");
1824+
x = timestamp2tm(*dt, &tz, tm, &fsec, &tzn);
18251825
}
18261826

1827+
if (x!=0)
1828+
elog(ERROR, "to_char(): Unable to convert timestamp to tm");
1829+
18271830
tm->tm_wday = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + 1) % 7;
18281831
tm->tm_yday = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(tm->tm_year, 1,1) +1;
18291832

@@ -2330,7 +2333,7 @@ get_last_relevant_decnum(char *num)
23302333
char *result,
23312334
*p = strchr(num, '.');
23322335

2333-
elog(NOTICE, "CALL: get_last_relevant_decnum()");
2336+
/*elog(NOTICE, "CALL: get_last_relevant_decnum()");*/
23342337

23352338
if (!p)
23362339
p = num;
@@ -2349,16 +2352,21 @@ get_last_relevant_decnum(char *num)
23492352
* ----------
23502353
*/
23512354
static void
2352-
NUM_numpart_from_char(NUMProc *Np, int id)
2355+
NUM_numpart_from_char(NUMProc *Np, int id, int plen)
23532356
{
23542357

23552358
#ifdef DEBUG_TO_FROM_CHAR
23562359
elog(DEBUG_elog_output, " --- scan start --- ");
23572360
#endif
23582361

2362+
#define OVERLOAD_TEST (Np->inout_p >= Np->inout + plen)
2363+
23592364
if (*Np->inout_p == ' ')
23602365
Np->inout_p++;
23612366

2367+
if (OVERLOAD_TEST)
2368+
return;
2369+
23622370
/* ----------
23632371
* read sign
23642372
* ----------
@@ -2413,6 +2421,9 @@ NUM_numpart_from_char(NUMProc *Np, int id)
24132421
}
24142422
}
24152423

2424+
if (OVERLOAD_TEST)
2425+
return;
2426+
24162427
/* ----------
24172428
* read digit
24182429
* ----------
@@ -2430,7 +2441,7 @@ NUM_numpart_from_char(NUMProc *Np, int id)
24302441

24312442
#ifdef DEBUG_TO_FROM_CHAR
24322443
elog(DEBUG_elog_output, "Read digit (%c).", *Np->inout_p);
2433-
#endif
2444+
#endif
24342445

24352446
/* ----------
24362447
* read decimal point
@@ -2821,7 +2832,7 @@ NUM_processor (FormatNode *node, NUMDesc *Num, char *inout, char *number,
28212832
* Check non-string inout end
28222833
* ----------
28232834
*/
2824-
if (Np->inout_p == Np->inout + plen)
2835+
if (Np->inout_p >= Np->inout + plen)
28252836
break;
28262837
}
28272838

@@ -2847,7 +2858,7 @@ NUM_processor (FormatNode *node, NUMDesc *Num, char *inout, char *number,
28472858
NUM_numpart_to_char(Np, n->key->id);
28482859
continue; /* for() */
28492860
} else {
2850-
NUM_numpart_from_char(Np, n->key->id);
2861+
NUM_numpart_from_char(Np, n->key->id, plen);
28512862
break; /* switch() case: */
28522863
}
28532864

src/test/regress/expected/int8.out

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,179 @@ SELECT '' AS five, q1 * 2 AS "twice int4" FROM INT8_TBL;
117117
| 9135780246913578
118118
(5 rows)
119119

120+
-- TO_CHAR()
121+
--
122+
SELECT '' AS to_char_1, to_char(q1, '9G999G999G999G999G999'), to_char(q2, '9,999,999,999,999,999')
123+
FROM INT8_TBL;
124+
to_char_1 | to_char | to_char
125+
-----------+------------------------+------------------------
126+
| 123 | 456
127+
| 123 | 4,567,890,123,456,789
128+
| 4,567,890,123,456,789 | 123
129+
| 4,567,890,123,456,789 | 4,567,890,123,456,789
130+
| 4,567,890,123,456,789 | -4,567,890,123,456,789
131+
(5 rows)
132+
133+
SELECT '' AS to_char_2, to_char(q1, '9G999G999G999G999G999D999G999'), to_char(q2, '9,999,999,999,999,999.999,999')
134+
FROM INT8_TBL;
135+
to_char_2 | to_char | to_char
136+
-----------+--------------------------------+--------------------------------
137+
| 123.000,000 | 456.000,000
138+
| 123.000,000 | 4,567,890,123,456,789.000,000
139+
| 4,567,890,123,456,789.000,000 | 123.000,000
140+
| 4,567,890,123,456,789.000,000 | 4,567,890,123,456,789.000,000
141+
| 4,567,890,123,456,789.000,000 | -4,567,890,123,456,789.000,000
142+
(5 rows)
143+
144+
SELECT '' AS to_char_3, to_char( (q1 * -1), '9999999999999999PR'), to_char( (q2 * -1), '9999999999999999.999PR')
145+
FROM INT8_TBL;
146+
to_char_3 | to_char | to_char
147+
-----------+--------------------+------------------------
148+
| <123> | <456.000>
149+
| <123> | <4567890123456789.000>
150+
| <4567890123456789> | <123.000>
151+
| <4567890123456789> | <4567890123456789.000>
152+
| <4567890123456789> | 4567890123456789.000
153+
(5 rows)
154+
155+
SELECT '' AS to_char_4, to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 * -1), 'S9999999999999999')
156+
FROM INT8_TBL;
157+
to_char_4 | to_char | to_char
158+
-----------+-------------------+-------------------
159+
| 123- | -456
160+
| 123- | -4567890123456789
161+
| 4567890123456789- | -123
162+
| 4567890123456789- | -4567890123456789
163+
| 4567890123456789- | +4567890123456789
164+
(5 rows)
165+
166+
SELECT '' AS to_char_5, to_char(q2, 'MI9999999999999999') FROM INT8_TBL;
167+
to_char_5 | to_char
168+
-----------+--------------------
169+
| 456
170+
| 4567890123456789
171+
| 123
172+
| 4567890123456789
173+
| -4567890123456789
174+
(5 rows)
175+
176+
SELECT '' AS to_char_6, to_char(q2, 'FMS9999999999999999') FROM INT8_TBL;
177+
to_char_6 | to_char
178+
-----------+-------------------
179+
| +456
180+
| +4567890123456789
181+
| +123
182+
| +4567890123456789
183+
| -4567890123456789
184+
(5 rows)
185+
186+
SELECT '' AS to_char_7, to_char(q2, 'FM9999999999999999THPR') FROM INT8_TBL;
187+
to_char_7 | to_char
188+
-----------+--------------------
189+
| 456TH
190+
| 4567890123456789TH
191+
| 123RD
192+
| 4567890123456789TH
193+
| <4567890123456789>
194+
(5 rows)
195+
196+
SELECT '' AS to_char_8, to_char(q2, 'SG9999999999999999th') FROM INT8_TBL;
197+
to_char_8 | to_char
198+
-----------+---------------------
199+
| + 456th
200+
| +4567890123456789th
201+
| + 123rd
202+
| +4567890123456789th
203+
| -4567890123456789
204+
(5 rows)
205+
206+
SELECT '' AS to_char_9, to_char(q2, '0999999999999999') FROM INT8_TBL;
207+
to_char_9 | to_char
208+
-----------+-------------------
209+
| 0000000000000456
210+
| 4567890123456789
211+
| 0000000000000123
212+
| 4567890123456789
213+
| -4567890123456789
214+
(5 rows)
215+
216+
SELECT '' AS to_char_10, to_char(q2, 'S0999999999999999') FROM INT8_TBL;
217+
to_char_10 | to_char
218+
------------+-------------------
219+
| +0000000000000456
220+
| +4567890123456789
221+
| +0000000000000123
222+
| +4567890123456789
223+
| -4567890123456789
224+
(5 rows)
225+
226+
SELECT '' AS to_char_11, to_char(q2, 'FM0999999999999999') FROM INT8_TBL;
227+
to_char_11 | to_char
228+
------------+-------------------
229+
| 0000000000000456
230+
| 4567890123456789
231+
| 0000000000000123
232+
| 4567890123456789
233+
| -4567890123456789
234+
(5 rows)
235+
236+
SELECT '' AS to_char_12, to_char(q2, 'FM9999999999999999.000') FROM INT8_TBL;
237+
to_char_12 | to_char
238+
------------+-----------------------
239+
| 456.000
240+
| 4567890123456789.000
241+
| 123.000
242+
| 4567890123456789.000
243+
| -4567890123456789.000
244+
(5 rows)
245+
246+
SELECT '' AS to_char_13, to_char(q2, 'L9999999999999999.000') FROM INT8_TBL;
247+
to_char_13 | to_char
248+
------------+------------------------
249+
| 456.000
250+
| 4567890123456789.000
251+
| 123.000
252+
| 4567890123456789.000
253+
| -4567890123456789.000
254+
(5 rows)
255+
256+
SELECT '' AS to_char_14, to_char(q2, 'FM9999999999999999.999') FROM INT8_TBL;
257+
to_char_14 | to_char
258+
------------+-------------------
259+
| 456
260+
| 4567890123456789
261+
| 123
262+
| 4567890123456789
263+
| -4567890123456789
264+
(5 rows)
265+
266+
SELECT '' AS to_char_15, to_char(q2, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9') FROM INT8_TBL;
267+
to_char_15 | to_char
268+
------------+-------------------------------------------
269+
| +4 5 6 . 0 0 0
270+
| + 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
271+
| +1 2 3 . 0 0 0
272+
| + 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
273+
| - 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
274+
(5 rows)
275+
276+
SELECT '' AS to_char_16, to_char(q2, '99999 text 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL;
277+
to_char_16 | to_char
278+
------------+-----------------------------------------------------------
279+
| text 9999 "text between quote marks" 456
280+
| 45678 text 9012 9999 345 "text between quote marks" 6789
281+
| text 9999 "text between quote marks" 123
282+
| 45678 text 9012 9999 345 "text between quote marks" 6789
283+
| -45678 text 9012 9999 345 "text between quote marks" 6789
284+
(5 rows)
285+
286+
SELECT '' AS to_char_17, to_char(q2, '999999SG9999999999') FROM INT8_TBL;
287+
to_char_17 | to_char
288+
------------+-------------------
289+
| + 456
290+
| 456789+0123456789
291+
| + 123
292+
| 456789+0123456789
293+
| 456789-0123456789
294+
(5 rows)
295+

0 commit comments

Comments
 (0)