fasternumeric_20121112_v2.patch
text/x-patch
Filename: fasternumeric_20121112_v2.patch
Type: text/x-patch
Part: 0
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
Series: patch v2
| File | + | − |
|---|---|---|
| src/backend/utils/adt/numeric.c | 42 | 52 |
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 68c1f1d..fcff325 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -367,6 +367,7 @@ static void zero_var(NumericVar *var);
static const char *set_var_from_str(const char *str, const char *cp,
NumericVar *dest);
static void set_var_from_num(Numeric value, NumericVar *dest);
+static void set_var_from_num_nocopy(Numeric num, NumericVar *dest);
static void set_var_from_var(NumericVar *value, NumericVar *dest);
static char *get_str_from_var(NumericVar *var, int dscale);
static char *get_str_from_var_sci(NumericVar *var, int rscale);
@@ -617,11 +618,10 @@ numeric_out_sci(Numeric num, int scale)
return pstrdup("NaN");
init_var(&x);
- set_var_from_num(num, &x);
+ set_var_from_num_nocopy(num, &x);
str = get_str_from_var_sci(&x, scale);
- free_var(&x);
return str;
}
@@ -696,7 +696,7 @@ numeric_send(PG_FUNCTION_ARGS)
int i;
init_var(&x);
- set_var_from_num(num, &x);
+ set_var_from_num_nocopy(num, &x);
pq_begintypsend(&buf);
@@ -707,8 +707,6 @@ numeric_send(PG_FUNCTION_ARGS)
for (i = 0; i < x.ndigits; i++)
pq_sendint(&buf, x.digits[i], sizeof(NumericDigit));
- free_var(&x);
-
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
@@ -1577,15 +1575,13 @@ numeric_add(PG_FUNCTION_ARGS)
init_var(&arg2);
init_var(&result);
- set_var_from_num(num1, &arg1);
- set_var_from_num(num2, &arg2);
+ set_var_from_num_nocopy(num1, &arg1);
+ set_var_from_num_nocopy(num2, &arg2);
add_var(&arg1, &arg2, &result);
res = make_result(&result);
- free_var(&arg1);
- free_var(&arg2);
free_var(&result);
PG_RETURN_NUMERIC(res);
@@ -1620,15 +1616,13 @@ numeric_sub(PG_FUNCTION_ARGS)
init_var(&arg2);
init_var(&result);
- set_var_from_num(num1, &arg1);
- set_var_from_num(num2, &arg2);
+ set_var_from_num_nocopy(num1, &arg1);
+ set_var_from_num_nocopy(num2, &arg2);
sub_var(&arg1, &arg2, &result);
res = make_result(&result);
- free_var(&arg1);
- free_var(&arg2);
free_var(&result);
PG_RETURN_NUMERIC(res);
@@ -1667,15 +1661,13 @@ numeric_mul(PG_FUNCTION_ARGS)
init_var(&arg2);
init_var(&result);
- set_var_from_num(num1, &arg1);
- set_var_from_num(num2, &arg2);
+ set_var_from_num_nocopy(num1, &arg1);
+ set_var_from_num_nocopy(num2, &arg2);
mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
res = make_result(&result);
- free_var(&arg1);
- free_var(&arg2);
free_var(&result);
PG_RETURN_NUMERIC(res);
@@ -1711,8 +1703,8 @@ numeric_div(PG_FUNCTION_ARGS)
init_var(&arg2);
init_var(&result);
- set_var_from_num(num1, &arg1);
- set_var_from_num(num2, &arg2);
+ set_var_from_num_nocopy(num1, &arg1);
+ set_var_from_num_nocopy(num2, &arg2);
/*
* Select scale for division result
@@ -1726,8 +1718,6 @@ numeric_div(PG_FUNCTION_ARGS)
res = make_result(&result);
- free_var(&arg1);
- free_var(&arg2);
free_var(&result);
PG_RETURN_NUMERIC(res);
@@ -1762,8 +1752,8 @@ numeric_div_trunc(PG_FUNCTION_ARGS)
init_var(&arg2);
init_var(&result);
- set_var_from_num(num1, &arg1);
- set_var_from_num(num2, &arg2);
+ set_var_from_num_nocopy(num1, &arg1);
+ set_var_from_num_nocopy(num2, &arg2);
/*
* Do the divide and return the result
@@ -1772,8 +1762,6 @@ numeric_div_trunc(PG_FUNCTION_ARGS)
res = make_result(&result);
- free_var(&arg1);
- free_var(&arg2);
free_var(&result);
PG_RETURN_NUMERIC(res);
@@ -1802,15 +1790,13 @@ numeric_mod(PG_FUNCTION_ARGS)
init_var(&arg2);
init_var(&result);
- set_var_from_num(num1, &arg1);
- set_var_from_num(num2, &arg2);
+ set_var_from_num_nocopy(num1, &arg1);
+ set_var_from_num_nocopy(num2, &arg2);
mod_var(&arg1, &arg2, &result);
res = make_result(&result);
- free_var(&result);
- free_var(&arg2);
free_var(&arg1);
PG_RETURN_NUMERIC(res);
@@ -1980,7 +1966,7 @@ numeric_sqrt(PG_FUNCTION_ARGS)
init_var(&arg);
init_var(&result);
- set_var_from_num(num, &arg);
+ set_var_from_num_nocopy(num, &arg);
/* Assume the input was normalized, so arg.weight is accurate */
sweight = (arg.weight + 1) * DEC_DIGITS / 2 - 1;
@@ -1998,7 +1984,6 @@ numeric_sqrt(PG_FUNCTION_ARGS)
res = make_result(&result);
free_var(&result);
- free_var(&arg);
PG_RETURN_NUMERIC(res);
}
@@ -2033,7 +2018,7 @@ numeric_exp(PG_FUNCTION_ARGS)
init_var(&arg);
init_var(&result);
- set_var_from_num(num, &arg);
+ set_var_from_num_nocopy(num, &arg);
/* convert input to float8, ignoring overflow */
val = numericvar_to_double_no_overflow(&arg);
@@ -2061,7 +2046,6 @@ numeric_exp(PG_FUNCTION_ARGS)
res = make_result(&result);
free_var(&result);
- free_var(&arg);
PG_RETURN_NUMERIC(res);
}
@@ -2091,7 +2075,7 @@ numeric_ln(PG_FUNCTION_ARGS)
init_var(&arg);
init_var(&result);
- set_var_from_num(num, &arg);
+ set_var_from_num_nocopy(num, &arg);
/* Approx decimal digits before decimal point */
dec_digits = (arg.weight + 1) * DEC_DIGITS;
@@ -2112,7 +2096,6 @@ numeric_ln(PG_FUNCTION_ARGS)
res = make_result(&result);
free_var(&result);
- free_var(&arg);
PG_RETURN_NUMERIC(res);
}
@@ -2146,8 +2129,8 @@ numeric_log(PG_FUNCTION_ARGS)
init_var(&arg2);
init_var(&result);
- set_var_from_num(num1, &arg1);
- set_var_from_num(num2, &arg2);
+ set_var_from_num_nocopy(num1, &arg1);
+ set_var_from_num_nocopy(num2, &arg2);
/*
* Call log_var() to compute and return the result; note it handles scale
@@ -2158,8 +2141,6 @@ numeric_log(PG_FUNCTION_ARGS)
res = make_result(&result);
free_var(&result);
- free_var(&arg2);
- free_var(&arg1);
PG_RETURN_NUMERIC(res);
}
@@ -2195,8 +2176,8 @@ numeric_power(PG_FUNCTION_ARGS)
init_var(&arg2_trunc);
init_var(&result);
- set_var_from_num(num1, &arg1);
- set_var_from_num(num2, &arg2);
+ set_var_from_num_nocopy(num1, &arg1);
+ set_var_from_num_nocopy(num2, &arg2);
set_var_from_var(&arg2, &arg2_trunc);
trunc_var(&arg2_trunc, 0);
@@ -2227,9 +2208,7 @@ numeric_power(PG_FUNCTION_ARGS)
res = make_result(&result);
free_var(&result);
- free_var(&arg2);
free_var(&arg2_trunc);
- free_var(&arg1);
PG_RETURN_NUMERIC(res);
}
@@ -2277,9 +2256,8 @@ numeric_int4(PG_FUNCTION_ARGS)
/* Convert to variable format, then convert to int4 */
init_var(&x);
- set_var_from_num(num, &x);
+ set_var_from_num_nocopy(num, &x);
result = numericvar_to_int4(&x);
- free_var(&x);
PG_RETURN_INT32(result);
}
@@ -2400,8 +2378,6 @@ numeric_int2(PG_FUNCTION_ARGS)
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("smallint out of range")));
- free_var(&x);
-
/* Down-convert to int2 */
result = (int16) val;
@@ -2411,6 +2387,8 @@ numeric_int2(PG_FUNCTION_ARGS)
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("smallint out of range")));
+ free_var(&x);
+
PG_RETURN_INT16(result);
}
@@ -2764,7 +2742,7 @@ numeric_stddev_internal(ArrayType *transarray,
return make_result(&const_nan);
init_var(&vN);
- set_var_from_num(N, &vN);
+ set_var_from_num_nocopy(N, &vN);
/*
* Sample stddev and variance are undefined when N <= 1; population stddev
@@ -2777,7 +2755,6 @@ numeric_stddev_internal(ArrayType *transarray,
if (cmp_var(&vN, comp) <= 0)
{
- free_var(&vN);
*is_null = true;
return NULL;
}
@@ -2786,7 +2763,7 @@ numeric_stddev_internal(ArrayType *transarray,
sub_var(&vN, &const_one, &vNminus1);
init_var(&vsumX);
- set_var_from_num(sumX, &vsumX);
+ set_var_from_num_nocopy(sumX, &vsumX);
init_var(&vsumX2);
set_var_from_num(sumX2, &vsumX2);
@@ -2816,9 +2793,7 @@ numeric_stddev_internal(ArrayType *transarray,
res = make_result(&vsumX);
}
- free_var(&vN);
free_var(&vNminus1);
- free_var(&vsumX);
free_var(&vsumX2);
return res;
@@ -3448,6 +3423,21 @@ set_var_from_num(Numeric num, NumericVar *dest)
memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
}
+/*
+ * set_var_from_num_nocopy() -
+ *
+ * Convert the packed db format into a variable - without copying digits
+ */
+static void
+set_var_from_num_nocopy(Numeric num, NumericVar *dest)
+{
+ dest->ndigits = NUMERIC_NDIGITS(num);
+ dest->weight = NUMERIC_WEIGHT(num);
+ dest->sign = NUMERIC_SIGN(num);
+ dest->dscale = NUMERIC_DSCALE(num);
+ dest->digits = NUMERIC_DIGITS(num);
+}
+
/*
* set_var_from_var() -