summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/formatting.c136
1 files changed, 49 insertions, 87 deletions
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index d3e3843cfab..13208526297 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------
* formatting.c
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.84.4.2 2005/03/26 00:41:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.84.4.3 2007/06/29 01:52:04 tgl Exp $
*
*
* Portions Copyright (c) 1999-2005, PostgreSQL Global Development Group
@@ -73,6 +73,7 @@
#include <unistd.h>
#include <math.h>
#include <float.h>
+#include <limits.h>
#include "utils/builtins.h"
#include "utils/date.h"
@@ -107,8 +108,8 @@
* More is in float.c
* ----------
*/
-#define MAXFLOATWIDTH 64
-#define MAXDOUBLEWIDTH 128
+#define MAXFLOATWIDTH 60
+#define MAXDOUBLEWIDTH 500
/* ----------
* External (defined in PgSQL datetime.c (timestamp utils))
@@ -1471,7 +1472,7 @@ str_numth(char *dest, char *num, int type)
}
/* ----------
- * Convert string to upper-string. Input string is modified in place.
+ * Convert string to upper case. Input string is modified in place.
* ----------
*/
static char *
@@ -1491,7 +1492,7 @@ str_toupper(char *buff)
}
/* ----------
- * Convert string to lower-string. Input string is modified in place.
+ * Convert string to lower case. Input string is modified in place.
* ----------
*/
static char *
@@ -2019,19 +2020,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
case DCH_TZ:
if (flag == TO_CHAR && tmtcTzn(tmtc))
{
- int siz = strlen(tmtcTzn(tmtc));
-
if (arg == DCH_TZ)
strcpy(inout, tmtcTzn(tmtc));
else
{
- char *p = palloc(siz);
+ char *p = pstrdup(tmtcTzn(tmtc));
- strcpy(p, tmtcTzn(tmtc));
strcpy(inout, str_tolower(p));
pfree(p);
}
- return siz - 1;
+ return strlen(inout) - 1;
}
else if (flag == FROM_CHAR)
ereport(ERROR,
@@ -3292,7 +3290,7 @@ static char *
fill_str(char *str, int c, int max)
{
memset(str, c, max);
- *(str + max + 1) = '\0';
+ *(str + max) = '\0';
return str;
}
@@ -4498,10 +4496,9 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
#define NUM_TOCHAR_prepare \
do { \
len = VARSIZE(fmt) - VARHDRSZ; \
- if (len <= 0) \
+ if (len <= 0 || len >= (INT_MAX-VARHDRSZ)/NUM_MAX_ITEM_SIZ) \
return DirectFunctionCall1(textin, CStringGetDatum("")); \
- result = (text *) palloc( (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \
- memset(result, 0, (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ ); \
+ result = (text *) palloc0((len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \
format = NUM_cache(len, &Num, VARDATA(fmt), &shouldFree); \
} while (0)
@@ -4513,28 +4510,18 @@ do { \
do { \
NUM_processor(format, &Num, VARDATA(result), \
numstr, plen, sign, TO_CHAR); \
- pfree(orgnum); \
\
- if (shouldFree) \
- pfree(format); \
+ if (shouldFree) \
+ pfree(format); \
\
- /*
- * for result is allocated max memory, which current format-picture\
- * needs, now it must be re-allocate to result real size \
+ /* \
+ * Convert null-terminated representation of result to standard text. \
+ * The result is usually much bigger than it needs to be, but there \
+ * seems little point in realloc'ing it smaller. \
*/ \
- if (!(len = strlen(VARDATA(result)))) \
- { \
- pfree(result); \
- PG_RETURN_NULL(); \
- } \
- \
- result_tmp = result; \
- result = (text *) palloc( len + 1 + VARHDRSZ); \
- \
- strcpy( VARDATA(result), VARDATA(result_tmp)); \
- VARATT_SIZEP(result) = len + VARHDRSZ; \
- pfree(result_tmp); \
-} while(0)
+ len = strlen(VARDATA(result)); \
+ VARATT_SIZEP(result) = len + VARHDRSZ; \
+} while (0)
/* -------------------
* NUMERIC to_number() (convert string to numeric)
@@ -4556,7 +4543,7 @@ numeric_to_number(PG_FUNCTION_ARGS)
len = VARSIZE(fmt) - VARHDRSZ;
- if (len <= 0)
+ if (len <= 0 || len >= INT_MAX/NUM_MAX_ITEM_SIZ)
PG_RETURN_NULL();
format = NUM_cache(len, &Num, VARDATA(fmt), &shouldFree);
@@ -4591,8 +4578,7 @@ numeric_to_char(PG_FUNCTION_ARGS)
text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num;
FormatNode *format;
- text *result,
- *result_tmp;
+ text *result;
bool shouldFree;
int len = 0,
plen = 0,
@@ -4615,7 +4601,6 @@ numeric_to_char(PG_FUNCTION_ARGS)
numstr = orgnum =
int_to_roman(DatumGetInt32(DirectFunctionCall1(numeric_int4,
NumericGetDatum(x))));
- pfree(x);
}
else
{
@@ -4634,9 +4619,6 @@ numeric_to_char(PG_FUNCTION_ARGS)
val = DatumGetNumeric(DirectFunctionCall2(numeric_mul,
NumericGetDatum(value),
NumericGetDatum(x)));
- pfree(x);
- pfree(a);
- pfree(b);
Num.pre += Num.multi;
}
@@ -4645,10 +4627,9 @@ numeric_to_char(PG_FUNCTION_ARGS)
Int32GetDatum(Num.post)));
orgnum = DatumGetCString(DirectFunctionCall1(numeric_out,
NumericGetDatum(x)));
- pfree(x);
if (*orgnum == '-')
- { /* < 0 */
+ {
sign = '-';
numstr = orgnum + 1;
}
@@ -4667,13 +4648,10 @@ numeric_to_char(PG_FUNCTION_ARGS)
else if (len > Num.pre)
{
- fill_str(numstr, '#', Num.pre);
+ numstr = (char *) palloc(Num.pre + Num.post + 2);
+ fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
- fill_str(numstr + 1 + Num.pre, '#', Num.post);
}
-
- if (IS_MULTI(&Num))
- pfree(val);
}
NUM_TOCHAR_finish;
@@ -4691,8 +4669,7 @@ int4_to_char(PG_FUNCTION_ARGS)
text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num;
FormatNode *format;
- text *result,
- *result_tmp;
+ text *result;
bool shouldFree;
int len = 0,
plen = 0,
@@ -4720,40 +4697,34 @@ int4_to_char(PG_FUNCTION_ARGS)
orgnum = DatumGetCString(DirectFunctionCall1(int4out,
Int32GetDatum(value)));
}
- len = strlen(orgnum);
if (*orgnum == '-')
- { /* < 0 */
+ {
sign = '-';
- --len;
+ orgnum++;
}
else
sign = '+';
+ len = strlen(orgnum);
if (Num.post)
{
- int i;
-
numstr = (char *) palloc(len + Num.post + 2);
- strcpy(numstr, orgnum + (*orgnum == '-' ? 1 : 0));
+ strcpy(numstr, orgnum);
*(numstr + len) = '.';
-
- for (i = len + 1; i <= len + Num.post; i++)
- *(numstr + i) = '0';
+ memset(numstr + len + 1, '0', Num.post);
*(numstr + len + Num.post + 1) = '\0';
- pfree(orgnum);
- orgnum = numstr;
}
else
- numstr = orgnum + (*orgnum == '-' ? 1 : 0);
+ numstr = orgnum;
if (Num.pre > len)
plen = Num.pre - len;
else if (len > Num.pre)
{
- fill_str(numstr, '#', Num.pre);
+ numstr = (char *) palloc(Num.pre + Num.post + 2);
+ fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
- fill_str(numstr + 1 + Num.pre, '#', Num.post);
}
}
@@ -4772,8 +4743,7 @@ int8_to_char(PG_FUNCTION_ARGS)
text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num;
FormatNode *format;
- text *result,
- *result_tmp;
+ text *result;
bool shouldFree;
int len = 0,
plen = 0,
@@ -4807,40 +4777,34 @@ int8_to_char(PG_FUNCTION_ARGS)
orgnum = DatumGetCString(DirectFunctionCall1(int8out,
Int64GetDatum(value)));
- len = strlen(orgnum);
if (*orgnum == '-')
- { /* < 0 */
+ {
sign = '-';
- --len;
+ orgnum++;
}
else
sign = '+';
+ len = strlen(orgnum);
if (Num.post)
{
- int i;
-
numstr = (char *) palloc(len + Num.post + 2);
- strcpy(numstr, orgnum + (*orgnum == '-' ? 1 : 0));
+ strcpy(numstr, orgnum);
*(numstr + len) = '.';
-
- for (i = len + 1; i <= len + Num.post; i++)
- *(numstr + i) = '0';
+ memset(numstr + len + 1, '0', Num.post);
*(numstr + len + Num.post + 1) = '\0';
- pfree(orgnum);
- orgnum = numstr;
}
else
- numstr = orgnum + (*orgnum == '-' ? 1 : 0);
+ numstr = orgnum;
if (Num.pre > len)
plen = Num.pre - len;
else if (len > Num.pre)
{
- fill_str(numstr, '#', Num.pre);
+ numstr = (char *) palloc(Num.pre + Num.post + 2);
+ fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
- fill_str(numstr + 1 + Num.pre, '#', Num.post);
}
}
@@ -4859,8 +4823,7 @@ float4_to_char(PG_FUNCTION_ARGS)
text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num;
FormatNode *format;
- text *result,
- *result_tmp;
+ text *result;
bool shouldFree;
int len = 0,
plen = 0,
@@ -4919,9 +4882,9 @@ float4_to_char(PG_FUNCTION_ARGS)
else if (len > Num.pre)
{
- fill_str(numstr, '#', Num.pre);
+ numstr = (char *) palloc(Num.pre + Num.post + 2);
+ fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
- fill_str(numstr + 1 + Num.pre, '#', Num.post);
}
}
@@ -4940,8 +4903,7 @@ float8_to_char(PG_FUNCTION_ARGS)
text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num;
FormatNode *format;
- text *result,
- *result_tmp;
+ text *result;
bool shouldFree;
int len = 0,
plen = 0,
@@ -4998,9 +4960,9 @@ float8_to_char(PG_FUNCTION_ARGS)
else if (len > Num.pre)
{
- fill_str(numstr, '#', Num.pre);
+ numstr = (char *) palloc(Num.pre + Num.post + 2);
+ fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
- fill_str(numstr + 1 + Num.pre, '#', Num.post);
}
}