Commit eae5184d authored by Bruce Momjian's avatar Bruce Momjian

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
parent 0c542291
/* -----------------------------------------------------------------------
* formatting.c
*
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.4 2000/02/16 17:24:48 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.5 2000/03/08 01:34:36 momjian Exp $
*
*
* Portions Copyright (c) 1999-2000, PostgreSQL, Inc
......@@ -630,7 +630,7 @@ static FormatNode *NUM_cache( int len, char *CacheStr, FormatNode *CacheFormat,
static char *int_to_roman(int number);
static void NUM_prepare_locale(NUMProc *Np);
static char *get_last_relevant_decnum(char *num);
static void NUM_numpart_from_char(NUMProc *Np, int id);
static void NUM_numpart_from_char(NUMProc *Np, int id, int plen);
static void NUM_numpart_to_char(NUMProc *Np, int id);
static char *NUM_processor (FormatNode *node, NUMDesc *Num, char *inout, char *number,
int plen, int sign, int type);
......@@ -1798,14 +1798,14 @@ timestamp_to_char(Timestamp *dt, text *fmt)
char *str;
double fsec;
char *tzn;
int len=0, tz;
int len=0, tz, x=0;
if ((!PointerIsValid(dt)) || (!PointerIsValid(fmt)))
return NULL;
len = VARSIZE(fmt) - VARHDRSZ;
if (!len)
if ((!len) || (TIMESTAMP_NOT_FINITE(*dt)))
return textin("");
tm->tm_sec =0; tm->tm_year =0;
......@@ -1814,16 +1814,19 @@ timestamp_to_char(Timestamp *dt, text *fmt)
tm->tm_mday =1; tm->tm_isdst =0;
tm->tm_mon =1;
if (TIMESTAMP_IS_EPOCH(*dt))
{
timestamp2tm(SetTimestamp(*dt), NULL, tm, &fsec, NULL);
if (TIMESTAMP_IS_EPOCH(*dt)) {
x = timestamp2tm(SetTimestamp(*dt), NULL, tm, &fsec, NULL);
} else if (TIMESTAMP_IS_CURRENT(*dt)) {
timestamp2tm(SetTimestamp(*dt), &tz, tm, &fsec, &tzn);
x = timestamp2tm(SetTimestamp(*dt), &tz, tm, &fsec, &tzn);
} else {
if (timestamp2tm(*dt, &tz, tm, &fsec, &tzn) != 0)
elog(ERROR, "to_char(): Unable to convert timestamp to tm");
x = timestamp2tm(*dt, &tz, tm, &fsec, &tzn);
}
if (x!=0)
elog(ERROR, "to_char(): Unable to convert timestamp to tm");
tm->tm_wday = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + 1) % 7;
tm->tm_yday = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(tm->tm_year, 1,1) +1;
......@@ -2330,7 +2333,7 @@ get_last_relevant_decnum(char *num)
char *result,
*p = strchr(num, '.');
elog(NOTICE, "CALL: get_last_relevant_decnum()");
/*elog(NOTICE, "CALL: get_last_relevant_decnum()");*/
if (!p)
p = num;
......@@ -2349,16 +2352,21 @@ get_last_relevant_decnum(char *num)
* ----------
*/
static void
NUM_numpart_from_char(NUMProc *Np, int id)
NUM_numpart_from_char(NUMProc *Np, int id, int plen)
{
#ifdef DEBUG_TO_FROM_CHAR
elog(DEBUG_elog_output, " --- scan start --- ");
#endif
#define OVERLOAD_TEST (Np->inout_p >= Np->inout + plen)
if (*Np->inout_p == ' ')
Np->inout_p++;
if (OVERLOAD_TEST)
return;
/* ----------
* read sign
* ----------
......@@ -2413,6 +2421,9 @@ NUM_numpart_from_char(NUMProc *Np, int id)
}
}
if (OVERLOAD_TEST)
return;
/* ----------
* read digit
* ----------
......@@ -2430,7 +2441,7 @@ NUM_numpart_from_char(NUMProc *Np, int id)
#ifdef DEBUG_TO_FROM_CHAR
elog(DEBUG_elog_output, "Read digit (%c).", *Np->inout_p);
#endif
#endif
/* ----------
* read decimal point
......@@ -2821,7 +2832,7 @@ NUM_processor (FormatNode *node, NUMDesc *Num, char *inout, char *number,
* Check non-string inout end
* ----------
*/
if (Np->inout_p == Np->inout + plen)
if (Np->inout_p >= Np->inout + plen)
break;
}
......@@ -2847,7 +2858,7 @@ NUM_processor (FormatNode *node, NUMDesc *Num, char *inout, char *number,
NUM_numpart_to_char(Np, n->key->id);
continue; /* for() */
} else {
NUM_numpart_from_char(Np, n->key->id);
NUM_numpart_from_char(Np, n->key->id, plen);
break; /* switch() case: */
}
......
......@@ -117,3 +117,179 @@ SELECT '' AS five, q1 * 2 AS "twice int4" FROM INT8_TBL;
| 9135780246913578
(5 rows)
-- TO_CHAR()
--
SELECT '' AS to_char_1, to_char(q1, '9G999G999G999G999G999'), to_char(q2, '9,999,999,999,999,999')
FROM INT8_TBL;
to_char_1 | to_char | to_char
-----------+------------------------+------------------------
| 123 | 456
| 123 | 4,567,890,123,456,789
| 4,567,890,123,456,789 | 123
| 4,567,890,123,456,789 | 4,567,890,123,456,789
| 4,567,890,123,456,789 | -4,567,890,123,456,789
(5 rows)
SELECT '' AS to_char_2, to_char(q1, '9G999G999G999G999G999D999G999'), to_char(q2, '9,999,999,999,999,999.999,999')
FROM INT8_TBL;
to_char_2 | to_char | to_char
-----------+--------------------------------+--------------------------------
| 123.000,000 | 456.000,000
| 123.000,000 | 4,567,890,123,456,789.000,000
| 4,567,890,123,456,789.000,000 | 123.000,000
| 4,567,890,123,456,789.000,000 | 4,567,890,123,456,789.000,000
| 4,567,890,123,456,789.000,000 | -4,567,890,123,456,789.000,000
(5 rows)
SELECT '' AS to_char_3, to_char( (q1 * -1), '9999999999999999PR'), to_char( (q2 * -1), '9999999999999999.999PR')
FROM INT8_TBL;
to_char_3 | to_char | to_char
-----------+--------------------+------------------------
| <123> | <456.000>
| <123> | <4567890123456789.000>
| <4567890123456789> | <123.000>
| <4567890123456789> | <4567890123456789.000>
| <4567890123456789> | 4567890123456789.000
(5 rows)
SELECT '' AS to_char_4, to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 * -1), 'S9999999999999999')
FROM INT8_TBL;
to_char_4 | to_char | to_char
-----------+-------------------+-------------------
| 123- | -456
| 123- | -4567890123456789
| 4567890123456789- | -123
| 4567890123456789- | -4567890123456789
| 4567890123456789- | +4567890123456789
(5 rows)
SELECT '' AS to_char_5, to_char(q2, 'MI9999999999999999') FROM INT8_TBL;
to_char_5 | to_char
-----------+--------------------
| 456
| 4567890123456789
| 123
| 4567890123456789
| -4567890123456789
(5 rows)
SELECT '' AS to_char_6, to_char(q2, 'FMS9999999999999999') FROM INT8_TBL;
to_char_6 | to_char
-----------+-------------------
| +456
| +4567890123456789
| +123
| +4567890123456789
| -4567890123456789
(5 rows)
SELECT '' AS to_char_7, to_char(q2, 'FM9999999999999999THPR') FROM INT8_TBL;
to_char_7 | to_char
-----------+--------------------
| 456TH
| 4567890123456789TH
| 123RD
| 4567890123456789TH
| <4567890123456789>
(5 rows)
SELECT '' AS to_char_8, to_char(q2, 'SG9999999999999999th') FROM INT8_TBL;
to_char_8 | to_char
-----------+---------------------
| + 456th
| +4567890123456789th
| + 123rd
| +4567890123456789th
| -4567890123456789
(5 rows)
SELECT '' AS to_char_9, to_char(q2, '0999999999999999') FROM INT8_TBL;
to_char_9 | to_char
-----------+-------------------
| 0000000000000456
| 4567890123456789
| 0000000000000123
| 4567890123456789
| -4567890123456789
(5 rows)
SELECT '' AS to_char_10, to_char(q2, 'S0999999999999999') FROM INT8_TBL;
to_char_10 | to_char
------------+-------------------
| +0000000000000456
| +4567890123456789
| +0000000000000123
| +4567890123456789
| -4567890123456789
(5 rows)
SELECT '' AS to_char_11, to_char(q2, 'FM0999999999999999') FROM INT8_TBL;
to_char_11 | to_char
------------+-------------------
| 0000000000000456
| 4567890123456789
| 0000000000000123
| 4567890123456789
| -4567890123456789
(5 rows)
SELECT '' AS to_char_12, to_char(q2, 'FM9999999999999999.000') FROM INT8_TBL;
to_char_12 | to_char
------------+-----------------------
| 456.000
| 4567890123456789.000
| 123.000
| 4567890123456789.000
| -4567890123456789.000
(5 rows)
SELECT '' AS to_char_13, to_char(q2, 'L9999999999999999.000') FROM INT8_TBL;
to_char_13 | to_char
------------+------------------------
| 456.000
| 4567890123456789.000
| 123.000
| 4567890123456789.000
| -4567890123456789.000
(5 rows)
SELECT '' AS to_char_14, to_char(q2, 'FM9999999999999999.999') FROM INT8_TBL;
to_char_14 | to_char
------------+-------------------
| 456
| 4567890123456789
| 123
| 4567890123456789
| -4567890123456789
(5 rows)
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;
to_char_15 | to_char
------------+-------------------------------------------
| +4 5 6 . 0 0 0
| + 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
| +1 2 3 . 0 0 0
| + 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
| - 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
(5 rows)
SELECT '' AS to_char_16, to_char(q2, '99999 text 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL;
to_char_16 | to_char
------------+-----------------------------------------------------------
| text 9999 "text between quote marks" 456
| 45678 text 9012 9999 345 "text between quote marks" 6789
| text 9999 "text between quote marks" 123
| 45678 text 9012 9999 345 "text between quote marks" 6789
| -45678 text 9012 9999 345 "text between quote marks" 6789
(5 rows)
SELECT '' AS to_char_17, to_char(q2, '999999SG9999999999') FROM INT8_TBL;
to_char_17 | to_char
------------+-------------------
| + 456
| 456789+0123456789
| + 123
| 456789+0123456789
| 456789-0123456789
(5 rows)
This diff is collapsed.
This diff is collapsed.
......@@ -26,3 +26,31 @@ SELECT '' AS five, q1, int8(float8(q1)) AS "two coercions" FROM INT8_TBL;
SELECT '' AS five, 2 * q1 AS "twice int4" FROM INT8_TBL;
SELECT '' AS five, q1 * 2 AS "twice int4" FROM INT8_TBL;
-- TO_CHAR()
--
SELECT '' AS to_char_1, to_char(q1, '9G999G999G999G999G999'), to_char(q2, '9,999,999,999,999,999')
FROM INT8_TBL;
SELECT '' AS to_char_2, to_char(q1, '9G999G999G999G999G999D999G999'), to_char(q2, '9,999,999,999,999,999.999,999')
FROM INT8_TBL;
SELECT '' AS to_char_3, to_char( (q1 * -1), '9999999999999999PR'), to_char( (q2 * -1), '9999999999999999.999PR')
FROM INT8_TBL;
SELECT '' AS to_char_4, to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 * -1), 'S9999999999999999')
FROM INT8_TBL;
SELECT '' AS to_char_5, to_char(q2, 'MI9999999999999999') FROM INT8_TBL;
SELECT '' AS to_char_6, to_char(q2, 'FMS9999999999999999') FROM INT8_TBL;
SELECT '' AS to_char_7, to_char(q2, 'FM9999999999999999THPR') FROM INT8_TBL;
SELECT '' AS to_char_8, to_char(q2, 'SG9999999999999999th') FROM INT8_TBL;
SELECT '' AS to_char_9, to_char(q2, '0999999999999999') FROM INT8_TBL;
SELECT '' AS to_char_10, to_char(q2, 'S0999999999999999') FROM INT8_TBL;
SELECT '' AS to_char_11, to_char(q2, 'FM0999999999999999') FROM INT8_TBL;
SELECT '' AS to_char_12, to_char(q2, 'FM9999999999999999.000') FROM INT8_TBL;
SELECT '' AS to_char_13, to_char(q2, 'L9999999999999999.000') FROM INT8_TBL;
SELECT '' AS to_char_14, to_char(q2, 'FM9999999999999999.999') FROM INT8_TBL;
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;
SELECT '' AS to_char_16, to_char(q2, '99999 text 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL;
SELECT '' AS to_char_17, to_char(q2, '999999SG9999999999') FROM INT8_TBL;
......@@ -652,3 +652,52 @@ INSERT INTO fract_only VALUES (7, '0.00001');
INSERT INTO fract_only VALUES (8, '0.00017');
SELECT * FROM fract_only;
DROP TABLE fract_only;
-- TO_CHAR()
--
SELECT '' AS to_char_1, to_char(val, '9G999G999G999G999G999')
FROM num_data;
SELECT '' AS to_char_2, to_char(val, '9G999G999G999G999G999D999G999G999G999G999')
FROM num_data;
SELECT '' AS to_char_3, to_char(val, '9999999999999999.999999999999999PR')
FROM num_data;
SELECT '' AS to_char_4, to_char(val, '9999999999999999.999999999999999S')
FROM num_data;
SELECT '' AS to_char_5, to_char(val, 'MI9999999999999999.999999999999999') FROM num_data;
SELECT '' AS to_char_6, to_char(val, 'FMS9999999999999999.999999999999999') FROM num_data;
SELECT '' AS to_char_7, to_char(val, 'FM9999999999999999.999999999999999THPR') FROM num_data;
SELECT '' AS to_char_8, to_char(val, 'SG9999999999999999.999999999999999th') FROM num_data;
SELECT '' AS to_char_9, to_char(val, '0999999999999999.999999999999999') FROM num_data;
SELECT '' AS to_char_10, to_char(val, 'S0999999999999999.999999999999999') FROM num_data;
SELECT '' AS to_char_11, to_char(val, 'FM0999999999999999.999999999999999') FROM num_data;
SELECT '' AS to_char_12, to_char(val, 'FM9999999999999999.099999999999999') FROM num_data;
SELECT '' AS to_char_13, to_char(val, 'FM9999999999990999.990999999999999') FROM num_data;
SELECT '' AS to_char_14, to_char(val, 'FM0999999999999999.999909999999999') FROM num_data;
SELECT '' AS to_char_15, to_char(val, 'FM9999999990999999.099999999999999') FROM num_data;
SELECT '' AS to_char_16, to_char(val, 'L9999999999999999.099999999999999') FROM num_data;
SELECT '' AS to_char_17, to_char(val, 'FM9999999999999999.99999999999999') FROM num_data;
SELECT '' AS to_char_15, to_char(val, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data;
SELECT '' AS to_char_16, to_char(val, 'FMS 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data;
SELECT '' AS to_char_17, to_char(val, '99999 text 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM num_data;
SELECT '' AS to_char_18, to_char(val, '999999SG9999999999') FROM num_data;
SELECT '' AS to_char_19, to_char(val, 'FM9999999999999999.999999999999999') FROM num_data;
-- TO_NUMBER()
--
SELECT '' AS to_number_1, to_number('-34,338,492', '99G999G999');
SELECT '' AS to_number_2, to_number('-34,338,492.654,878', '99G999G999D999G999');
SELECT '' AS to_number_3, to_number('<564646.654564>', '999999.999999PR');
SELECT '' AS to_number_4, to_number('0.00001-', '9.999999S');
SELECT '' AS to_number_5, to_number('5.01-', 'FM9.999999S');
SELECT '' AS to_number_5, to_number('5.01-', 'FM9.999999MI');
SELECT '' AS to_number_7, to_number('5 4 4 4 4 8 . 7 8', '9 9 9 9 9 9 . 9 9');
SELECT '' AS to_number_8, to_number('.01', 'FM9.99');
SELECT '' AS to_number_9, to_number('.0', '99999999.99999999');
SELECT '' AS to_number_10, to_number('0', '99.99');
SELECT '' AS to_number_11, to_number('.-01', 'S99.99');
SELECT '' AS to_number_12, to_number('.01-', '99.99S');
SELECT '' AS to_number_13, to_number(' . 0 1 -', ' 9 9 . 9 9 S');
......@@ -167,3 +167,48 @@ SELECT '' AS fortynine, date_part( 'quarter', d1) AS quarter, date_part( 'msec',
date_part( 'usec', d1) AS usec
FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01';
-- TO_CHAR()
--
SELECT '' AS to_char_1, to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon')
FROM TIMESTAMP_TBL;
SELECT '' AS to_char_2, to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth FMRM')
FROM TIMESTAMP_TBL;
SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J')
FROM TIMESTAMP_TBL;
SELECT '' AS to_char_4, to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM FMWW FMDDD FMDD FMD FMJ')
FROM TIMESTAMP_TBL;
SELECT '' AS to_char_5, to_char(d1, 'HH HH12 HH24 MI SS SSSS')
FROM TIMESTAMP_TBL;
SELECT '' AS to_char_6, to_char(d1, '"HH:MI:SS is" HH:MI:SS "\\"text bettween quote marks\\""')
FROM TIMESTAMP_TBL;
SELECT '' AS to_char_7, to_char(d1, 'HH24--text--MI--text--SS')
FROM TIMESTAMP_TBL;
SELECT '' AS to_char_8, to_char(d1, 'YYYYTH YYYYth Jth')
FROM TIMESTAMP_TBL;
-- TO_TIMESTAMP()
--
SELECT '' AS to_timestamp_1, to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS');
SELECT '' AS to_timestamp_2, to_timestamp('97/2/16 8:14:30', 'FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS');
SELECT '' AS to_timestamp_3, to_timestamp('1985 January 12', 'YYYY FMMonth DD');
SELECT '' AS to_timestamp_4, to_timestamp('My birthday-> Year: 1976, Month: May, Day: 16',
'"My birthday-> Year" YYYY, "Month:" FMMonth, "Day:" DD');
SELECT '' AS to_timestamp_5, to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD');
SELECT '' AS to_timestamp_6, to_timestamp('15 "text bettween quote marks" 98 54 45',
'HH "\\text bettween quote marks\\"" YY MI SS');
SELECT '' AS to_timestamp_7, to_timestamp('05121445482000', 'MMDDHHMISSYYYY');
SELECT '' AS to_timestamp_8, to_timestamp('2000January09Sunday', 'YYYYFMMonthDDFMDay');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment