Re: NUMERIC private methods? - Mailing list pgsql-hackers

From Heikki Linnakangas
Subject Re: NUMERIC private methods?
Date
Msg-id 548FEC0B.40309@vmware.com
Whole thread Raw
In response to NUMERIC private methods?  (David Fetter <david@fetter.org>)
Responses Re: NUMERIC private methods?  (Andrew Gierth <andrew@tao11.riddles.org.uk>)
Re: NUMERIC private methods?  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
On 12/16/2014 08:34 AM, David Fetter wrote:
> Folks,
>
> While noodling with some weighted statistics
> <https://github.com/davidfetter/weighted_stats>, I noticed I was
> having to jump through a lot of hoops because of all the private
> methods in numeric.c, especially NumericVar.  Would there be some
> major objection to exposing NumericVar as an opaque blob?

Hmm. You'd want to make add_var, mul_var etc. non-static?

Looking at the weighed_stats code, this probably illustrates the hoops 
you had to jump through:

> /* sqrt((n/(n-1)) * ((s0*s2 - s1*s1)/(s0*s0)) */
>
>         result
>             = DirectFunctionCall1(
>                 numeric_sqrt,
>                 DirectFunctionCall2(
>                     numeric_mul,
>                     DirectFunctionCall2(
>                         numeric_div,
>                         n_prime,
>                         DirectFunctionCall2(
>                             numeric_sub,
>                             n_prime,
>                             /*
>                              * This rather convoluted way to compute the value
>                              * 1 gives us a result which should have at least
>                              * as big a decimal scale as s_2 does, which should
>                              * guarantee that our result is as precise as the
>                              * input...
>                              */
>                             DirectFunctionCall2(
>                                 numeric_add,
>                                 DirectFunctionCall2(
>                                     numeric_sub,
>                                     state->s_2,
>                                     state->s_2
>                                     ),
>                                 make_numeric(1)
>                                 )
>                             )
>                         ),
>                     DirectFunctionCall2(
>                         numeric_div,
>                         DirectFunctionCall2(
>                             numeric_sub,
>                             DirectFunctionCall2(
>                                 numeric_mul,
>                                 state->s_0,
>                                 state->s_2
>                                 ),
>                             DirectFunctionCall2(
>                                 numeric_mul,
>                                 state->s_1,
>                                 state->s_1
>                                 )
>                             ),
>                         DirectFunctionCall2(
>                             numeric_mul,
>                             state->s_0,
>                             state->s_0
>                             )
>                         )
>                     )
>                 );

As a start, it would help a lot to #define a few helper macros like:

#define ADD(a, b) DirectFunctionCall2(numeric_add, a, b)
#define MUL(a, b) DirectFunctionCall2(numeric_mul, a, b)

in your extension. That would already make that a lot shorter.

You might also be worrying about performance, though. The above snippet 
was from the aggregate's final function, which isn't performance 
critical, but you have some numeric operations in the transition 
function too. I wonder how big the impact really is, though. 
init_var_from_num and make_result look quite cheap, but certainly not free.

- Heikki



pgsql-hackers by date:

Previous
From: Craig Ringer
Date:
Subject: Re: Commitfest problems
Next
From: Borodin Vladimir
Date:
Subject: Re: Streaming replication and WAL archive interactions