Implementing product-aggregate
Hi,
we need a product aggregate and used to implement this as
exp(sum(ln([COLUMN])))
While using the sum of logarithms is working RDBMS-independently, we'd like to
switch to a more PostgreSQL native way of doing this and implement an
aggregate to be used. Currently the implementation is
create aggregate prod(numeric) (sfunc = numeric_mul, stype = numeric)
This is simply calling the implementation funtion of the *-Operator for the numeric
datatype. Since I could not find any documentation of this implementation
function, I am wondering, if using a possibly internal function might be a bad idea.
Are there any recommendations on this?
Thanks for any input!
--
MfG Jan
Hi again,
Am Montag, 11. März 2024, 10:16:33 CET schrieb Jan Kohnert:
create aggregate prod(numeric) (sfunc = numeric_mul, stype = numeric)
my basic idea was creating a function
create function multiply(arg1 numeric, arg2 numeric)
returns numeric
language sql
immutable
returns null on null input
return arg1 * arg2;
and use that function instead of the undocumented numeric_mul as the sfunc in
the aggregate definition.
Then again, this seems odd, too, since we're only reimplementing basic stuff that's
already there.
I'm still undecided...
--
MfG Jan
Jan Kohnert <nospam001-lists@jan-kohnert.de> writes:
Am Montag, 11. März 2024, 10:16:33 CET schrieb Jan Kohnert:
create aggregate prod(numeric) (sfunc = numeric_mul, stype = numeric)
...
Then again, this seems odd, too, since we're only reimplementing basic stuff that's
already there.
I wouldn't be concerned about relying on numeric_mul (or any of the
other functions underlying standard operators). They're undocumented
only because documenting both the functions and the operators would
bloat the documentation to little purpose. Using one makes your code
not so portable to non-Postgres DBMSes, but you already crossed that
bridge by deciding to use a custom aggregate.
A bigger question is whether this implementation actually has the
properties you want --- notably, maybe you should be using type
float8 not numeric. Numeric would get pretty slow and be carrying
an awful lot of decimal places by the end of the query, I fear.
regards, tom lane
Hello,
Am Donnerstag, 14. März 2024, 15:17:58 CET schrieb Tom Lane:
I wouldn't be concerned about relying on numeric_mul (or any of the
other functions underlying standard operators). They're undocumented
only because documenting both the functions and the operators would
bloat the documentation to little purpose. Using one makes your code
not so portable to non-Postgres DBMSes, but you already crossed that
bridge by deciding to use a custom aggregate.
thank you for clearifying this. We're not too concerned about portability. Let's face
the facts: Porting a reasonably complex database and the application using it
from one DBMS to another will almost certainly introduce an awful lot of
portability issues (f.e. the pseudo-types (big)serial, upserts, differences in merge
implementations, progammability, and so on). My main concern was, that
undocumented features sometimes tend to change without notice, since users
are not expected to use them..
A bigger question is whether this implementation actually has the
properties you want --- notably, maybe you should be using type
float8 not numeric. Numeric would get pretty slow and be carrying
an awful lot of decimal places by the end of the query, I fear.
This needs to be checked on our side. I was expecting, that using an aggregate
this way would be significantly faster than using exp(sum(log())). Though we're
not multiplying too many lines in a statement, if using the aggregate slows down
performance, we should propably stick the old way doing it.
Best regards!
--
MfG Jan