diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index a83feea396..57d117fccb 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -301,6 +301,7 @@ struct NumericData * This is feasible because the digit buffer is separate from the variable. * ---------- */ +#define FIXED_BUF_LEN 4 typedef struct NumericVar { int ndigits; /* # of digits in digits[] - can be 0! */ @@ -309,6 +310,7 @@ typedef struct NumericVar int dscale; /* display scale */ NumericDigit *buf; /* start of palloc'd space for digits[] */ NumericDigit *digits; /* base-NBASE digits */ + NumericDigit fixed_buf[FIXED_BUF_LEN]; } NumericVar; @@ -414,18 +416,18 @@ typedef struct NumericSumAccum */ static const NumericDigit const_zero_data[1] = {0}; static const NumericVar const_zero = -{0, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_zero_data}; +{0, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_zero_data, {0}}; static const NumericDigit const_one_data[1] = {1}; static const NumericVar const_one = -{1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_one_data}; +{1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_one_data, {0}}; static const NumericVar const_minus_one = -{1, 0, NUMERIC_NEG, 0, NULL, (NumericDigit *) const_one_data}; +{1, 0, NUMERIC_NEG, 0, NULL, (NumericDigit *) const_one_data, {0}}; static const NumericDigit const_two_data[1] = {2}; static const NumericVar const_two = -{1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_two_data}; +{1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_two_data, {0}}; #if DEC_DIGITS == 4 static const NumericDigit const_zero_point_nine_data[1] = {9000}; @@ -435,7 +437,7 @@ static const NumericDigit const_zero_point_nine_data[1] = {90}; static const NumericDigit const_zero_point_nine_data[1] = {9}; #endif static const NumericVar const_zero_point_nine = -{1, -1, NUMERIC_POS, 1, NULL, (NumericDigit *) const_zero_point_nine_data}; +{1, -1, NUMERIC_POS, 1, NULL, (NumericDigit *) const_zero_point_nine_data, {0}}; #if DEC_DIGITS == 4 static const NumericDigit const_one_point_one_data[2] = {1, 1000}; @@ -445,16 +447,16 @@ static const NumericDigit const_one_point_one_data[2] = {1, 10}; static const NumericDigit const_one_point_one_data[2] = {1, 1}; #endif static const NumericVar const_one_point_one = -{2, 0, NUMERIC_POS, 1, NULL, (NumericDigit *) const_one_point_one_data}; +{2, 0, NUMERIC_POS, 1, NULL, (NumericDigit *) const_one_point_one_data, {0}}; static const NumericVar const_nan = -{0, 0, NUMERIC_NAN, 0, NULL, NULL}; +{0, 0, NUMERIC_NAN, 0, NULL, NULL, {0}}; static const NumericVar const_pinf = -{0, 0, NUMERIC_PINF, 0, NULL, NULL}; +{0, 0, NUMERIC_PINF, 0, NULL, NULL, {0}}; static const NumericVar const_ninf = -{0, 0, NUMERIC_NINF, 0, NULL, NULL}; +{0, 0, NUMERIC_NINF, 0, NULL, NULL, {0}}; #if DEC_DIGITS == 4 static const int round_powers[4] = {0, 1000, 100, 10}; @@ -6872,9 +6874,18 @@ static void alloc_var(NumericVar *var, int ndigits) { digitbuf_free(var->buf); - var->buf = digitbuf_alloc(ndigits + 1); - var->buf[0] = 0; /* spare digit for rounding */ - var->digits = var->buf + 1; + init_var(var); + if (ndigits + 1 < FIXED_BUF_LEN) + { + var->fixed_buf[0] = 0; /* spare digit for rounding */ + var->digits = var->fixed_buf + 1; + } + else + { + var->buf = digitbuf_alloc(ndigits + 1); + var->buf[0] = 0; /* spare digit for rounding */ + var->digits = var->buf + 1; + } var->ndigits = ndigits; }