113113#define DCH_MAX_ITEM_SIZ 12/* max localized day name*/
114114#define NUM_MAX_ITEM_SIZ 8/* roman number (RN has 15 chars)*/
115115
116+ /* ----------
117+ * More is in float.c
118+ * ----------
119+ */
120+ #define MAXFLOATWIDTH 60
121+ #define MAXDOUBLEWIDTH 500
122+
116123
117124/* ----------
118125 * Format parser structs
@@ -5207,7 +5214,8 @@ int4_to_char(PG_FUNCTION_ARGS)
52075214/* we can do it easily because float8 won't lose any precision */
52085215float8 val = (float8 )value ;
52095216
5210- orgnum = psprintf ("%+.*e" ,Num .post ,val );
5217+ orgnum = (char * )palloc (MAXDOUBLEWIDTH + 1 );
5218+ snprintf (orgnum ,MAXDOUBLEWIDTH + 1 ,"%+.*e" ,Num .post ,val );
52115219
52125220/*
52135221 * Swap a leading positive sign for a space.
@@ -5406,6 +5414,7 @@ float4_to_char(PG_FUNCTION_ARGS)
54065414numstr = orgnum = int_to_roman ((int )rint (value ));
54075415else if (IS_EEEE (& Num ))
54085416{
5417+ numstr = orgnum = (char * )palloc (MAXDOUBLEWIDTH + 1 );
54095418if (isnan (value )|| is_infinite (value ))
54105419{
54115420/*
@@ -5419,29 +5428,15 @@ float4_to_char(PG_FUNCTION_ARGS)
54195428}
54205429else
54215430{
5422- numstr = psprintf ("%+.*e" ,Num .post ,value );
5423-
5424- /* prevent the display of imprecise/junk digits */
5425- if (Num .pre + Num .post > FLT_DIG )
5426- {
5427- int digits = 0 ;
5428- char * numstr_p ;
5429-
5430- for (numstr_p = numstr ;* numstr_p && * numstr_p != 'e' ;numstr_p ++ )
5431- {
5432- if (isdigit (* numstr_p ))
5433- {
5434- if (++ digits > FLT_DIG )
5435- * numstr_p = '0' ;
5436- }
5437- }
5438- }
5431+ snprintf (orgnum ,MAXDOUBLEWIDTH + 1 ,"%+.*e" ,Num .post ,value );
54395432
54405433/*
54415434 * Swap a leading positive sign for a space.
54425435 */
5443- if (* numstr == '+' )
5444- * numstr = ' ' ;
5436+ if (* orgnum == '+' )
5437+ * orgnum = ' ' ;
5438+
5439+ numstr = orgnum ;
54455440}
54465441}
54475442else
@@ -5457,24 +5452,16 @@ float4_to_char(PG_FUNCTION_ARGS)
54575452Num .pre += Num .multi ;
54585453}
54595454
5460- /* let psprintf() do the rounding */
5461- orgnum = psprintf ("%.*f" ,Num .post ,val );
5455+ orgnum = (char * )palloc (MAXFLOATWIDTH + 1 );
5456+ snprintf (orgnum ,MAXFLOATWIDTH + 1 ,"%.0f" ,fabs (val ));
5457+ numstr_pre_len = strlen (orgnum );
54625458
5463- /* prevent the display of imprecise/junk digits */
5464- if (Num .pre + Num .post > FLT_DIG )
5465- {
5466- int digits = 0 ;
5467- char * orgnum_p ;
5468-
5469- for (orgnum_p = orgnum ;* orgnum_p ;orgnum_p ++ )
5470- {
5471- if (isdigit (* orgnum_p ))
5472- {
5473- if (++ digits > FLT_DIG )
5474- * orgnum_p = '0' ;
5475- }
5476- }
5477- }
5459+ /* adjust post digits to fit max float digits */
5460+ if (numstr_pre_len >=FLT_DIG )
5461+ Num .post = 0 ;
5462+ else if (numstr_pre_len + Num .post > FLT_DIG )
5463+ Num .post = FLT_DIG - numstr_pre_len ;
5464+ snprintf (orgnum ,MAXFLOATWIDTH + 1 ,"%.*f" ,Num .post ,val );
54785465
54795466if (* orgnum == '-' )
54805467{/* < 0 */
@@ -5533,6 +5520,7 @@ float8_to_char(PG_FUNCTION_ARGS)
55335520numstr = orgnum = int_to_roman ((int )rint (value ));
55345521else if (IS_EEEE (& Num ))
55355522{
5523+ numstr = orgnum = (char * )palloc (MAXDOUBLEWIDTH + 1 );
55365524if (isnan (value )|| is_infinite (value ))
55375525{
55385526/*
@@ -5546,29 +5534,15 @@ float8_to_char(PG_FUNCTION_ARGS)
55465534}
55475535else
55485536{
5549- numstr = psprintf ("%+.*e" ,Num .post ,value );
5550-
5551- /* prevent the display of imprecise/junk digits */
5552- if (Num .pre + Num .post > DBL_DIG )
5553- {
5554- int digits = 0 ;
5555- char * numstr_p ;
5556-
5557- for (numstr_p = numstr ;* numstr_p && * numstr_p != 'e' ;numstr_p ++ )
5558- {
5559- if (isdigit (* numstr_p ))
5560- {
5561- if (++ digits > DBL_DIG )
5562- * numstr_p = '0' ;
5563- }
5564- }
5565- }
5537+ snprintf (orgnum ,MAXDOUBLEWIDTH + 1 ,"%+.*e" ,Num .post ,value );
55665538
55675539/*
55685540 * Swap a leading positive sign for a space.
55695541 */
5570- if (* numstr == '+' )
5571- * numstr = ' ' ;
5542+ if (* orgnum == '+' )
5543+ * orgnum = ' ' ;
5544+
5545+ numstr = orgnum ;
55725546}
55735547}
55745548else
@@ -5583,25 +5557,15 @@ float8_to_char(PG_FUNCTION_ARGS)
55835557val = value * multi ;
55845558Num .pre += Num .multi ;
55855559}
5586-
5587- /* let psprintf() do the rounding */
5588- orgnum = psprintf ("%.*f" ,Num .post ,val );
5589-
5590- /* prevent the display of imprecise/junk digits */
5591- if (Num .pre + Num .post > DBL_DIG )
5592- {
5593- int digits = 0 ;
5594- char * orgnum_p ;
5595-
5596- for (orgnum_p = orgnum ;* orgnum_p ;orgnum_p ++ )
5597- {
5598- if (isdigit (* orgnum_p ))
5599- {
5600- if (++ digits > DBL_DIG )
5601- * orgnum_p = '0' ;
5602- }
5603- }
5604- }
5560+ orgnum = (char * )palloc (MAXDOUBLEWIDTH + 1 );
5561+ numstr_pre_len = snprintf (orgnum ,MAXDOUBLEWIDTH + 1 ,"%.0f" ,fabs (val ));
5562+
5563+ /* adjust post digits to fit max double digits */
5564+ if (numstr_pre_len >=DBL_DIG )
5565+ Num .post = 0 ;
5566+ else if (numstr_pre_len + Num .post > DBL_DIG )
5567+ Num .post = DBL_DIG - numstr_pre_len ;
5568+ snprintf (orgnum ,MAXDOUBLEWIDTH + 1 ,"%.*f" ,Num .post ,val );
56055569
56065570if (* orgnum == '-' )
56075571{/* < 0 */