Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7e01c8e

Browse files
committed
Remove bogus dependencies on NUMERIC_MAX_PRECISION.
NUMERIC_MAX_PRECISION is a purely arbitrary constraint on the precisionand scale you can write in a numeric typmod. It might once have hadsomething to do with the allowed range of a typmod-less numeric value,but at least since 9.1 we've allowed, and documented that we allowed,any value that would physically fit in the numeric storage format;which is something over 100000 decimal digits, not 1000.Hence, get rid of numeric_in()'s use of NUMERIC_MAX_PRECISION as a limiton the allowed range of the exponent in scientific-format input. That wasespecially silly in view of the fact that you can enter larger numbers aslong as you don't use 'e' to do it. Just constrain the value enough toavoid localized overflow, and let make_result be the final arbiter of whatis too large. Likewise adjust ecpg's equivalent of this code.Also get rid of numeric_recv()'s use of NUMERIC_MAX_PRECISION to limit thenumber of base-NBASE digits it would accept. That created a dump/restorehazard for binary COPY without doing anything useful; the wire-formatlimit on number of digits (65535) is about as tight as we would want.In HEAD, also get rid of pg_size_bytes()'s unnecessary intimacy with whatthe numeric range limit is. That code doesn't exist in the back branches.Per gripe from Aravind Kumar. Back-patch to all supported branches,since they all contain the documentation claim about allowed range ofNUMERIC (cf commitcabf5d8).Discussion: <2895.1471195721@sss.pgh.pa.us>
1 parent99396e6 commit7e01c8e

File tree

3 files changed

+16
-13
lines changed

3 files changed

+16
-13
lines changed

‎src/backend/utils/adt/numeric.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -648,10 +648,6 @@ numeric_recv(PG_FUNCTION_ARGS)
648648
init_var(&value);
649649

650650
len= (uint16)pq_getmsgint(buf,sizeof(uint16));
651-
if (len<0||len>NUMERIC_MAX_PRECISION+NUMERIC_MAX_RESULT_SCALE)
652-
ereport(ERROR,
653-
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
654-
errmsg("invalid length in external \"numeric\" value")));
655651

656652
alloc_var(&value,len);
657653

@@ -3338,12 +3334,19 @@ set_var_from_str(const char *str, const char *cp, NumericVar *dest)
33383334
errmsg("invalid input syntax for type numeric: \"%s\"",
33393335
str)));
33403336
cp=endptr;
3341-
if (exponent>NUMERIC_MAX_PRECISION||
3342-
exponent<-NUMERIC_MAX_PRECISION)
3337+
3338+
/*
3339+
* At this point, dweight and dscale can't be more than about
3340+
* INT_MAX/2 due to the MaxAllocSize limit on string length, so
3341+
* constraining the exponent similarly should be enough to prevent
3342+
* integer overflow in this function. If the value is too large to
3343+
* fit in storage format, make_result() will complain about it later;
3344+
* for consistency use the same ereport errcode/text as make_result().
3345+
*/
3346+
if (exponent >=INT_MAX /2||exponent <=-(INT_MAX /2))
33433347
ereport(ERROR,
3344-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3345-
errmsg("invalid input syntax for type numeric: \"%s\"",
3346-
str)));
3348+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3349+
errmsg("value overflows numeric format")));
33473350
dweight+= (int)exponent;
33483351
dscale-= (int)exponent;
33493352
if (dscale<0)

‎src/include/utils/numeric.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
#include"fmgr.h"
1818

1919
/*
20-
* Hardcoded precision limit - arbitrary, but must be small enough that
21-
* dscale values will fit in 14 bits.
20+
* Limit on the precision (and hence scale) specifiable in a NUMERIC typmod.
21+
* Note that the implementation limit on the length of a numeric value is
22+
* much larger --- beware of what you use this for!
2223
*/
2324
#defineNUMERIC_MAX_PRECISION1000
2425

‎src/interfaces/ecpg/pgtypeslib/numeric.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,7 @@ set_var_from_str(char *str, char **ptr, numeric *dest)
263263
return-1;
264264
}
265265
(*ptr)=endptr;
266-
if (exponent>NUMERIC_MAX_PRECISION||
267-
exponent<-NUMERIC_MAX_PRECISION)
266+
if (exponent >=INT_MAX /2||exponent <=-(INT_MAX /2))
268267
{
269268
errno=PGTYPES_NUM_BAD_NUMERIC;
270269
return-1;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp