From fd5e1ccffe2c1aa1c619fb0f31389f35fe554e5b Mon Sep 17 00:00:00 2001 From: Amul Sul Date: Fri, 22 Apr 2022 06:17:51 -0400 Subject: [PATCH v2 5/5] Call numeric arithmetic functions directly --- contrib/btree_gist/btree_numeric.c | 17 +++------ src/backend/access/brin/brin_minmax_multi.c | 14 ++++---- src/backend/utils/adt/cash.c | 15 ++++---- src/backend/utils/adt/dbsize.c | 33 +++++++++-------- src/backend/utils/adt/formatting.c | 15 ++++---- src/backend/utils/adt/jsonb.c | 7 ++-- src/backend/utils/adt/numeric.c | 39 +++++++++++---------- src/backend/utils/adt/pg_lsn.c | 16 ++++----- src/backend/utils/adt/rangetypes.c | 10 +++--- 9 files changed, 80 insertions(+), 86 deletions(-) diff --git a/contrib/btree_gist/btree_numeric.c b/contrib/btree_gist/btree_numeric.c index 35e466cdd94..6c50cfa41f2 100644 --- a/contrib/btree_gist/btree_numeric.c +++ b/contrib/btree_gist/btree_numeric.c @@ -174,17 +174,10 @@ gbt_numeric_penalty(PG_FUNCTION_ARGS) ok = gbt_var_key_readable(org); uk = gbt_var_key_readable((GBT_VARKEY *) DatumGetPointer(uni)); - us = DatumGetNumeric(DirectFunctionCall2(numeric_sub, - PointerGetDatum(uk.upper), - PointerGetDatum(uk.lower))); + us = numeric_sub_opt_error((Numeric) uk.upper, (Numeric) uk.lower, NULL); + os = numeric_sub_opt_error((Numeric) ok.upper, (Numeric) ok.lower, NULL); - os = DatumGetNumeric(DirectFunctionCall2(numeric_sub, - PointerGetDatum(ok.upper), - PointerGetDatum(ok.lower))); - - ds = DatumGetNumeric(DirectFunctionCall2(numeric_sub, - NumericGetDatum(us), - NumericGetDatum(os))); + ds = numeric_sub_opt_error(us, os, NULL); if (numeric_is_nan(us)) { @@ -202,9 +195,7 @@ gbt_numeric_penalty(PG_FUNCTION_ARGS) if (DirectFunctionCall2(numeric_gt, NumericGetDatum(ds), NumericGetDatum(nul))) { *result += FLT_MIN; - os = DatumGetNumeric(DirectFunctionCall2(numeric_div, - NumericGetDatum(ds), - NumericGetDatum(us))); + os = numeric_div_opt_error(ds, us, NULL); *result += (float4) DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow, NumericGetDatum(os))); } } diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c index 764efa381f2..c84a70d1ad9 100644 --- a/src/backend/access/brin/brin_minmax_multi.c +++ b/src/backend/access/brin/brin_minmax_multi.c @@ -2008,19 +2008,21 @@ brin_minmax_multi_distance_tid(PG_FUNCTION_ARGS) Datum brin_minmax_multi_distance_numeric(PG_FUNCTION_ARGS) { - Datum d; - Datum a1 = PG_GETARG_DATUM(0); - Datum a2 = PG_GETARG_DATUM(1); + Numeric res; + Numeric a1 = PG_GETARG_NUMERIC(0); + Numeric a2 = PG_GETARG_NUMERIC(1); /* * We know the values are range boundaries, but the range may be collapsed * (i.e. single points), with equal values. */ - Assert(DatumGetBool(DirectFunctionCall2(numeric_le, a1, a2))); + Assert(DatumGetBool(DirectFunctionCall2(numeric_le, + NumericGetDatum(a1), + NumericGetDatum(a2)))); - d = DirectFunctionCall2(numeric_sub, a2, a1); /* a2 - a1 */ + res = numeric_sub_opt_error(a2, a1, NULL); /* a2 - a1 */ - PG_RETURN_FLOAT8(numeric_to_float8(DatumGetNumeric(d))); + PG_RETURN_FLOAT8(numeric_to_float8(res)); } /* diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c index d05335dbd47..81f4eceee9c 100644 --- a/src/backend/utils/adt/cash.c +++ b/src/backend/utils/adt/cash.c @@ -1069,7 +1069,10 @@ cash_numeric(PG_FUNCTION_ARGS) Int32GetDatum(fpoint)); /* Now we can safely divide ... */ - quotient = DirectFunctionCall2(numeric_div, result, numeric_scale); + quotient = + NumericGetDatum(numeric_div_opt_error(DatumGetNumeric(result), + DatumGetNumeric(numeric_scale), + NULL)); /* ... and forcibly round to exactly the intended number of digits */ result = DirectFunctionCall2(numeric_round, @@ -1086,12 +1089,12 @@ cash_numeric(PG_FUNCTION_ARGS) Datum numeric_cash(PG_FUNCTION_ARGS) { - Datum amount = PG_GETARG_DATUM(0); + Numeric amount = PG_GETARG_NUMERIC(0); Cash result; int fpoint; int64 scale; int i; - Datum numeric_scale; + Numeric numeric_scale; struct lconv *lconvert = PGLC_localeconv(); /* see comments about frac_digits in cash_in() */ @@ -1105,11 +1108,11 @@ numeric_cash(PG_FUNCTION_ARGS) scale *= 10; /* multiply the input amount by scale factor */ - numeric_scale = NumericGetDatum(int64_to_numeric(scale)); - amount = DirectFunctionCall2(numeric_mul, amount, numeric_scale); + numeric_scale = int64_to_numeric(scale); + amount = numeric_mul_opt_error(amount, numeric_scale, NULL); /* note that numeric_to_int64 will round to nearest integer for us */ - result = numeric_to_int64_type(DatumGetNumeric(amount), "money"); + result = numeric_to_int64_type(amount, "money"); PG_RETURN_CASH(result); } diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index afd6a7ab623..10675d19bcb 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -620,22 +620,29 @@ numeric_absolute(Numeric n) static Numeric numeric_half_rounded(Numeric n) { - Datum d = NumericGetDatum(n); - Datum zero; - Datum one; - Datum two; + Numeric d; + Numeric zero; + Numeric one; + Numeric two; Datum result; + bool gt; + + zero = int64_to_numeric(0); + one = int64_to_numeric(1); + two = int64_to_numeric(2); - zero = NumericGetDatum(int64_to_numeric(0)); - one = NumericGetDatum(int64_to_numeric(1)); - two = NumericGetDatum(int64_to_numeric(2)); + gt = DatumGetBool(DirectFunctionCall2(numeric_ge, + NumericGetDatum(n), + NumericGetDatum(zero))); - if (DatumGetBool(DirectFunctionCall2(numeric_ge, d, zero))) - d = DirectFunctionCall2(numeric_add, d, one); + if (gt) + d = numeric_add_opt_error(n, one, NULL); else - d = DirectFunctionCall2(numeric_sub, d, one); + d = numeric_sub_opt_error(n, one, NULL); - result = DirectFunctionCall2(numeric_div_trunc, d, two); + result = DirectFunctionCall2(numeric_div_trunc, + NumericGetDatum(d), + NumericGetDatum(two)); return DatumGetNumeric(result); } @@ -819,9 +826,7 @@ pg_size_bytes(PG_FUNCTION_ARGS) mul_num = int64_to_numeric(multiplier); - num = DatumGetNumeric(DirectFunctionCall2(numeric_mul, - NumericGetDatum(mul_num), - NumericGetDatum(num))); + num = numeric_mul_opt_error(mul_num, num, NULL); } } diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index 97a4544ffc6..f19f94b8e5f 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -6178,9 +6178,9 @@ numeric_to_number(PG_FUNCTION_ARGS) x = DatumGetNumeric(DirectFunctionCall2(numeric_power, NumericGetDatum(a), NumericGetDatum(b))); - result = DirectFunctionCall2(numeric_mul, - result, - NumericGetDatum(x)); + result = NumericGetDatum(numeric_mul_opt_error(DatumGetNumeric(result), + x, + NULL)); } pfree(numstr); @@ -6217,9 +6217,7 @@ numeric_to_char(PG_FUNCTION_ARGS) x = DatumGetNumeric(DirectFunctionCall2(numeric_round, NumericGetDatum(value), Int32GetDatum(0))); - numstr = - int_to_roman(DatumGetInt32(DirectFunctionCall1(numeric_int4, - NumericGetDatum(x)))); + numstr = int_to_roman(numeric_int4_opt_error(x, NULL)); } else if (IS_EEEE(&Num)) { @@ -6268,9 +6266,8 @@ numeric_to_char(PG_FUNCTION_ARGS) x = DatumGetNumeric(DirectFunctionCall2(numeric_power, NumericGetDatum(a), NumericGetDatum(b))); - val = DatumGetNumeric(DirectFunctionCall2(numeric_mul, - NumericGetDatum(value), - NumericGetDatum(x))); + val = numeric_mul_opt_error(value, x, NULL); + Num.pre += Num.multi; } diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c index 7b295c199d8..d595d99a03c 100644 --- a/src/backend/utils/adt/jsonb.c +++ b/src/backend/utils/adt/jsonb.c @@ -2156,17 +2156,16 @@ jsonb_int4(PG_FUNCTION_ARGS) { Jsonb *in = PG_GETARG_JSONB_P(0); JsonbValue v; - Datum retValue; + int32 retValue; if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric) cannotCastJsonbValue(v.type, "integer"); - retValue = DirectFunctionCall1(numeric_int4, - NumericGetDatum(v.val.numeric)); + retValue = numeric_int4_opt_error(v.val.numeric, NULL); PG_FREE_IF_COPY(in, 0); - PG_RETURN_DATUM(retValue); + PG_RETURN_INT32(retValue); } Datum diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index d83fe5a326d..c42e72c3193 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -5960,8 +5960,8 @@ numeric_poly_avg(PG_FUNCTION_ARGS) #ifdef HAVE_INT128 PolyNumAggState *state; NumericVar result; - Datum countd, - sumd; + Numeric count, + sum; state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0); @@ -5973,12 +5973,12 @@ numeric_poly_avg(PG_FUNCTION_ARGS) int128_to_numericvar(state->sumX, &result); - countd = NumericGetDatum(int64_to_numeric(state->N)); - sumd = NumericGetDatum(make_result(&result)); + count = int64_to_numeric(state->N); + sum = make_result(&result); free_var(&result); - PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd)); + PG_RETURN_NUMERIC(numeric_div_opt_error(sum, count, NULL)); #else return numeric_avg(fcinfo); #endif @@ -5988,8 +5988,7 @@ Datum numeric_avg(PG_FUNCTION_ARGS) { NumericAggState *state; - Datum N_datum; - Datum sumX_datum; + Numeric sumX; NumericVar sumX_var; state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0); @@ -6009,14 +6008,14 @@ numeric_avg(PG_FUNCTION_ARGS) if (state->nInfcount > 0) PG_RETURN_NUMERIC(make_result(&const_ninf)); - N_datum = NumericGetDatum(int64_to_numeric(state->N)); - init_var(&sumX_var); accum_sum_final(&state->sumX, &sumX_var); - sumX_datum = NumericGetDatum(make_result(&sumX_var)); + sumX = make_result(&sumX_var); free_var(&sumX_var); - PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum)); + PG_RETURN_NUMERIC(numeric_div_opt_error(sumX, + int64_to_numeric(state->N), + NULL)); } Datum @@ -6469,6 +6468,7 @@ Datum int8_sum(PG_FUNCTION_ARGS) { Numeric oldsum; + Numeric result; if (PG_ARGISNULL(0)) { @@ -6492,9 +6492,10 @@ int8_sum(PG_FUNCTION_ARGS) PG_RETURN_NUMERIC(oldsum); /* OK to do the addition. */ - PG_RETURN_DATUM(DirectFunctionCall2(numeric_add, - NumericGetDatum(oldsum), - NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1))))); + result = numeric_add_opt_error(oldsum, + int64_to_numeric(PG_GETARG_INT64(1)), + NULL); + PG_RETURN_NUMERIC(result); } @@ -6661,8 +6662,8 @@ int8_avg(PG_FUNCTION_ARGS) { ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); Int8TransTypeData *transdata; - Datum countd, - sumd; + Numeric count, + sum; if (ARR_HASNULL(transarray) || ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData)) @@ -6673,10 +6674,10 @@ int8_avg(PG_FUNCTION_ARGS) if (transdata->count == 0) PG_RETURN_NULL(); - countd = NumericGetDatum(int64_to_numeric(transdata->count)); - sumd = NumericGetDatum(int64_to_numeric(transdata->sum)); + count = int64_to_numeric(transdata->count); + sum = int64_to_numeric(transdata->sum); - PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd)); + PG_RETURN_NUMERIC(numeric_div_opt_error(sum, count, NULL)); } /* diff --git a/src/backend/utils/adt/pg_lsn.c b/src/backend/utils/adt/pg_lsn.c index e0991d4d2f6..9ee31859d07 100644 --- a/src/backend/utils/adt/pg_lsn.c +++ b/src/backend/utils/adt/pg_lsn.c @@ -270,7 +270,7 @@ pg_lsn_pli(PG_FUNCTION_ARGS) XLogRecPtr lsn = PG_GETARG_LSN(0); Numeric nbytes = PG_GETARG_NUMERIC(1); Datum num; - Datum res; + Numeric res; char buf[32]; if (numeric_is_nan(nbytes)) @@ -286,12 +286,10 @@ pg_lsn_pli(PG_FUNCTION_ARGS) Int32GetDatum(-1)); /* Add two numerics */ - res = DirectFunctionCall2(numeric_add, - NumericGetDatum(num), - NumericGetDatum(nbytes)); + res = numeric_add_opt_error(DatumGetNumeric(num), nbytes, NULL); /* Convert to pg_lsn */ - PG_RETURN_LSN(numeric_to_pg_lsn(DatumGetNumeric(res))); + PG_RETURN_LSN(numeric_to_pg_lsn(res)); } /* @@ -304,7 +302,7 @@ pg_lsn_mii(PG_FUNCTION_ARGS) XLogRecPtr lsn = PG_GETARG_LSN(0); Numeric nbytes = PG_GETARG_NUMERIC(1); Datum num; - Datum res; + Numeric res; char buf[32]; if (numeric_is_nan(nbytes)) @@ -320,10 +318,8 @@ pg_lsn_mii(PG_FUNCTION_ARGS) Int32GetDatum(-1)); /* Subtract two numerics */ - res = DirectFunctionCall2(numeric_sub, - NumericGetDatum(num), - NumericGetDatum(nbytes)); + res = numeric_sub_opt_error(DatumGetNumeric(num), nbytes, NULL); /* Convert to pg_lsn */ - PG_RETURN_LSN(numeric_to_pg_lsn(DatumGetNumeric(res))); + PG_RETURN_LSN(numeric_to_pg_lsn(res)); } diff --git a/src/backend/utils/adt/rangetypes.c b/src/backend/utils/adt/rangetypes.c index 8fb67387cc5..e0b339ab1f7 100644 --- a/src/backend/utils/adt/rangetypes.c +++ b/src/backend/utils/adt/rangetypes.c @@ -1571,14 +1571,14 @@ int8range_subdiff(PG_FUNCTION_ARGS) Datum numrange_subdiff(PG_FUNCTION_ARGS) { - Datum v1 = PG_GETARG_DATUM(0); - Datum v2 = PG_GETARG_DATUM(1); - Datum numresult; + Numeric v1 = PG_GETARG_NUMERIC(0); + Numeric v2 = PG_GETARG_NUMERIC(1); + Numeric numresult; float8 floatresult; - numresult = DirectFunctionCall2(numeric_sub, v1, v2); + numresult = numeric_sub_opt_error(v1, v2, NULL); - floatresult = numeric_to_float8(DatumGetNumeric(numresult)); + floatresult = numeric_to_float8(numresult); PG_RETURN_FLOAT8(floatresult); } -- 2.18.0