1
1
/* -----------------------------------------------------------------------
2
2
* formatting.c
3
3
*
4
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.56.2.3 2005/03/26 00:42:44 tgl Exp $
4
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.56.2.4 2007/06/29 01:52:21 tgl Exp $
5
5
*
6
6
*
7
7
* Portions Copyright (c) 1999-2002, PostgreSQL Global Development Group
75
75
#include <locale.h>
76
76
#include <math.h>
77
77
#include <float.h>
78
+ #include <limits.h>
78
79
79
80
#include "utils/builtins.h"
80
81
#include "utils/date.h"
109
110
* More is in float.c
110
111
* ----------
111
112
*/
112
- #define MAXFLOATWIDTH 64
113
- #define MAXDOUBLEWIDTH 128
113
+ #define MAXFLOATWIDTH 60
114
+ #define MAXDOUBLEWIDTH 500
114
115
115
116
/* ----------
116
117
* External (defined in PgSQL dt.c (timestamp utils))
@@ -1417,7 +1418,7 @@ str_numth(char *dest, char *num, int type)
1417
1418
}
1418
1419
1419
1420
/* ----------
1420
- * Convert string to upper-string . Input string is modified in place.
1421
+ * Convert string to upper case . Input string is modified in place.
1421
1422
* ----------
1422
1423
*/
1423
1424
static char *
@@ -1437,7 +1438,7 @@ str_toupper(char *buff)
1437
1438
}
1438
1439
1439
1440
/* ----------
1440
- * Convert string to lower-string . Input string is modified in place.
1441
+ * Convert string to lower case . Input string is modified in place.
1441
1442
* ----------
1442
1443
*/
1443
1444
static char *
@@ -1963,19 +1964,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
1963
1964
case DCH_TZ :
1964
1965
if (flag == TO_CHAR && tmtcTzn (tmtc ))
1965
1966
{
1966
- int siz = strlen (tmtcTzn (tmtc ));
1967
-
1968
1967
if (arg == DCH_TZ )
1969
1968
strcpy (inout , tmtcTzn (tmtc ));
1970
1969
else
1971
1970
{
1972
- char * p = palloc ( siz );
1971
+ char * p = pstrdup ( tmtcTzn ( tmtc ) );
1973
1972
1974
- strcpy (p , tmtcTzn (tmtc ));
1975
1973
strcpy (inout , str_tolower (p ));
1976
1974
pfree (p );
1977
1975
}
1978
- return siz - 1 ;
1976
+ return strlen ( inout ) - 1 ;
1979
1977
}
1980
1978
else if (flag == FROM_CHAR )
1981
1979
elog (ERROR , "to_timestamp(): TZ/tz not supported." );
@@ -3155,7 +3153,7 @@ static char *
3155
3153
fill_str (char * str , int c , int max )
3156
3154
{
3157
3155
memset (str , c , max );
3158
- * (str + max + 1 ) = '\0' ;
3156
+ * (str + max ) = '\0' ;
3159
3157
return str ;
3160
3158
}
3161
3159
@@ -4286,9 +4284,9 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
4286
4284
#define NUM_TOCHAR_prepare \
4287
4285
do { \
4288
4286
len = VARSIZE(fmt) - VARHDRSZ; \
4289
- if (len <= 0) \
4287
+ if (len <= 0 || len >= (INT_MAX-VARHDRSZ)/NUM_MAX_ITEM_SIZ) \
4290
4288
return DirectFunctionCall1(textin, CStringGetDatum("")); \
4291
- result = (text *) palloc( (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \
4289
+ result = (text *) palloc((len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \
4292
4290
format = NUM_cache(len, &Num, VARDATA(fmt), &shouldFree); \
4293
4291
} while (0)
4294
4292
@@ -4300,28 +4298,18 @@ do { \
4300
4298
do { \
4301
4299
NUM_processor(format, &Num, VARDATA(result), \
4302
4300
numstr, plen, sign, TO_CHAR); \
4303
- pfree(orgnum); \
4304
4301
\
4305
- if (shouldFree) \
4306
- pfree(format); \
4302
+ if (shouldFree) \
4303
+ pfree(format); \
4307
4304
\
4308
- /*
4309
- * for result is allocated max memory, which current format-picture\
4310
- * needs, now it must be re-allocate to result real size \
4305
+ /* \
4306
+ * Convert null-terminated representation of result to standard text. \
4307
+ * The result is usually much bigger than it needs to be, but there \
4308
+ * seems little point in realloc'ing it smaller. \
4311
4309
*/ \
4312
- if (!(len = strlen (VARDATA (result )))) \
4313
- { \
4314
- pfree (result ); \
4315
- PG_RETURN_NULL (); \
4316
- } \
4317
- \
4318
- result_tmp = result ; \
4319
- result = (text * ) palloc ( len + 1 + VARHDRSZ ); \
4320
- \
4321
- strcpy ( VARDATA (result ), VARDATA (result_tmp )); \
4322
- VARATT_SIZEP (result ) = len + VARHDRSZ ; \
4323
- pfree (result_tmp ); \
4324
- } while (0 )
4310
+ len = strlen (VARDATA (result )); \
4311
+ VARATT_SIZEP (result ) = len +
10000
VARHDRSZ ; \
4312
+ } while (0 )
4325
4313
4326
4314
/* -------------------
4327
4315
* NUMERIC to_number() (convert string to numeric)
@@ -4343,7 +4331,7 @@ numeric_to_number(PG_FUNCTION_ARGS)
4343
4331
4344
4332
len = VARSIZE (fmt ) - VARHDRSZ ;
4345
4333
4346
- if (len <= 0 )
4334
+ if (len <= 0 || len >= INT_MAX / NUM_MAX_ITEM_SIZ )
4347
4335
PG_RETURN_NULL ();
4348
4336
4349
4337
format = NUM_cache (len , & Num , VARDATA (fmt ), & shouldFree );
@@ -4378,8 +4366,7 @@ numeric_to_char(PG_FUNCTION_ARGS)
4378
4366
text * fmt = PG_GETARG_TEXT_P (1 );
4379
4367
NUMDesc Num ;
4380
4368
FormatNode * format ;
4381
- text * result ,
4382
- * result_tmp ;
4369
+ text * result ;
4383
4370
bool shouldFree ;
4384
4371
int len = 0 ,
4385
4372
plen = 0 ,
@@ -4402,7 +4389,6 @@ numeric_to_char(PG_FUNCTION_ARGS)
4402
4389
numstr = orgnum =
4403
4390
int_to_roman (DatumGetInt32 (DirectFunctionCall1 (numeric_int4 ,
4404
4391
NumericGetDatum (x ))));
4405
- pfree (x );
4406
4392
}
4407
4393
else
4408
4394
{
@@ -4421,9 +4407,6 @@ numeric_to_char(PG_FUNCTION_ARGS)
4421
4407
val = DatumGetNumeric (DirectFunctionCall2 (numeric_mul ,
4422
4408
NumericGetDatum (value ),
4423
4409
NumericGetDatum (x )));
4424
- pfree (x );
4425
- pfree (a );
4426
- pfree (b );
4427
4410
Num .pre += Num .multi ;
4428
4411
}
4429
4412
@@ -4432,10 +4415,9 @@ numeric_to_char(PG_FUNCTION_ARGS)
4432
4415
Int32GetDatum (Num .post )));
4433
4416
orgnum = DatumGetCString (DirectFunctionCall1 (numeric_out ,
4434
4417
NumericGetDatum (x )));
4435
- pfree (x );
4436
4418
4437
4419
if (* orgnum == '-' )
4438
- { /* < 0 */
4420
+ {
4439
4421
sign = '-' ;
4440
4422
numstr = orgnum + 1 ;
4441
4423
}
@@ -4454,13 +4436,10 @@ numeric_to_char(PG_FUNCTION_ARGS)
4454
4436
4455
4437
else if (len > Num .pre )
4456
4438
{
4457
- fill_str (numstr , '#' , Num .pre );
4439
+ numstr = (char * ) palloc (Num .pre + Num .post + 2 );
4440
+ fill_str (numstr , '#' , Num .pre + Num .post + 1 );
4458
4441
* (numstr + Num .pre ) = '.' ;
4459
- fill_str (numstr + 1 + Num .pre , '#' , Num .post );
4460
4442
}
4461
-
4462
- if (IS_MULTI (& Num ))
4463
- pfree (val );
4464
4443
}
4465
4444
4466
4445
NUM_TOCHAR_finish ;
@@ -4478,8 +4457,7 @@ int4_to_char(PG_FUNCTION_ARGS)
4478
4457
text * fmt = PG_GETARG_TEXT_P (1 );
4479
4458
NUMDesc Num ;
4480
4459
FormatNode * format ;
4481
- text * result ,
4482
- * result_tmp ;
4460
+ text * result ;
4483
4461
bool shouldFree ;
4484
4462
int len = 0 ,
4485
4463
plen = 0 ,
@@ -4507,40 +4485,34 @@ int4_to_char(PG_FUNCTION_ARGS)
4507
4485
orgnum = DatumGetCString (DirectFunctionCall1 (int4out ,
4508
4486
Int32GetDatum (value )));
4509
4487
}
4510
- len = strlen (orgnum );
4511
4488
4512
4489
if (* orgnum == '-' )
4513
- { /* < 0 */
4490
+ {
4514
4491
sign = '-' ;
4515
- -- len ;
4492
+ orgnum ++ ;
4516
4493
}
4517
4494
else
4518
4495
sign = '+' ;
4496
+ len = strlen (orgnum );
4519
4497
4520
4498
if (Num .post )
4521
4499
{
4522
- int i ;
4523
-
4524
4500
numstr = (char * ) palloc (len + Num .post + 2 );
4525
- strcpy (numstr , orgnum + ( * orgnum == '-' ? 1 : 0 ) );
4501
+ strcpy (numstr , orgnum );
4526
4502
* (numstr + len ) = '.' ;
4527
-
4528
- for (i = len + 1 ; i <= len + Num .post ; i ++ )
4529
- * (numstr + i ) = '0' ;
4503
+ memset (numstr + len + 1 , '0' , Num .post );
4530
4504
* (numstr + len + Num .post + 1 ) = '\0' ;
4531
- pfree (orgnum );
4532
- orgnum = numstr ;
4533
4505
}
4534
4506
else
4535
- numstr = orgnum + ( * orgnum == '-' ? 1 : 0 ) ;
4507
+ numstr = orgnum ;
4536
4508
4537
4509
if (Num .pre > len )
4538
4510
plen = Num .pre - len ;
4539
4511
else if (len > Num .pre )
4540
4512
{
4541
- fill_str (numstr , '#' , Num .pre );
4513
+ numstr = (char * ) palloc (Num .pre + Num .post + 2 );
4514
+ fill_str (numstr , '#' , Num .pre + Num .post + 1 );
4542
4515
* (numstr + Num .pre ) = '.' ;
4543
- fill_str (numstr + 1 + Num .pre , '#' , Num .post );
4544
4516
}
4545
4517
}
4546
4518
@@ -4559,8 +4531,7 @@ int8_to_char(PG_FUNCTION_ARGS)
4559
4531
text * fmt = PG_GETARG_TEXT_P (1 );
4560
4532
NUMDesc Num ;
4561
4533
FormatNode * format ;
4562
- text * result ,
4563
- * result_tmp ;
4534
+ text * result ;
4564
4535
bool shouldFree ;
4565
4536
int len = 0 ,
4566
4537
plen = 0 ,
@@ -4594,40 +4565,34 @@ int8_to_char(PG_FUNCTION_ARGS)
4594
4565
4595
4566
orgnum = DatumGetCString (DirectFunctionCall1 (int8out ,
4596
4567
Int64GetDatum (value )));
4597
- len = strlen (orgnum );
4598
4568
4599
4569
if (* orgnum == '-' )
4600
- { /* < 0 */
4570
+ {
4601
4571
sign = '-' ;
4602
- -- len ;
4572
+ orgnum ++ ;
4603
4573
}
4604
4574
else
4605
4575
sign = '+' ;
4576
+ len = strlen (orgnum );
4606
4577
4607
4578
if (Num .post )
4608
4579
{
4609
- int i ;
4610
-
4611
4580
numstr = (char * ) palloc (len + Num .post + 2 );
4612
- strcpy (numstr , orgnum + ( * orgnum == '-' ? 1 : 0 ) );
4581
+ strcpy (numstr , orgnum );
4613
4582
* (numstr + len ) = '.' ;
4614
-
4615
- for (i = len + 1 ; i <= len + Num .post ; i ++ )
4616
- * (numstr + i ) = '0' ;
4583
+ memset (numstr + len + 1 , '0' , Num .post );
4617
4584
* (numstr + len + Num .post + 1 ) = '\0' ;
4618
- pfree (orgnum );
4619
- orgnum = numstr ;
4620
4585
}
4621
4586
else
4622
- numstr = orgnum + ( * orgnum == '-' ? 1 : 0 ) ;
4587
+ numstr = orgnum ;
4623
4588
4624
4589
if (Num .pre > len )
4625
4590
plen = Num .pre - len ;
4626
4591
else if (len > Num .pre )
4627
4592
{
4628
- fill_str (numstr , '#' , Num .pre );
4593
+ numstr = (char * ) palloc (Num .pre + Num .post + 2 );
4594
+ fill_str (numstr , '#' , Num .pre + Num .post + 1 );
4629
4595
* (numstr + Num .pre ) = '.' ;
4630
- fill_str (numstr + 1 + Num .pre , '#' , Num .post );
4631
4596
}
4632
4597
}
4633
4598
@@ -4646,8 +4611,7 @@ float4_to_char(PG_FUNCTION_ARGS)
4646
4611
text * fmt = PG_GETARG_TEXT_P (1 );
4647
4612
NUMDesc Num ;
4648
4613
FormatNode * format ;
4649
- text * result ,
4650
- * result_tmp ;
4614
+ text * result ;
4651
4615
bool shouldFree ;
4652
4616
int len = 0 ,
4653
4617
plen = 0 ,
@@ -4706,9 +4670,9 @@ float4_to_char(PG_FUNCTION_ARGS)
4706
4670
4707
4671
else if (len > Num .pre )
4708
4672
{
4709
- fill_str (numstr , '#' , Num .pre );
4673
+ numstr = (char * ) palloc (Num .pre + Num .post + 2 );
4674
+ fill_str (numstr , '#' , Num .pre + Num .post + 1 );
4710
4675
* (numstr + Num .pre ) = '.' ;
4711
- fill_str (numstr + 1 + Num .pre , '#' , Num .post );
4712
4676
}
4713
4677
}
4714
4678
@@ -4727,8 +4691,7 @@ float8_to_char(PG_FUNCTION_ARGS)
4727
4691
text * fmt = PG_GETARG_TEXT_P (1 );
4728
4692
NUMDesc Num ;
4729
4693
FormatNode * format ;
4730
- text * result ,
4731
- * result_tmp ;
4694
+ text * result ;
4732
4695
bool shouldFree ;
4733
4696
int len = 0 ,
4734
4697
plen = 0 ,
@@ -4785,9 +4748,9 @@ float8_to_char(PG_FUNCTION_ARGS)
4785
4748
4786
4749
else if (len > Num .pre )
4787
4750
{
4788
- fill_str (numstr , '#' , Num .pre );
4751
+ numstr = (char * ) palloc (Num .pre + Num .post + 2 );
4752
+ fill_str (numstr , '#' , Num .pre + Num .post + 1 );
4789
4753
* (numstr + Num .pre ) = '.' ;
4790
- fill_str (numstr + 1 + Num .pre , '#' , Num .post );
4791
4754
}
4792
4755
}
4793
4756
0 commit comments