numeric_maximum_size.patch
application/octet-stream
Filename: numeric_maximum_size.patch
Type: application/octet-stream
Part: 0
Message:
Re: reducing NUMERIC size for 9.1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/utils/adt/numeric.c | 21 | 2 |
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 2568fdc..e6281bc 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -568,6 +568,7 @@ int32
numeric_maximum_size(int32 typemod)
{
int precision;
+ int numeric_digits;
if (typemod <= VARHDRSZ)
return -1;
@@ -575,8 +576,26 @@ numeric_maximum_size(int32 typemod)
/* precision (ie, max # of digits) is in upper bits of typmod */
precision = ((typemod - VARHDRSZ) >> 16) & 0xffff;
- /* Numeric stores 2 decimal digits/byte, plus header */
- return (precision + 1) / 2 + NUMERIC_HDRSZ;
+ /*
+ * This formula computes the maximum number of NumericDigits we could
+ * need in order to store the specified number of decimal digits.
+ * Because the weight is stored as a number of NumericDigits rather
+ * than a number of decimal digits, it's possible that the first
+ * NumericDigit will contain only a single decimal digit. Thus, the
+ * first two decimal digits can require two NumericDigits to store,
+ * but it isn't until we reach DEC_DIGITS + 2 decimal digits that we
+ * potentially need a third NumericDigit.
+ */
+ numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
+
+ /*
+ * In most cases, the size of a numeric will be smaller than the value
+ * computed below, because the varlena header will typically get toasted
+ * down to a single byte before being stored on disk, and it may also
+ * be possible to use a short numeric header. But our job here is to
+ * compute the worst case.
+ */
+ return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
}
/*