to_char(numeric) overflow return ########

This commit is contained in:
JulianZhang
2024-11-07 16:08:03 +08:00
parent 058fa062e7
commit 57589b382e
4 changed files with 297 additions and 14 deletions

View File

@ -6566,6 +6566,10 @@ static char* NUM_processor(FormatNode* node, NUMDesc* Num, char* inout, char* nu
*/ \
len = strlen(VARDATA(result)); \
SET_VARSIZE(result, len + VARHDRSZ); \
/* In A compatibility, all we need for overflow num is a pure "###" style str */ \
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && overflow) { \
fill_str(VARDATA(result), '#', len); \
} \
} while (0)
@ -6890,6 +6894,7 @@ Datum numeric_to_char(PG_FUNCTION_ARGS)
FormatNode* format = NULL;
text* result = NULL;
bool shouldFree = false;
bool overflow = false;
int len = 0, plen = 0, sign = 0;
char *numstr = NULL, *orgnum = NULL, *p = NULL;
Numeric x;
@ -6975,9 +6980,13 @@ Datum numeric_to_char(PG_FUNCTION_ARGS)
if (Num.pre > len)
plen = Num.pre - len;
else if (len > Num.pre) {
numstr = (char*)palloc(Num.pre + Num.post + 2);
fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
overflow = true;
// if overflow when A_FORMAT, do fill_str later.
if (u_sess->attr.attr_sql.sql_compatibility != A_FORMAT) {
numstr = (char*)palloc(Num.pre + Num.post + 2);
fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
}
}
}
@ -7004,6 +7013,7 @@ Datum int4_to_char(PG_FUNCTION_ARGS)
FormatNode* format = NULL;
text* result = NULL;
bool shouldFree = false;
bool overflow = false;
int len = 0, plen = 0, sign = 0;
char *numstr = NULL, *orgnum = NULL;
errno_t ret = EOK;
@ -7073,9 +7083,12 @@ Datum int4_to_char(PG_FUNCTION_ARGS)
if (Num.pre > len)
plen = Num.pre - len;
else if (len > Num.pre) {
numstr = (char*)palloc(Num.pre + Num.post + 2);
fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
overflow = true;
if (u_sess->attr.attr_sql.sql_compatibility != A_FORMAT) {
numstr = (char*)palloc(Num.pre + Num.post + 2);
fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
}
}
}
@ -7095,6 +7108,7 @@ Datum int8_to_char(PG_FUNCTION_ARGS)
FormatNode* format = NULL;
text* result = NULL;
bool shouldFree = false;
bool overflow = false;
int len = 0, plen = 0, sign = 0;
char *numstr = NULL, *orgnum = NULL;
errno_t ret = EOK;
@ -7174,8 +7188,11 @@ Datum int8_to_char(PG_FUNCTION_ARGS)
if (Num.pre > len)
plen = Num.pre - len;
else if (len > Num.pre) {
numstr = (char*)palloc(Num.pre + Num.post + 2);
fill_str(numstr, '#', Num.pre + Num.post + 1);
overflow = true;
if (u_sess->attr.attr_sql.sql_compatibility != A_FORMAT) {
numstr = (char*)palloc(Num.pre + Num.post + 2);
fill_str(numstr, '#', Num.pre + Num.post + 1);
}
}
}
@ -7195,6 +7212,7 @@ Datum float4_to_char(PG_FUNCTION_ARGS)
FormatNode* format = NULL;
text* result = NULL;
bool shouldFree = false;
bool overflow = false;
int len = 0, plen = 0, sign = 0;
char *numstr = NULL, *orgnum = NULL, *p = NULL;
errno_t ret = EOK;
@ -7282,8 +7300,11 @@ Datum float4_to_char(PG_FUNCTION_ARGS)
if (Num.pre > len)
plen = Num.pre - len;
else if (len > Num.pre) {
numstr = (char*)palloc(Num.pre + Num.post + 2);
fill_str(numstr, '#', Num.pre + Num.post + 1);
overflow = true;
if (u_sess->attr.attr_sql.sql_compatibility != A_FORMAT) {
numstr = (char*)palloc(Num.pre + Num.post + 2);
fill_str(numstr, '#', Num.pre + Num.post + 1);
}
}
}
@ -7303,6 +7324,7 @@ Datum float8_to_char(PG_FUNCTION_ARGS)
FormatNode* format = NULL;
text* result = NULL;
bool shouldFree = false;
bool overflow = false;
int len = 0, plen = 0, sign = 0;
char *numstr = NULL, *orgnum = NULL, *p = NULL;
errno_t ret = EOK;
@ -7390,9 +7412,12 @@ Datum float8_to_char(PG_FUNCTION_ARGS)
if (Num.pre > len)
plen = Num.pre - len;
else if (len > Num.pre) {
numstr = (char*)palloc(Num.pre + Num.post + 2);
fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
overflow = true;
if (u_sess->attr.attr_sql.sql_compatibility != A_FORMAT) {
numstr = (char*)palloc(Num.pre + Num.post + 2);
fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
}
}
}

View File

@ -0,0 +1,217 @@
-- to_char overflow case test
select to_char( 127::int4, '999');
to_char
---------
127
(1 row)
select to_char( 126::int8, '999');
to_char
---------
126
(1 row)
select to_char( 125.7::float4, '999D9');
to_char
---------
125.7
(1 row)
select to_char( 125.9::float8, '999D9');
to_char
---------
125.9
(1 row)
select to_char( 125.9::numeric, '999D9');
to_char
---------
125.9
(1 row)
select to_char( 8e2, '999D9');
to_char
---------
800.0
(1 row)
select to_char( 125.9::float8, '999.999');
to_char
----------
125.900
(1 row)
select to_char( 125.9::numeric, '999.999');
to_char
----------
125.900
(1 row)
select to_char( 8e2, '999.999');
to_char
----------
800.000
(1 row)
select to_char( -127::int4, '999');
to_char
---------
-127
(1 row)
select to_char( -126::int8, '999');
to_char
---------
-126
(1 row)
select to_char( -125.7::float4, '999D9');
to_char
---------
-125.7
(1 row)
select to_char( -125.9::float8, '999D9');
to_char
---------
-125.9
(1 row)
select to_char( -125.9::numeric, '999D9');
to_char
---------
-125.9
(1 row)
select to_char( -8e2, '999D9');
to_char
---------
-800.0
(1 row)
select to_char( -125.9::float8, '999.999');
to_char
----------
-125.900
(1 row)
select to_char( -125.9::numeric, '999.999');
to_char
----------
-125.900
(1 row)
select to_char( -8e2, '999.999');
to_char
----------
-800.000
(1 row)
select to_char( 1287::int4, '999');
to_char
---------
####
(1 row)
select to_char( 1286::int8, '999');
to_char
---------
####
(1 row)
select to_char( 1285.7888::float4, '999D9');
to_char
---------
######
(1 row)
select to_char( 1285.9888::float8, '999D9');
to_char
---------
######
(1 row)
select to_char( 1285.8889::numeric, '999D9');
to_char
---------
######
(1 row)
select to_char( 8e99, '999D9');
to_char
---------
######
(1 row)
select to_char( 1285.9888::float8, '999.999');
to_char
----------
########
(1 row)
select to_char( 1285.8889::numeric, '999.999');
to_char
----------
########
(1 row)
select to_char( 8e99, '999.999');
to_char
----------
########
(1 row)
select to_char( -1287::int4, '999');
to_char
---------
####
(1 row)
select to_char( -1286::int8, '999');
to_char
---------
####
(1 row)
select to_char( -1285.7888::float4, '999D9');
to_char
---------
######
(1 row)
select to_char( -1285.9888::float8, '999D9');
to_char
---------
######
(1 row)
select to_char( -1285.8889::numeric, '999D9');
to_char
---------
######
(1 row)
select to_char( -8e99, '999D9');
to_char
---------
######
(1 row)
select to_char( -1285.9888::float8, '999.999');
to_char
----------
########
(1 row)
select to_char( -1285.8889::numeric, '999.999');
to_char
----------
########
(1 row)
select to_char( -8e99, '999.999');
to_char
----------
########
(1 row)

View File

@ -167,7 +167,7 @@ test: vec_mergejoin_aggregation llvm_vecagg llvm_vecagg2 llvm_vecagg3 llvm_vecha
# ----------$
# The first group of parallel tests$
# ----------$
test: boolean name oid bit txid uuid numeric_hide_tailing_zero rawlike
test: boolean name oid bit txid uuid numeric_hide_tailing_zero rawlike to_char
#test: float8 numeric char varchar text int2 int4 float4 numeric_2 money
# Depends on things setup during char, varchar and text

View File

@ -0,0 +1,41 @@
-- to_char overflow case test
select to_char( 127::int4, '999');
select to_char( 126::int8, '999');
select to_char( 125.7::float4, '999D9');
select to_char( 125.9::float8, '999D9');
select to_char( 125.9::numeric, '999D9');
select to_char( 8e2, '999D9');
select to_char( 125.9::float8, '999.999');
select to_char( 125.9::numeric, '999.999');
select to_char( 8e2, '999.999');
select to_char( -127::int4, '999');
select to_char( -126::int8, '999');
select to_char( -125.7::float4, '999D9');
select to_char( -125.9::float8, '999D9');
select to_char( -125.9::numeric, '999D9');
select to_char( -8e2, '999D9');
select to_char( -125.9::float8, '999.999');
select to_char( -125.9::numeric, '999.999');
select to_char( -8e2, '999.999');
select to_char( 1287::int4, '999');
select to_char( 1286::int8, '999');
select to_char( 1285.7888::float4, '999D9');
select to_char( 1285.9888::float8, '999D9');
select to_char( 1285.8889::numeric, '999D9');
select to_char( 8e99, '999D9');
select to_char( 1285.9888::float8, '999.999');
select to_char( 1285.8889::numeric, '999.999');
select to_char( 8e99, '999.999');
select to_char( -1287::int4, '999');
select to_char( -1286::int8, '999');
select to_char( -1285.7888::float4, '999D9');
select to_char( -1285.9888::float8, '999D9');
select to_char( -1285.8889::numeric, '999D9');
select to_char( -8e99, '999D9');
select to_char( -1285.9888::float8, '999.999');
select to_char( -1285.8889::numeric, '999.999');
select to_char( -8e99, '999.999');