|
|
|
|
@ -922,7 +922,7 @@ typedef struct NUMProc |
|
|
|
|
num_count, /* number of write digits */ |
|
|
|
|
num_in, /* is inside number */ |
|
|
|
|
num_curr, /* current position in number */ |
|
|
|
|
num_pre, /* space before first number */ |
|
|
|
|
out_pre_spaces, /* spaces before first digit */ |
|
|
|
|
|
|
|
|
|
read_dec, /* to_number - was read dec. point */ |
|
|
|
|
read_post, /* to_number - number of dec. digit */ |
|
|
|
|
@ -979,10 +979,11 @@ static FormatNode *NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *should |
|
|
|
|
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, int plen); |
|
|
|
|
static void NUM_numpart_from_char(NUMProc *Np, int id, int input_len); |
|
|
|
|
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, bool is_to_char, Oid collid); |
|
|
|
|
static char *NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, |
|
|
|
|
char *number, int from_char_input_len, int to_char_out_pre_spaces, |
|
|
|
|
int sign, bool is_to_char, Oid collid); |
|
|
|
|
static DCHCacheEntry *DCH_cache_search(char *str); |
|
|
|
|
static DCHCacheEntry *DCH_cache_getnew(char *str); |
|
|
|
|
|
|
|
|
|
@ -4004,7 +4005,7 @@ get_last_relevant_decnum(char *num) |
|
|
|
|
* ---------- |
|
|
|
|
*/ |
|
|
|
|
static void |
|
|
|
|
NUM_numpart_from_char(NUMProc *Np, int id, int plen) |
|
|
|
|
NUM_numpart_from_char(NUMProc *Np, int id, int input_len) |
|
|
|
|
{ |
|
|
|
|
bool isread = FALSE; |
|
|
|
|
|
|
|
|
|
@ -4016,8 +4017,8 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen) |
|
|
|
|
if (*Np->inout_p == ' ') |
|
|
|
|
Np->inout_p++; |
|
|
|
|
|
|
|
|
|
#define OVERLOAD_TEST (Np->inout_p >= Np->inout + plen) |
|
|
|
|
#define AMOUNT_TEST(_s) (plen-(Np->inout_p-Np->inout) >= _s) |
|
|
|
|
#define OVERLOAD_TEST (Np->inout_p >= Np->inout + input_len) |
|
|
|
|
#define AMOUNT_TEST(_s) (input_len-(Np->inout_p-Np->inout) >= _s) |
|
|
|
|
|
|
|
|
|
if (*Np->inout_p == ' ') |
|
|
|
|
Np->inout_p++; |
|
|
|
|
@ -4168,7 +4169,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen) |
|
|
|
|
* next char is not digit |
|
|
|
|
*/ |
|
|
|
|
if (IS_LSIGN(Np->Num) && isread && |
|
|
|
|
(Np->inout_p + 1) <= Np->inout + plen && |
|
|
|
|
(Np->inout_p + 1) <= Np->inout + input_len && |
|
|
|
|
!isdigit((unsigned char) *(Np->inout_p + 1))) |
|
|
|
|
{ |
|
|
|
|
int x; |
|
|
|
|
@ -4263,7 +4264,7 @@ NUM_numpart_to_char(NUMProc *Np, int id) |
|
|
|
|
* handle "9.9" --> " .1" |
|
|
|
|
*/ |
|
|
|
|
if (Np->sign_wrote == FALSE && |
|
|
|
|
(Np->num_curr >= Np->num_pre || (IS_ZERO(Np->Num) && Np->Num->zero_start == Np->num_curr)) && |
|
|
|
|
(Np->num_curr >= Np->out_pre_spaces || (IS_ZERO(Np->Num) && Np->Num->zero_start == Np->num_curr)) && |
|
|
|
|
(IS_PREDEC_SPACE(Np) == FALSE || (Np->last_relevant && *Np->last_relevant == '.'))) |
|
|
|
|
{ |
|
|
|
|
if (IS_LSIGN(Np->Num)) |
|
|
|
|
@ -4307,7 +4308,7 @@ NUM_numpart_to_char(NUMProc *Np, int id) |
|
|
|
|
*/ |
|
|
|
|
if (id == NUM_9 || id == NUM_0 || id == NUM_D || id == NUM_DEC) |
|
|
|
|
{ |
|
|
|
|
if (Np->num_curr < Np->num_pre && |
|
|
|
|
if (Np->num_curr < Np->out_pre_spaces && |
|
|
|
|
(Np->Num->zero_start > Np->num_curr || !IS_ZERO(Np->Num))) |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
@ -4320,7 +4321,7 @@ NUM_numpart_to_char(NUMProc *Np, int id) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else if (IS_ZERO(Np->Num) && |
|
|
|
|
Np->num_curr < Np->num_pre && |
|
|
|
|
Np->num_curr < Np->out_pre_spaces && |
|
|
|
|
Np->Num->zero_start <= Np->num_curr) |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
@ -4392,7 +4393,7 @@ NUM_numpart_to_char(NUMProc *Np, int id) |
|
|
|
|
++Np->number_p; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
end = Np->num_count + (Np->num_pre ? 1 : 0) + (IS_DECIMAL(Np->Num) ? 1 : 0); |
|
|
|
|
end = Np->num_count + (Np->out_pre_spaces ? 1 : 0) + (IS_DECIMAL(Np->Num) ? 1 : 0); |
|
|
|
|
|
|
|
|
|
if (Np->last_relevant && Np->last_relevant == Np->number_p) |
|
|
|
|
end = Np->num_curr; |
|
|
|
|
@ -4418,13 +4419,10 @@ NUM_numpart_to_char(NUMProc *Np, int id) |
|
|
|
|
++Np->num_curr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Note: 'plen' is used in FROM_CHAR conversion and it's length of |
|
|
|
|
* input (inout). In TO_CHAR conversion it's space before first number. |
|
|
|
|
*/ |
|
|
|
|
static char * |
|
|
|
|
NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, |
|
|
|
|
int plen, int sign, bool is_to_char, Oid collid) |
|
|
|
|
NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, |
|
|
|
|
char *number, int from_char_input_len, int to_char_out_pre_spaces, |
|
|
|
|
int sign, bool is_to_char, Oid collid) |
|
|
|
|
{ |
|
|
|
|
FormatNode *n; |
|
|
|
|
NUMProc _Np, |
|
|
|
|
@ -4464,7 +4462,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, |
|
|
|
|
errmsg("\"RN\" not supported for input"))); |
|
|
|
|
|
|
|
|
|
Np->Num->lsign = Np->Num->pre_lsign_num = Np->Num->post = |
|
|
|
|
Np->Num->pre = Np->num_pre = Np->sign = 0; |
|
|
|
|
Np->Num->pre = Np->out_pre_spaces = Np->sign = 0; |
|
|
|
|
|
|
|
|
|
if (IS_FILLMODE(Np->Num)) |
|
|
|
|
{ |
|
|
|
|
@ -4522,7 +4520,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, |
|
|
|
|
|
|
|
|
|
if (is_to_char) |
|
|
|
|
{ |
|
|
|
|
Np->num_pre = plen; |
|
|
|
|
Np->out_pre_spaces = to_char_out_pre_spaces; |
|
|
|
|
|
|
|
|
|
if (IS_FILLMODE(Np->Num) && IS_DECIMAL(Np->Num)) |
|
|
|
|
{ |
|
|
|
|
@ -4532,22 +4530,22 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, |
|
|
|
|
* If any '0' specifiers are present, make sure we don't strip |
|
|
|
|
* those digits. |
|
|
|
|
*/ |
|
|
|
|
if (Np->last_relevant && Np->Num->zero_end > Np->num_pre) |
|
|
|
|
if (Np->last_relevant && Np->Num->zero_end > Np->out_pre_spaces) |
|
|
|
|
{ |
|
|
|
|
char *last_zero; |
|
|
|
|
|
|
|
|
|
last_zero = Np->number + (Np->Num->zero_end - Np->num_pre); |
|
|
|
|
last_zero = Np->number + (Np->Num->zero_end - Np->out_pre_spaces); |
|
|
|
|
if (Np->last_relevant < last_zero) |
|
|
|
|
Np->last_relevant = last_zero; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (Np->sign_wrote == FALSE && Np->num_pre == 0) |
|
|
|
|
if (Np->sign_wrote == FALSE && Np->out_pre_spaces == 0) |
|
|
|
|
++Np->num_count; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Np->num_pre = 0; |
|
|
|
|
Np->out_pre_spaces = 0; |
|
|
|
|
*Np->number = ' '; /* sign space */ |
|
|
|
|
*(Np->number + 1) = '\0'; |
|
|
|
|
} |
|
|
|
|
@ -4563,7 +4561,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, |
|
|
|
|
Np->Num->pre, |
|
|
|
|
Np->Num->post, |
|
|
|
|
Np->num_count, |
|
|
|
|
Np->num_pre, |
|
|
|
|
Np->out_pre_spaces, |
|
|
|
|
Np->sign_wrote ? "Yes" : "No", |
|
|
|
|
IS_ZERO(Np->Num) ? "Yes" : "No", |
|
|
|
|
Np->Num->zero_start, |
|
|
|
|
@ -4598,7 +4596,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 + from_char_input_len) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -4628,7 +4626,7 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
NUM_numpart_from_char(Np, n->key->id, plen); |
|
|
|
|
NUM_numpart_from_char(Np, n->key->id, from_char_input_len); |
|
|
|
|
break; /* switch() case: */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -4851,7 +4849,7 @@ do { \ |
|
|
|
|
*/ |
|
|
|
|
#define NUM_TOCHAR_finish \ |
|
|
|
|
do { \
|
|
|
|
|
NUM_processor(format, &Num, VARDATA(result), numstr, plen, sign, true, PG_GET_COLLATION()); \
|
|
|
|
|
NUM_processor(format, &Num, VARDATA(result), numstr, 0, out_pre_spaces, sign, true, PG_GET_COLLATION()); \
|
|
|
|
|
\
|
|
|
|
|
if (shouldFree) \
|
|
|
|
|
pfree(format); \
|
|
|
|
|
@ -4893,7 +4891,7 @@ numeric_to_number(PG_FUNCTION_ARGS) |
|
|
|
|
numstr = (char *) palloc((len * NUM_MAX_ITEM_SIZ) + 1); |
|
|
|
|
|
|
|
|
|
NUM_processor(format, &Num, VARDATA(value), numstr, |
|
|
|
|
VARSIZE(value) - VARHDRSZ, 0, false, PG_GET_COLLATION()); |
|
|
|
|
VARSIZE(value) - VARHDRSZ, 0, 0, false, PG_GET_COLLATION()); |
|
|
|
|
|
|
|
|
|
scale = Num.post; |
|
|
|
|
precision = Max(0, Num.pre) + scale; |
|
|
|
|
@ -4923,7 +4921,7 @@ numeric_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
text *result; |
|
|
|
|
bool shouldFree; |
|
|
|
|
int len = 0, |
|
|
|
|
plen = 0, |
|
|
|
|
out_pre_spaces = 0, |
|
|
|
|
sign = 0; |
|
|
|
|
char *numstr, |
|
|
|
|
*orgnum, |
|
|
|
|
@ -4979,6 +4977,7 @@ numeric_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
int numstr_pre_len; |
|
|
|
|
Numeric val = value; |
|
|
|
|
|
|
|
|
|
if (IS_MULTI(&Num)) |
|
|
|
|
@ -5013,14 +5012,17 @@ numeric_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
sign = '+'; |
|
|
|
|
numstr = orgnum; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((p = strchr(numstr, '.'))) |
|
|
|
|
len = p - numstr; |
|
|
|
|
numstr_pre_len = p - numstr; |
|
|
|
|
else |
|
|
|
|
len = strlen(numstr); |
|
|
|
|
numstr_pre_len = strlen(numstr); |
|
|
|
|
|
|
|
|
|
if (Num.pre > len) |
|
|
|
|
plen = Num.pre - len; |
|
|
|
|
else if (len > Num.pre) |
|
|
|
|
/* needs padding? */ |
|
|
|
|
if (numstr_pre_len < Num.pre) |
|
|
|
|
out_pre_spaces = Num.pre - numstr_pre_len; |
|
|
|
|
/* overflowed prefix digit format? */ |
|
|
|
|
else if (numstr_pre_len > Num.pre) |
|
|
|
|
{ |
|
|
|
|
numstr = (char *) palloc(Num.pre + Num.post + 2); |
|
|
|
|
fill_str(numstr, '#', Num.pre + Num.post + 1); |
|
|
|
|
@ -5046,7 +5048,7 @@ int4_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
text *result; |
|
|
|
|
bool shouldFree; |
|
|
|
|
int len = 0, |
|
|
|
|
plen = 0, |
|
|
|
|
out_pre_spaces = 0, |
|
|
|
|
sign = 0; |
|
|
|
|
char *numstr, |
|
|
|
|
*orgnum; |
|
|
|
|
@ -5077,6 +5079,8 @@ int4_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
int numstr_pre_len; |
|
|
|
|
|
|
|
|
|
if (IS_MULTI(&Num)) |
|
|
|
|
{ |
|
|
|
|
orgnum = DatumGetCString(DirectFunctionCall1(int4out, |
|
|
|
|
@ -5096,22 +5100,26 @@ int4_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
sign = '+'; |
|
|
|
|
len = strlen(orgnum); |
|
|
|
|
|
|
|
|
|
numstr_pre_len = strlen(orgnum); |
|
|
|
|
|
|
|
|
|
/* post-decimal digits? Pad out with zeros. */ |
|
|
|
|
if (Num.post) |
|
|
|
|
{ |
|
|
|
|
numstr = (char *) palloc(len + Num.post + 2); |
|
|
|
|
numstr = (char *) palloc(numstr_pre_len + Num.post + 2); |
|
|
|
|
strcpy(numstr, orgnum); |
|
|
|
|
*(numstr + len) = '.'; |
|
|
|
|
memset(numstr + len + 1, '0', Num.post); |
|
|
|
|
*(numstr + len + Num.post + 1) = '\0'; |
|
|
|
|
*(numstr + numstr_pre_len) = '.'; |
|
|
|
|
memset(numstr + numstr_pre_len + 1, '0', Num.post); |
|
|
|
|
*(numstr + numstr_pre_len + Num.post + 1) = '\0'; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
numstr = orgnum; |
|
|
|
|
|
|
|
|
|
if (Num.pre > len) |
|
|
|
|
plen = Num.pre - len; |
|
|
|
|
else if (len > Num.pre) |
|
|
|
|
/* needs padding? */ |
|
|
|
|
if (numstr_pre_len < Num.pre) |
|
|
|
|
out_pre_spaces = Num.pre - numstr_pre_len; |
|
|
|
|
/* overflowed prefix digit format? */ |
|
|
|
|
else if (numstr_pre_len > Num.pre) |
|
|
|
|
{ |
|
|
|
|
numstr = (char *) palloc(Num.pre + Num.post + 2); |
|
|
|
|
fill_str(numstr, '#', Num.pre + Num.post + 1); |
|
|
|
|
@ -5137,7 +5145,7 @@ int8_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
text *result; |
|
|
|
|
bool shouldFree; |
|
|
|
|
int len = 0, |
|
|
|
|
plen = 0, |
|
|
|
|
out_pre_spaces = 0, |
|
|
|
|
sign = 0; |
|
|
|
|
char *numstr, |
|
|
|
|
*orgnum; |
|
|
|
|
@ -5182,6 +5190,8 @@ int8_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
int numstr_pre_len; |
|
|
|
|
|
|
|
|
|
if (IS_MULTI(&Num)) |
|
|
|
|
{ |
|
|
|
|
double multi = pow((double) 10, (double) Num.multi); |
|
|
|
|
@ -5203,22 +5213,26 @@ int8_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
sign = '+'; |
|
|
|
|
len = strlen(orgnum); |
|
|
|
|
|
|
|
|
|
numstr_pre_len = strlen(orgnum); |
|
|
|
|
|
|
|
|
|
/* post-decimal digits? Pad out with zeros. */ |
|
|
|
|
if (Num.post) |
|
|
|
|
{ |
|
|
|
|
numstr = (char *) palloc(len + Num.post + 2); |
|
|
|
|
numstr = (char *) palloc(numstr_pre_len + Num.post + 2); |
|
|
|
|
strcpy(numstr, orgnum); |
|
|
|
|
*(numstr + len) = '.'; |
|
|
|
|
memset(numstr + len + 1, '0', Num.post); |
|
|
|
|
*(numstr + len + Num.post + 1) = '\0'; |
|
|
|
|
*(numstr + numstr_pre_len) = '.'; |
|
|
|
|
memset(numstr + numstr_pre_len + 1, '0', Num.post); |
|
|
|
|
*(numstr + numstr_pre_len + Num.post + 1) = '\0'; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
numstr = orgnum; |
|
|
|
|
|
|
|
|
|
if (Num.pre > len) |
|
|
|
|
plen = Num.pre - len; |
|
|
|
|
else if (len > Num.pre) |
|
|
|
|
/* needs padding? */ |
|
|
|
|
if (numstr_pre_len < Num.pre) |
|
|
|
|
out_pre_spaces = Num.pre - numstr_pre_len; |
|
|
|
|
/* overflowed prefix digit format? */ |
|
|
|
|
else if (numstr_pre_len > Num.pre) |
|
|
|
|
{ |
|
|
|
|
numstr = (char *) palloc(Num.pre + Num.post + 2); |
|
|
|
|
fill_str(numstr, '#', Num.pre + Num.post + 1); |
|
|
|
|
@ -5244,7 +5258,7 @@ float4_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
text *result; |
|
|
|
|
bool shouldFree; |
|
|
|
|
int len = 0, |
|
|
|
|
plen = 0, |
|
|
|
|
out_pre_spaces = 0, |
|
|
|
|
sign = 0; |
|
|
|
|
char *numstr, |
|
|
|
|
*orgnum, |
|
|
|
|
@ -5284,6 +5298,7 @@ float4_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
int numstr_pre_len; |
|
|
|
|
float4 val = value; |
|
|
|
|
|
|
|
|
|
if (IS_MULTI(&Num)) |
|
|
|
|
@ -5296,13 +5311,13 @@ float4_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
|
|
|
|
|
orgnum = (char *) palloc(MAXFLOATWIDTH + 1); |
|
|
|
|
snprintf(orgnum, MAXFLOATWIDTH + 1, "%.0f", fabs(val)); |
|
|
|
|
len = strlen(orgnum); |
|
|
|
|
if (Num.pre > len) |
|
|
|
|
plen = Num.pre - len; |
|
|
|
|
if (len >= FLT_DIG) |
|
|
|
|
numstr_pre_len = strlen(orgnum); |
|
|
|
|
|
|
|
|
|
/* adjust post digits to fit max float digits */ |
|
|
|
|
if (numstr_pre_len >= FLT_DIG) |
|
|
|
|
Num.post = 0; |
|
|
|
|
else if (Num.post + len > FLT_DIG) |
|
|
|
|
Num.post = FLT_DIG - len; |
|
|
|
|
else if (numstr_pre_len + Num.post > FLT_DIG) |
|
|
|
|
Num.post = FLT_DIG - numstr_pre_len; |
|
|
|
|
snprintf(orgnum, MAXFLOATWIDTH + 1, "%.*f", Num.post, val); |
|
|
|
|
|
|
|
|
|
if (*orgnum == '-') |
|
|
|
|
@ -5315,14 +5330,17 @@ float4_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
sign = '+'; |
|
|
|
|
numstr = orgnum; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((p = strchr(numstr, '.'))) |
|
|
|
|
len = p - numstr; |
|
|
|
|
numstr_pre_len = p - numstr; |
|
|
|
|
else |
|
|
|
|
len = strlen(numstr); |
|
|
|
|
numstr_pre_len = strlen(numstr); |
|
|
|
|
|
|
|
|
|
if (Num.pre > len) |
|
|
|
|
plen = Num.pre - len; |
|
|
|
|
else if (len > Num.pre) |
|
|
|
|
/* needs padding? */ |
|
|
|
|
if (numstr_pre_len < Num.pre) |
|
|
|
|
out_pre_spaces = Num.pre - numstr_pre_len; |
|
|
|
|
/* overflowed prefix digit format? */ |
|
|
|
|
else if (numstr_pre_len > Num.pre) |
|
|
|
|
{ |
|
|
|
|
numstr = (char *) palloc(Num.pre + Num.post + 2); |
|
|
|
|
fill_str(numstr, '#', Num.pre + Num.post + 1); |
|
|
|
|
@ -5348,7 +5366,7 @@ float8_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
text *result; |
|
|
|
|
bool shouldFree; |
|
|
|
|
int len = 0, |
|
|
|
|
plen = 0, |
|
|
|
|
out_pre_spaces = 0, |
|
|
|
|
sign = 0; |
|
|
|
|
char *numstr, |
|
|
|
|
*orgnum, |
|
|
|
|
@ -5388,6 +5406,7 @@ float8_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
int numstr_pre_len; |
|
|
|
|
float8 val = value; |
|
|
|
|
|
|
|
|
|
if (IS_MULTI(&Num)) |
|
|
|
|
@ -5398,13 +5417,13 @@ float8_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
Num.pre += Num.multi; |
|
|
|
|
} |
|
|
|
|
orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1); |
|
|
|
|
len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.0f", fabs(val)); |
|
|
|
|
if (Num.pre > len) |
|
|
|
|
plen = Num.pre - len; |
|
|
|
|
if (len >= DBL_DIG) |
|
|
|
|
numstr_pre_len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.0f", fabs(val)); |
|
|
|
|
|
|
|
|
|
/* adjust post digits to fit max double digits */ |
|
|
|
|
if (numstr_pre_len >= DBL_DIG) |
|
|
|
|
Num.post = 0; |
|
|
|
|
else if (Num.post + len > DBL_DIG) |
|
|
|
|
Num.post = DBL_DIG - len; |
|
|
|
|
else if (numstr_pre_len + Num.post > DBL_DIG) |
|
|
|
|
Num.post = DBL_DIG - numstr_pre_len; |
|
|
|
|
snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*f", Num.post, val); |
|
|
|
|
|
|
|
|
|
if (*orgnum == '-') |
|
|
|
|
@ -5417,14 +5436,17 @@ float8_to_char(PG_FUNCTION_ARGS) |
|
|
|
|
sign = '+'; |
|
|
|
|
numstr = orgnum; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((p = strchr(numstr, '.'))) |
|
|
|
|
len = p - numstr; |
|
|
|
|
numstr_pre_len = p - numstr; |
|
|
|
|
else |
|
|
|
|
len = strlen(numstr); |
|
|
|
|
numstr_pre_len = strlen(numstr); |
|
|
|
|
|
|
|
|
|
if (Num.pre > len) |
|
|
|
|
plen = Num.pre - len; |
|
|
|
|
else if (len > Num.pre) |
|
|
|
|
/* needs padding? */ |
|
|
|
|
if (numstr_pre_len < Num.pre) |
|
|
|
|
out_pre_spaces = Num.pre - numstr_pre_len; |
|
|
|
|
/* overflowed prefix digit format? */ |
|
|
|
|
else if (numstr_pre_len > Num.pre) |
|
|
|
|
{ |
|
|
|
|
numstr = (char *) palloc(Num.pre + Num.post + 2); |
|
|
|
|
fill_str(numstr, '#', Num.pre + Num.post + 1); |
|
|
|
|
|