Re: Partial aggregates pushdown - Mailing list pgsql-hackers
| From | Alexander Pyhalov |
|---|---|
| Subject | Re: Partial aggregates pushdown |
| Date | |
| Msg-id | 93fc7f04f8c6978296c05f4f70671a43@postgrespro.ru Whole thread Raw |
| In response to | RE: Partial aggregates pushdown ("Fujii.Yuki@df.MitsubishiElectric.co.jp" <Fujii.Yuki@df.MitsubishiElectric.co.jp>) |
| Responses |
RE: Partial aggregates pushdown
|
| List | pgsql-hackers |
Fujii.Yuki@df.MitsubishiElectric.co.jp писал 2023-06-06 06:08:
> Hi Mr.Pyhalov.
>
> Thank you for your always thoughtful review.
>
>> From: Alexander Pyhalov <a.pyhalov@postgrespro.ru>
>> Sent: Monday, June 5, 2023 6:00 PM
>> Have found one issue -
>>
>> src/backend/catalog/pg_aggregate.c
>>
>> 585 if(strcmp(strVal(linitial(aggpartialfnName)),
>> aggName) == 0){
>> 586 if(((aggTransType != INTERNALOID) &&
>> (finalfn != InvalidOid))
>> 587 || ((aggTransType ==
>> INTERNALOID) && (finalfn != serialfn)))
>> 588 elog(ERROR, "%s is not its own
>> aggpartialfunc", aggName);
>> 589 } else {
>>
>> Here string comparison of aggName and aggpartialfnName looks very
>> suspicios - it seems you should compare oids, not names (in this case,
>> likely oids of transition function and partial aggregation function).
>> The fact that aggregate name matches partial aggregation function name
>> is not a enough to make any decisions.
>
> I see no problem with this string comparison. Here is the reason.
> The intent of this code is, to determine whether the user specifies
> the new aggregate function whose aggpartialfunc is itself.
> For two aggregate functions,
> If the argument list and function name match, then the two aggregate
> functions must match.
> By definition of aggpartialfunc,
> every aggregate function and its aggpartialfn must have the same
> argument list.
> Thus, if aggpartialfnName and aggName are equal as strings,
> I think it is correct to determine that the user is specifying
> the new aggregate function whose aggpartialfunc is itself.
>
> However, since the document does not state these intentions
> I think your suspicions are valid.
> Therefore, I have added a specification to the document reflecting the
> above intentions.
>
Hi. Let me explain.
Look at this example, taken from test.
CREATE AGGREGATE udf_avg_p_int4(int4) (
sfunc = int4_avg_accum,
stype = _int8,
combinefunc = int4_avg_combine,
initcond = '{0,0}'
);
CREATE AGGREGATE udf_sum(int4) (
sfunc = int4_avg_accum,
stype = _int8,
finalfunc = int8_avg,
combinefunc = int4_avg_combine,
initcond = '{0,0}',
aggpartialfunc = udf_avg_p_int4
);
Now, let's create another aggregate.
# create schema test ;
create aggregate test.udf_avg_p_int4(int4) (
sfunc = int4_avg_accum,
stype = _int8,
finalfunc = int8_avg,
combinefunc = int4_avg_combine,
initcond = '{0,0}',
aggpartialfunc = udf_avg_p_int4
);
ERROR: udf_avg_p_int4 is not its own aggpartialfunc
What's the difference between test.udf_avg_p_int4(int4) aggregate and
udf_sum(int4)? They are essentially the same, but second one can't be
defined.
Also note difference:
# CREATE AGGREGATE udf_sum(int4) (
sfunc = int4_avg_accum,
stype = _int8,
finalfunc = int8_avg,
combinefunc = pg_catalog.int4_avg_combine,
initcond = '{0,0}',
aggpartialfunc = udf_avg_p_int4
);
CREATE AGGREGATE
# CREATE AGGREGATE udf_sum(int4) (
sfunc = int4_avg_accum,
stype = _int8,
finalfunc = int8_avg,
combinefunc = pg_catalog.int4_avg_combine,
initcond = '{0,0}',
aggpartialfunc = public.udf_avg_p_int4
);
ERROR: aggpartialfnName is invalid
It seems that assumption about aggpartialfnName - that it's a
non-qualified name is incorrect. And if we use qualified names, we can't
compare just names, likely we should compare oids.
--
Best regards,
Alexander Pyhalov,
Postgres Professional
pgsql-hackers by date: