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


--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to