36.12. ÐолÑзоваÑелÑÑкие агÑегаÑнÑе ÑÑнкÑии #
- 36.12.1. Режим движÑÑегоÑÑ Ð°Ð³ÑегаÑа
- 36.12.2. ÐгÑегаÑнÑе ÑÑнкÑии Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑнÑми и пеÑеменнÑми аÑгÑменÑами
- 36.12.3. СоÑÑиÑÑÑÑие агÑегаÑнÑе ÑÑнкÑии
- 36.12.4. ЧаÑÑиÑное агÑегиÑование
- 36.12.5. ÐÑпомогаÑелÑнÑе ÑÑнкÑии Ð´Ð»Ñ Ð°Ð³ÑегаÑов
- 36.12.2. ÐгÑегаÑнÑе ÑÑнкÑии Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑнÑми и пеÑеменнÑми аÑгÑменÑами
ÐгÑегаÑнÑе ÑÑнкÑии в Postgres Pro опÑеделÑÑÑÑÑ Ð² ÑеÑÐ¼Ð¸Ð½Ð°Ñ Ð·Ð½Ð°Ñений ÑоÑÑоÑÐ½Ð¸Ñ Ð¸ ÑÑнкÑий пеÑÐµÑ Ð¾Ð´Ð° ÑоÑÑоÑниÑ. То еÑÑÑ Ð°Ð³ÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ ÑабоÑÐ°ÐµÑ Ñо знаÑением ÑоÑÑоÑниÑ, коÑоÑое менÑеÑÑÑ Ð¿Ñи обÑабоÑке каждой поÑледÑÑÑей ÑÑÑоки. ЧÑÐ¾Ð±Ñ Ð¾Ð¿ÑеделиÑÑ Ð°Ð³ÑегаÑнÑÑ ÑÑнкÑиÑ, нÑжно вÑбÑаÑÑ Ñип даннÑÑ Ð´Ð»Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÑоÑÑоÑниÑ, наÑалÑное знаÑение ÑоÑÑоÑÐ½Ð¸Ñ Ð¸ ÑÑнкÑÐ¸Ñ Ð¿ÐµÑÐµÑ Ð¾Ð´Ð° ÑоÑÑоÑниÑ. ФÑнкÑÐ¸Ñ Ð¿ÐµÑÐµÑ Ð¾Ð´Ð° ÑоÑÑоÑÐ½Ð¸Ñ Ð¿ÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð¿ÑедÑдÑÑее знаÑение ÑоÑÑоÑÐ½Ð¸Ñ Ð¸ Ð²Ñ Ð¾Ð´Ð½Ð¾Ðµ агÑегиÑÑемое знаÑение Ð´Ð»Ñ ÑекÑÑей ÑÑÑоки и возвÑаÑÐ°ÐµÑ Ð½Ð¾Ð²Ð¾Ðµ знаÑение ÑоÑÑоÑниÑ. Также можно ÑказаÑÑ ÑÑнкÑÐ¸Ñ Ð·Ð°Ð²ÐµÑÑениÑ, на ÑлÑÑай, еÑли ожидаемÑй ÑезÑлÑÑÐ°Ñ Ð°Ð³ÑегаÑной ÑÑнкÑии оÑлиÑаеÑÑÑ Ð¾Ñ Ð´Ð°Ð½Ð½ÑÑ , коÑоÑÑе ÑÐ¾Ñ ÑанÑÑÑÑÑ Ð² изменÑÑÑемÑÑ Ð·Ð½Ð°Ñении ÑоÑÑоÑниÑ. ФÑнкÑÐ¸Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð¿ÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ ÐºÐ¾Ð½ÐµÑное знаÑение ÑоÑÑоÑÐ½Ð¸Ñ Ð¸ возвÑаÑÐ°ÐµÑ Ñо, ÑÑо она Ñ Ð¾ÑÐµÑ Ð²ÐµÑнÑÑÑ Ð² виде ÑезÑлÑÑаÑа агÑегиÑованиÑ. РпÑинÑипе, ÑÑнкÑии пеÑÐµÑ Ð¾Ð´Ð° и завеÑÑÐµÐ½Ð¸Ñ Ð¿ÑедÑÑавлÑÑÑ Ñобой пÑоÑÑо обÑÑнÑе ÑÑнкÑии, коÑоÑÑе Ñакже могÑÑ Ð¿ÑименÑÑÑÑÑ Ð²Ð½Ðµ конÑекÑÑа агÑегиÑованиÑ. (Ðа пÑакÑике Ð´Ð»Ñ Ð±Ð¾Ð»ÑÑей пÑоизводиÑелÑноÑÑи ÑаÑÑо ÑоздаÑÑÑÑ ÑпеÑиализиÑованнÑе ÑÑнкÑии пеÑÐµÑ Ð¾Ð´Ð°, коÑоÑÑе ÑабоÑаÑÑ, ÑолÑко когда вÑзÑваÑÑÑÑ Ð¿Ñи агÑегиÑовании.)
Таким обÑазом, помимо Ñипов даннÑÑ Ð°ÑгÑменÑов и ÑезÑлÑÑаÑа, Ñ ÐºÐ¾ÑоÑÑми Ð¸Ð¼ÐµÐµÑ Ð´ÐµÐ»Ð¾ полÑзоваÑÐµÐ»Ñ Ð°Ð³ÑегаÑной ÑÑнкÑии, еÑÑÑ Ñакже Ñип даннÑÑ Ð²Ð½ÑÑÑеннего ÑоÑÑоÑниÑ, коÑоÑÑй Ð¼Ð¾Ð¶ÐµÑ Ð¾ÑлиÑаÑÑÑÑ Ð¾Ñ ÑÑÐ¸Ñ Ñипов.
ÐÑли Ð¼Ñ Ð¾Ð¿ÑеделÑем агÑегаÑ, не иÑполÑзÑÑÑий ÑÑнкÑÐ¸Ñ Ð·Ð°Ð²ÐµÑÑениÑ, Ð½Ð°Ñ Ð°Ð³ÑÐµÐ³Ð°Ñ Ð±ÑÐ´ÐµÑ Ð²ÑÑиÑлÑÑÑ Ð±ÐµÐ³ÑÑее знаÑение ÑÑнкÑии по ÑÑолбÑам каждой ÑÑÑоки. ÐÑимеÑом Ñакой агÑегаÑной ÑÑнкÑии ÑвлÑеÑÑÑ sum. ÐÑÑиÑление sum наÑинаеÑÑÑ Ñ Ð½ÑлÑ, а заÑем к накапливаемой ÑÑмме вÑегда пÑибавлÑеÑÑÑ Ð·Ð½Ð°Ñение из ÑекÑÑей ÑÑÑоки. ÐапÑимеÑ, еÑли Ð¼Ñ Ñ
оÑим ÑделаÑÑ Ð°Ð³ÑегаÑнÑÑ ÑÑнкÑÐ¸Ñ sum Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿Ð»ÐµÐºÑнÑÑ
ÑиÑел, нам поÑÑебÑеÑÑÑ ÑолÑко ÑÑнкÑÐ¸Ñ ÑÐ»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñакого Ñипа даннÑÑ
. Ð¢Ð°ÐºÐ°Ñ Ð°Ð³ÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾Ð¿Ñеделена Ñак:
CREATE AGGREGATE sum (complex)
(
sfunc = complex_add,
stype = complex,
initcond = '(0,0)'
);ÐÑполÑзоваÑÑ ÐµÑ Ð¼Ð¾Ð¶Ð½Ð¾ бÑÐ´ÐµÑ Ñак:
SELECT sum(a) FROM test_complex; sum ----------- (34,53.9)
(ÐамеÑÑÑе, ÑÑо Ð¼Ñ Ð·Ð°Ð´ÐµÐ¹ÑÑвÑем пеÑегÑÑÐ·ÐºÑ ÑÑнкÑий: в ÑиÑÑеме еÑÑÑ Ð½ÐµÑколÑко агÑегаÑнÑÑ
ÑÑнкÑий Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ sum, но Postgres Pro Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделиÑÑ, ÐºÐ°ÐºÐ°Ñ Ð¸Ð¼ÐµÐ½Ð½Ð¾ из ниÑ
пÑименима к ÑÑолбÑÑ Ñипа complex.)
ÐпÑеделÑÐ½Ð½Ð°Ñ Ð²ÑÑе ÑÑнкÑÐ¸Ñ sum веÑнÑÑ Ð½Ð¾Ð»Ñ (наÑалÑное знаÑение ÑоÑÑоÑниÑ), еÑли в набоÑе даннÑÑ
не окажеÑÑÑ Ð·Ð½Ð°Ñений, оÑлиÑнÑÑ
Ð¾Ñ NULL. У Ð½Ð°Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÑÑÑ Ð¶ÐµÐ»Ð°Ð½Ð¸Ðµ веÑнÑÑÑ NULL в ÑÑом ÑлÑÑае â ÑÑандаÑÑ SQL ÑÑебÑеÑ, ÑÑÐ¾Ð±Ñ sum ÑабоÑала Ñак. ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ добиÑÑÑÑ ÑÑого, пÑоÑÑо опÑÑÑив ÑÑÐ°Ð·Ñ initcond, Ñак ÑÑо наÑалÑнÑм знаÑением ÑоÑÑоÑÐ½Ð¸Ñ Ð±ÑÐ´ÐµÑ NULL. ÐбÑÑно ÑÑо бÑÐ´ÐµÑ Ð¾Ð·Ð½Ð°ÑаÑÑ, ÑÑо в sfunc пÑидÑÑÑÑ Ð¿ÑовеÑÑÑÑ Ð²Ñ
одное знаÑение ÑоÑÑоÑÐ½Ð¸Ñ Ð½Ð° NULL. Ðо Ð´Ð»Ñ sum и некоÑоÑÑÑ
дÑÑгиÑ
пÑоÑÑÑÑ
агÑегаÑнÑÑ
ÑÑнкÑий, как max и min, доÑÑаÑоÑно вÑÑавиÑÑ Ð² пеÑеменнÑÑ ÑоÑÑоÑÐ½Ð¸Ñ Ð¿ÐµÑвое вÑ
одное знаÑение не NULL, а заÑем наÑаÑÑ Ð¿ÑименÑÑÑ ÑÑнкÑÐ¸Ñ Ð¿ÐµÑеÑ
ода Ñо ÑледÑÑÑего знаÑÐµÐ½Ð¸Ñ Ð½Ðµ NULL. Postgres Pro ÑÐ´ÐµÐ»Ð°ÐµÑ ÑÑо авÑомаÑиÑеÑки, еÑли наÑалÑное знаÑение ÑоÑÑоÑние Ñавно NULL и ÑÑнкÑÐ¸Ñ Ð¿ÐµÑеÑ
ода помеÑена как «strict» (Ñо еÑÑÑ Ð½Ðµ должна вÑзÑваÑÑÑÑ Ð´Ð»Ñ Ð°ÑгÑменÑов NULL).
ÐÑÑ Ð¾Ð´Ð½Ð° оÑобенноÑÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Â«ÑÑÑогой» ÑÑнкÑии пеÑÐµÑ Ð¾Ð´Ð° â пÑедÑдÑÑее знаÑение ÑоÑÑоÑÐ½Ð¸Ñ Ð¾ÑÑаÑÑÑÑ Ð±ÐµÐ· изменений, когда вÑÑÑеÑаеÑÑÑ Ð·Ð½Ð°Ñение NULL. ÐÑÑгими Ñловами, знаÑÐµÐ½Ð¸Ñ NULL игноÑиÑÑÑÑÑÑ. ÐÑли вам нÑжно дÑÑгое поведение Ð´Ð»Ñ Ð²Ñ Ð¾Ð´Ð½ÑÑ Ð·Ð½Ð°Ñений NULL, не обÑÑвлÑйÑе ÑÐ²Ð¾Ñ ÑÑнкÑÐ¸Ñ Ð¿ÐµÑÐµÑ Ð¾Ð´Ð° ÑÑÑогой (strict); вмеÑÑо ÑÑого, пÑовеÑÑÑе в ней поÑÑÑпаÑÑие знаÑÐµÐ½Ð¸Ñ Ð½Ð° NULL и обÑабоÑайÑе Ð¸Ñ , как ÑÑебÑеÑÑÑ.
ФÑнкÑÐ¸Ñ avg (вÑÑиÑлÑÑÑÐ°Ñ ÑÑеднее аÑиÑмеÑиÑеÑкое) пÑедÑÑавлÑÐµÑ Ñобой более ÑложнÑй пÑÐ¸Ð¼ÐµÑ Ð°Ð³ÑегаÑной ÑÑнкÑии. Ðй необÑ
Ð¾Ð´Ð¸Ð¼Ñ Ð´Ð²Ð° компоненÑа ÑекÑÑего ÑоÑÑоÑниÑ: ÑÑмма вÑ
однÑÑ
знаÑений и иÑ
колиÑеÑÑво. ÐконÑаÑелÑнÑй ÑезÑлÑÑÐ°Ñ Ð¿Ð¾Ð»ÑÑаеÑÑÑ ÐºÐ°Ðº ÑаÑÑное ÑÑиÑ
велиÑин. ÐÑи ÑеализаÑии ÑÑой ÑÑнкÑии Ð´Ð»Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÑоÑÑоÑÐ½Ð¸Ñ Ð¾Ð±ÑÑно иÑполÑзÑеÑÑÑ Ð¼Ð°ÑÑив. ÐапÑимеÑ, вÑÑÑÐ¾ÐµÐ½Ð½Ð°Ñ ÑеализаÑÐ¸Ñ avg(float8) вÑглÑÐ´Ð¸Ñ Ñак:
CREATE AGGREGATE avg (float8)
(
sfunc = float8_accum,
stype = float8[],
finalfunc = float8_avg,
initcond = '{0,0,0}'
);ÐÑимеÑание
ФÑнкÑÐ¸Ñ float8_accum пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð¼Ð°ÑÑив из ÑÑÑÑ
, а не двÑÑ
ÑлеменÑов, Ñак как в дополнение к колиÑеÑÑÐ²Ñ Ð¸ ÑÑмме знаÑений она подÑÑиÑÑÐ²Ð°ÐµÑ ÐµÑÑ ÑÑÐ¼Ð¼Ñ Ð¸Ñ
квадÑаÑов. ÐÑо Ñделано Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ ÐµÑ Ð¼Ð¾Ð¶Ð½Ð¾ бÑло пÑименÑÑÑ Ð´Ð»Ñ avg и Ð´Ð»Ñ Ð½ÐµÐºÐ¾ÑоÑÑÑ
дÑÑгиÑ
агÑегаÑнÑÑ
ÑÑнкÑий.
ÐÑÐ·Ð¾Ð²Ñ Ð°Ð³ÑегаÑнÑÑ
ÑÑнкÑий SQL допÑÑкаÑÑ ÑÐºÐ°Ð·Ð°Ð½Ð¸Ñ DISTINCT и ORDER BY, коÑоÑÑе опÑеделÑÑÑ, какие ÑÑÑоки и в каком поÑÑдке бÑдÑÑ Ð¿Ð¾ÑÑÑпаÑÑ Ð² ÑÑнкÑÐ¸Ñ Ð¿ÐµÑеÑ
ода агÑегаÑа. ÐÑо Ñеализовано на заднем плане и непоÑÑедÑÑвенно не заÑÑÐ°Ð³Ð¸Ð²Ð°ÐµÑ ÑÑнкÑии, поддеÑживаÑÑие ÑабоÑÑ Ð°Ð³ÑегаÑа.
Ðа дополниÑелÑнÑми подÑобноÑÑÑми обÑаÑиÑеÑÑ Ðº опиÑÐ°Ð½Ð¸Ñ CREATE AGGREGATE.
36.12.1. Режим движÑÑегоÑÑ Ð°Ð³ÑегаÑа #
ÐгÑегаÑнÑе ÑÑнкÑии могÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑно поддеÑживаÑÑ Ñежим движÑÑегоÑÑ Ð°Ð³ÑегаÑа, коÑоÑÑй позволÑÐµÑ Ð·Ð½Ð°ÑиÑелÑно бÑÑÑÑее вÑполнÑÑÑ Ð°Ð³ÑегаÑнÑе ÑÑнкÑии в окнаÑ
Ñо ÑдвигаÑÑимÑÑ Ð½Ð°Ñалом Ñамки. (Ðа инÑоÑмаÑией об иÑполÑзовании агÑегаÑнÑÑ
ÑÑнкÑий в каÑеÑÑве оконнÑÑ
обÑаÑиÑеÑÑ Ðº РазделÑ 3.5 и ÐодÑазделÑ 4.2.8.) ÐÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð¸Ð´ÐµÑ ÑоÑÑÐ¾Ð¸Ñ Ð² Ñом, ÑÑо помимо Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑÑной ÑÑнкÑии пеÑеÑ
ода «впеÑÑд», Ð´Ð»Ñ Ð°Ð³ÑегаÑной ÑÑнкÑии задаÑÑÑÑ ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑаÑного пеÑеÑ
ода, коÑоÑÐ°Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÐµÑ ÑбиÑаÑÑ ÑÑÑоки из накапливаемого знаÑÐµÐ½Ð¸Ñ ÑоÑÑоÑниÑ, когда они покидаÑÑ ÑÐ°Ð¼ÐºÑ Ð¾ÐºÐ½Ð°. ÐапÑимеÑ, Ð´Ð»Ñ sum в каÑеÑÑве ÑÑнкÑии пÑÑмого пеÑеÑ
ода вÑполнÑеÑÑÑ Ñложение, а в каÑеÑÑве ÑÑнкÑии обÑаÑного пеÑеÑ
ода вÑполнÑеÑÑÑ Ð²ÑÑиÑание. Ðез ÑÑнкÑии обÑаÑного пеÑеÑ
ода меÑ
анизм оконнÑÑ
ÑÑнкÑий вÑнÑжден вÑÑиÑлÑÑÑ Ð°Ð³ÑÐµÐ³Ð°Ñ Ð·Ð°Ð½Ð¾Ð²Ð¾ пÑи каждом пеÑемеÑении наÑала Ñамки, в ÑезÑлÑÑаÑе Ñего вÑÐµÐ¼Ñ Ð¾Ð±ÑабоÑки оказÑваеÑÑÑ Ð¿ÑопоÑÑионалÑнÑм колиÑеÑÑÐ²Ñ Ð²Ñ
однÑÑ
ÑÑÑок, Ð¿Ð¾Ð¼Ð½Ð¾Ð¶ÐµÐ½Ð½Ð¾Ð¼Ñ Ð½Ð° ÑÑедний ÑÐ°Ð·Ð¼ÐµÑ Ñамки. С ÑÑнкÑией обÑаÑного пеÑеÑ
ода ÑÑо вÑÐµÐ¼Ñ Ð¿ÑопоÑÑионалÑно ÑолÑко колиÑеÑÑÐ²Ñ Ð²Ñ
однÑÑ
ÑÑÑок.
ФÑнкÑии обÑаÑного пеÑÐµÑ Ð¾Ð´Ð° пеÑедаÑÑÑÑ ÑекÑÑее знаÑение ÑоÑÑоÑÐ½Ð¸Ñ Ð¸ агÑегиÑÑемое Ð²Ñ Ð¾Ð´Ð½Ð¾Ðµ знаÑение(Ñ) Ð´Ð»Ñ ÑÑÑоки, Ñанее ÑÑÑÑнной в ÑекÑÑем ÑоÑÑоÑнии. Ðна должна воÑÑÑановиÑÑ Ñо знаÑение ÑоÑÑоÑниÑ, коÑоÑое бÑло Ð±Ñ Ð¿Ð¾Ð»ÑÑено, еÑли Ð±Ñ ÑÑа ÑÑÑока не агÑегиÑовалаÑÑ, но агÑегиÑовалиÑÑ Ð²Ñе поÑледÑÑÑие. Ðногда Ð´Ð»Ñ ÑÑого нÑжно, ÑÑÐ¾Ð±Ñ ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑаÑного пеÑÐµÑ Ð¾Ð´Ð° ÑÐ¾Ñ ÑанÑла болÑÑе инÑоÑмаÑии о ÑоÑÑоÑнии, Ñем ÑÑо ÑÑебÑеÑÑÑ Ð´Ð»Ñ Ð¿ÑоÑÑого Ñежима агÑегиÑованиÑ. Таким обÑазом, Ð´Ð»Ñ Ñежима движÑÑегоÑÑ Ð°Ð³ÑегаÑа иÑполÑзÑеÑÑÑ ÑеализаÑиÑ, оÑлиÑÐ½Ð°Ñ Ð¾Ñ Ð¿ÑоÑÑого Ñежима: Ð´Ð»Ñ Ð½ÐµÐ³Ð¾ опÑеделÑеÑÑÑ Ð¾ÑделÑнÑй Ñип даннÑÑ , оÑделÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¿ÑÑмого пеÑÐµÑ Ð¾Ð´Ð° и оÑделÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð·Ð°Ð²ÐµÑÑениÑ, пÑи Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи. Ðни могÑÑ ÑовпадаÑÑ Ñ Ñипом даннÑÑ Ð¸ аналогиÑнÑми ÑÑнкÑиÑми обÑÑного Ñежима, еÑли в дополниÑелÑном ÑоÑÑоÑнии Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи неÑ.
РкаÑеÑÑве пÑимеÑа Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ доÑабоÑаÑÑ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ð½ÑÑ Ð²ÑÑе агÑегаÑнÑÑ ÑÑнкÑÐ¸Ñ sum, ÑÑÐ¾Ð±Ñ Ð¾Ð½Ð° поддеÑживала Ñежим движÑÑегоÑÑ Ð°Ð³ÑегаÑа Ñак:
CREATE AGGREGATE sum (complex)
(
sfunc = complex_add,
stype = complex,
initcond = '(0,0)',
msfunc = complex_add,
minvfunc = complex_sub,
mstype = complex,
minitcond = '(0,0)'
); ÐаÑамеÑÑÑ, имена коÑоÑÑÑ
наÑинаÑÑÑÑ Ñ m, опÑеделÑÑÑ ÑеализаÑÐ¸Ñ Ð´Ð»Ñ Ð´Ð²Ð¸Ð¶ÑÑегоÑÑ Ð°Ð³ÑегаÑа. Ðа иÑклÑÑением ÑÑнкÑии обÑаÑного пеÑеÑ
ода, minvfunc, они ÑооÑвеÑÑÑвÑÑÑ Ð¿Ð°ÑамеÑÑам обÑÑного агÑегаÑа без m.
ФÑнкÑии пÑÑмого пеÑеÑ
ода в Ñежиме движÑÑегоÑÑ Ð°Ð³ÑегаÑа не ÑазÑеÑено возвÑаÑаÑÑ NULL в каÑеÑÑве нового знаÑÐµÐ½Ð¸Ñ ÑоÑÑоÑниÑ. ÐÑли ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑаÑного пеÑеÑ
ода возвÑаÑÐ°ÐµÑ NULL, ÑÑо воÑпÑинимаеÑÑÑ ÐºÐ°Ðº пÑизнак Ñого, ÑÑо она не Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾ÑÑÑановиÑÑ Ð¿ÑедÑдÑÑее ÑоÑÑоÑние Ð´Ð»Ñ Ð¿Ð¾Ð»ÑÑеннÑÑ
даннÑÑ
, и знаÑиÑ, агÑегаÑное вÑÑиÑление нÑжно пÑоизводиÑÑ Ð·Ð°Ð½Ð¾Ð²Ð¾ Ñ ÑекÑÑей позиÑии наÑала Ñамки. ÐÑо ÑоглаÑение позволÑÐµÑ Ð¿ÑименÑÑÑ Ñежим движÑÑегоÑÑ Ð°Ð³ÑегаÑа и в ÑиÑÑаÑиÑÑ
, когда пÑокÑÑÑиваÑÑ Ð½Ð°Ð·Ð°Ð´ знаÑение ÑоÑÑоÑÐ½Ð¸Ñ Ð½ÐµÐ¿ÑакÑиÑно. ФÑнкÑÐ¸Ñ Ð¾Ð±ÑаÑного пеÑеÑ
ода Ð¼Ð¾Ð¶ÐµÑ Â«ÑпаÑоваÑÑ» в ÑакиÑ
ÑлÑÑаÑÑ
, но вклÑÑаÑÑÑÑ Ð² ÑабоÑÑ, наÑколÑко ÑÑо возможно в болÑÑинÑÑве ÑлÑÑаев. ÐапÑимеÑ, агÑегаÑÐ½Ð°Ñ ÑÑнкÑиÑ, ÑабоÑаÑÑÐ°Ñ Ñ ÑиÑлами Ñ Ð¿Ð»Ð°Ð²Ð°ÑÑей ÑоÑкой, Ð¼Ð¾Ð¶ÐµÑ ÑпаÑоваÑÑ, когда Ð¾Ñ Ð½ÐµÑ Ð¿Ð¾ÑÑебÑеÑÑÑ ÑбÑаÑÑ Ð·Ð½Ð°Ñение NaN (не ÑиÑло, not a number) из ÑекÑÑего знаÑÐµÐ½Ð¸Ñ ÑоÑÑоÑниÑ.
РазÑабаÑÑÐ²Ð°Ñ ÑÑнкÑии, ÑеализÑÑÑие Ñежим движÑÑегоÑÑ Ð°Ð³ÑегаÑа, важно, ÑÑÐ¾Ð±Ñ ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑаÑного пеÑеÑ
ода могла воÑÑÑановиÑÑ Ð² ÑоÑноÑÑи ÑÑебÑемое знаÑение ÑоÑÑоÑниÑ. ÐнаÑе в ÑезÑлÑÑаÑаÑ
могÑÑ Ð¿ÑоÑвлÑÑÑÑÑ ÑазлиÑÐ¸Ñ Ð² завиÑимоÑÑи Ð¾Ñ Ñого, иÑполÑзовалÑÑ Ð»Ð¸ Ñежим движÑÑегоÑÑ Ð°Ð³ÑегаÑа. ÐапÑимеÑ, на пеÑвÑй взглÑд Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÐºÐ°Ð·Ð°ÑÑÑÑ, ÑÑо легко добавиÑÑ ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑаÑного пеÑеÑ
ода Ð´Ð»Ñ ÑложениÑ, но заÑвленное ÑÑебование не бÑÐ´ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð´Ð»Ñ sum Ñ Ñипом float4 или float8. Ðаивное обÑÑвление sum( Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñаким: float8)
CREATE AGGREGATE unsafe_sum (float8)
(
stype = float8,
sfunc = float8pl,
mstype = float8,
msfunc = float8pl,
minvfunc = float8mi
);Ðднако Ñакой агÑÐµÐ³Ð°Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²ÑдаваÑÑ ÑезÑлÑÑаÑÑ, ÑадикалÑно оÑлиÑаÑÑиеÑÑ Ð¾Ñ ÑÐµÑ , ÑÑо он вÑдавал Ð±Ñ Ð±ÐµÐ· ÑÑнкÑии обÑаÑного пеÑÐµÑ Ð¾Ð´Ð°. ÐапÑимеÑ, ÑаÑÑмоÑÑиÑе запÑоÑ
SELECT
unsafe_sum(x) OVER (ORDER BY n ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING)
FROM (VALUES (1, 1.0e20::float8),
(2, 1.0::float8)) AS v (n,x); Ðн возвÑаÑÐ°ÐµÑ 0 в каÑеÑÑве вÑоÑого ÑезÑлÑÑаÑа, а не ожидаемое знаÑение 1. ÐÑо ÑвÑзано Ñ Ð¾Ð³ÑаниÑенной ÑоÑноÑÑÑÑ Ð·Ð½Ð°Ñений Ñ Ð¿Ð»Ð°Ð²Ð°ÑÑей ÑоÑкой: пÑи добавлении 1 к 1e20 Ñнова полÑÑаеÑÑÑ 1e20, а пÑи вÑÑиÑании 1e20 из ÑезÑлÑÑаÑа полÑÑаеÑÑÑ 0, а не 1. ÐамеÑÑÑе, ÑÑо ÑÑо пÑинÑипиалÑное огÑаниÑение аÑиÑмеÑики ÑиÑел Ñ Ð¿Ð»Ð°Ð²Ð°ÑÑей ÑоÑкой, а не недоÑÑаÑок Postgres Pro.
36.12.2. ÐгÑегаÑнÑе ÑÑнкÑии Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑнÑми и пеÑеменнÑми аÑгÑменÑами #
ÐгÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑнÑе ÑÑнкÑии пеÑÐµÑ Ð¾Ð´Ð° ÑоÑÑоÑÐ½Ð¸Ñ Ð¸Ð»Ð¸ ÑÑнкÑии завеÑÑениÑ, Ñак ÑÑо ÑÑи ÑÑнкÑии могÑÑ Ð¿ÑименÑÑÑÑÑ Ð´Ð»Ñ ÑеализаÑии неÑколÑÐºÐ¸Ñ Ð°Ð³ÑегаÑов. Ðа обÑÑÑнением полимоÑÑнÑÑ ÑÑнкÑий обÑаÑиÑеÑÑ Ðº ÐодÑазделÑ 36.2.5. Ðолее Ñого, Ñама агÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿Ð¸ÑÑваÑÑÑÑ Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑнÑми Ñипами Ð²Ñ Ð¾Ð´Ð½ÑÑ Ð´Ð°Ð½Ð½ÑÑ Ð¸ ÑоÑÑоÑниÑ, Ñак ÑÑо одно опÑеделение агÑегаÑной ÑÑнкÑии Ð¼Ð¾Ð¶ÐµÑ ÑлÑжиÑÑ Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ ÑазнÑми Ñипами даннÑÑ . ÐÑÐ¸Ð¼ÐµÑ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑного агÑегаÑа:
CREATE AGGREGATE array_accum (anycompatible)
(
sfunc = array_append,
stype = anycompatiblearray,
initcond = '{}'
); ÐдеÑÑ ÑакÑиÑеÑким Ñипом ÑоÑÑоÑÐ½Ð¸Ñ Ð´Ð»Ñ Ð»Ñбого конкÑеÑного агÑегаÑного вÑзова бÑÐ´ÐµÑ Ð¼Ð°ÑÑив, ÑлеменÑÑ ÐºÐ¾ÑоÑого бÑдÑÑ Ð¸Ð¼ÐµÑÑ Ñип вÑ
однÑÑ
даннÑÑ
. ÐейÑÑвие данного агÑегаÑа заклÑÑаеÑÑÑ Ð² накоплении вÑеÑ
вÑ
однÑÑ
знаÑений в маÑÑиве ÑÑого Ñипа. (РваÑÐµÐ¼Ñ ÑведениÑ: вÑÑÑÐ¾ÐµÐ½Ð½Ð°Ñ Ð°Ð³ÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ array_agg обеÑпеÑÐ¸Ð²Ð°ÐµÑ Ð¿Ð¾Ð´Ð¾Ð±Ð½ÑÑ ÑÑнкÑионалÑноÑÑÑ, но ÑабоÑÐ°ÐµÑ Ð±ÑÑÑÑее, Ñем могла Ð±Ñ ÑÑнкÑÐ¸Ñ Ñ Ð¿ÑиведÑннÑм опÑеделением.)
Так бÑдÑÑ Ð²ÑглÑдеÑÑ ÑезÑлÑÑаÑÑ Ñ Ð°ÑгÑменÑами двÑÑ ÑазлиÑнÑÑ Ñипов:
SELECT attrelid::regclass, array_accum(attname)
FROM pg_attribute
WHERE attnum > 0 AND attrelid = 'pg_tablespace'::regclass
GROUP BY attrelid;
attrelid | array_accum
---------------+---------------------------------------
pg_tablespace | {spcname,spcowner,spcacl,spcoptions}
(1 row)
SELECT attrelid::regclass, array_accum(atttypid::regtype)
FROM pg_attribute
WHERE attnum > 0 AND attrelid = 'pg_tablespace'::regclass
GROUP BY attrelid;
attrelid | array_accum
---------------+---------------------------
pg_tablespace | {name,oid,aclitem[],text[]}
(1 row)ÐбÑÑно агÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑнÑм Ñипом ÑезÑлÑÑаÑа Ð¸Ð¼ÐµÐµÑ Ð¸ полимоÑÑнÑй Ñип ÑоÑÑоÑниÑ, как в пÑедÑдÑÑем пÑимеÑе. ÐÑо необÑ
одимо, Ñак как инаÑе нелÑÐ·Ñ Ð±ÑÐ´ÐµÑ Ð¾Ð±ÑÑвиÑÑ ÑÑнкÑÐ¸Ñ Ð·Ð°Ð²ÐµÑÑениÑ: она должна бÑÐ´ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑнÑй Ñип ÑезÑлÑÑаÑа, но не бÑÐ´ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑного аÑгÑменÑа, ÑÑо команда CREATE FUNCTION не пÑÐ¸Ð¼ÐµÑ Ð½Ð° оÑновании Ñого, ÑÑо Ñип ÑезÑлÑÑаÑа нелÑÐ·Ñ Ð±ÑÐ´ÐµÑ Ð¾Ð¿ÑеделиÑÑ Ð¿Ñи вÑзове. Ðо имеÑÑ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑнÑй Ñип ÑоÑÑоÑÐ½Ð¸Ñ Ð½Ðµ вÑегда Ñдобно. ЧаÑе вÑего ÑÑа пÑоблема возникаеÑ, когда ÑÑнкÑии ÑеализаÑии агÑегаÑа пиÑÑÑÑÑ Ð½Ð° C и Ñип ÑоÑÑоÑÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ обÑÑвлÑÑÑÑÑ ÐºÐ°Ðº internal, Ñак как Ð´Ð»Ñ Ð½ÐµÐ³Ð¾ Ð½ÐµÑ ÑооÑвеÑÑÑвÑÑÑего Ñипа на ÑÑовне SQL. ЧÑÐ¾Ð±Ñ ÑеÑиÑÑ ÑÑÑ Ð¿ÑоблемÑ, можно обÑÑвиÑÑ ÑÑнкÑÐ¸Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ ÐºÐ°Ðº пÑинимаÑÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе ÑикÑивнÑе аÑгÑменÑÑ, ÑооÑвеÑÑÑвÑÑÑие вÑ
однÑм аÑгÑменÑам агÑегаÑа. Ð ÑÑиÑ
ÑикÑивнÑÑ
аÑгÑменÑаÑ
вÑегда пеÑедаÑÑÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ NULL, Ñак как пÑи вÑзове ÑÑнкÑии завеÑÑÐµÐ½Ð¸Ñ ÐºÐ°ÐºÐ¾Ðµ-либо опÑеделÑнное знаÑение оÑÑÑÑÑÑвÑеÑ. ÐдинÑÑвенное иÑ
пÑедназнаÑение â позволиÑÑ ÑвÑзаÑÑ Ñип ÑезÑлÑÑаÑа полимоÑÑной ÑÑнкÑии завеÑÑÐµÐ½Ð¸Ñ Ñ Ñипом вÑ
однÑÑ
даннÑÑ
агÑегаÑа. ÐапÑимеÑ, опÑеделение вÑÑÑоенного агÑегаÑа array_agg вÑглÑÐ´Ð¸Ñ Ñак:
CREATE FUNCTION array_agg_transfn(internal, anynonarray)
RETURNS internal ...;
CREATE FUNCTION array_agg_finalfn(internal, anynonarray)
RETURNS anyarray ...;
CREATE AGGREGATE array_agg (anynonarray)
(
sfunc = array_agg_transfn,
stype = internal,
finalfunc = array_agg_finalfn,
finalfunc_extra
); ÐдеÑÑ Ð¿Ð°ÑамеÑÑ finalfunc_extra ÑказÑваеÑ, ÑÑо ÑÑнкÑÐ¸Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ð¼Ð¸Ð¼Ð¾ знаÑÐµÐ½Ð¸Ñ ÑоÑÑоÑÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑÑÐ¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе ÑикÑивнÑе аÑгÑменÑÑ, ÑооÑвеÑÑÑвÑÑÑие вÑ
однÑм аÑгÑменÑам агÑегаÑа. ÐополниÑелÑнÑй аÑгÑÐ¼ÐµÐ½Ñ anynonarray позволÑÐµÑ ÑделаÑÑ Ð¾Ð±ÑÑвление array_agg_finalfn допÑÑÑимÑм.
ÐгÑегаÑнÑÑ ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ ÑделаÑÑ Ð¿ÑинимаÑÑей пеÑеменное ÑиÑло аÑгÑменÑов, обÑÑвив ÐµÑ Ð¿Ð¾Ñледний аÑгÑÐ¼ÐµÐ½Ñ ÐºÐ°Ðº маÑÑив VARIADIC, в Ñом же клÑÑе, как и обÑÑнÑÑ ÑÑнкÑиÑ; Ñм. ÐодÑаздел 36.5.6. ÐÑи ÑÑом Ñ ÑÑнкÑий пеÑеÑ
ода агÑегаÑа иÑ
поÑледний аÑгÑÐ¼ÐµÐ½Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ имеÑÑ ÑÐ¾Ñ Ð¶Ðµ Ñип маÑÑива. Такие ÑÑнкÑии обÑÑно Ñакже обÑÑвлÑÑÑÑÑ ÐºÐ°Ðº VARIADIC, но ÑÑÑого ÑÑо не ÑÑебÑеÑÑÑ.
ÐÑимеÑание
ÐгÑегаÑнÑе ÑÑнкÑии Ñ Ð¿ÐµÑеменнÑми аÑгÑменÑами легко допÑÑкаÑÑ Ð¾ÑибоÑное иÑполÑзование в ÑоÑеÑании Ñ Ñказанием ORDER BY (Ñм. ÐодÑаздел 4.2.7), Ñак как анализаÑÐ¾Ñ Ð·Ð°Ð¿ÑоÑа не Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделиÑÑ, бÑло ли пеÑедано нÑжное колиÑеÑÑво ÑакÑиÑеÑкиÑ
паÑамеÑÑов в Ñакой комбинаÑии. ÐомниÑе, ÑÑо вÑÑ, наÑ
одÑÑееÑÑ ÑпÑава Ð¾Ñ ORDER BY, ÑвлÑеÑÑÑ ÐºÐ»ÑÑом ÑоÑÑиÑовки, а не аÑгÑменÑом агÑегаÑной ÑÑнкÑии. ÐапÑимеÑ, в
SELECT myaggregate(a ORDER BY a, b, c) FROM ...
анализаÑÐ¾Ñ Ð·Ð°Ð¿ÑоÑа ÑÐ²Ð¸Ð´Ð¸Ñ Ð¾Ð´Ð¸Ð½ агÑегаÑнÑй аÑгÑÐ¼ÐµÐ½Ñ ÑÑнкÑии и ÑÑи клÑÑа ÑоÑÑиÑовки. Ðднако полÑзоваÑÐµÐ»Ñ Ð¼Ð¾Ð³ подÑазÑмеваÑÑ Ð¸ ÑледÑÑÑее:
SELECT myaggregate(a, b, c ORDER BY a) FROM ...
ÐÑли ÑÑнкÑÐ¸Ñ myaggregate пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð¿ÐµÑеменнÑе аÑгÑменÑÑ, оба ÑÑи вÑзова бÑдÑÑ Ð²Ð¿Ð¾Ð»Ð½Ðµ допÑÑÑимÑ.
Ðо ÑÑой же пÑиÑине, ÑÑÐ¾Ð¸Ñ Ð¿Ð¾Ð´ÑмаÑÑ Ð´Ð²Ð°Ð¶Ð´Ñ, пÑежде Ñем ÑоздаваÑÑ Ð°Ð³ÑегаÑнÑе ÑÑнкÑии Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñми именами, но ÑазнÑм ÑиÑлом обÑÑнÑÑ Ð°ÑгÑменÑов.
36.12.3. СоÑÑиÑÑÑÑие агÑегаÑнÑе ÑÑнкÑии #
ÐпиÑаннÑе вÑÑе агÑегаÑнÑе ÑÑнкÑии бÑли «обÑÑнÑми» агÑегаÑами. Ðо Postgres Pro Ñакже поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑоÑÑиÑÑÑÑие агÑегаÑнÑе ÑÑнкÑии, коÑоÑÑе имеÑÑ Ð´Ð²Ð° оÑлиÑÐ¸Ñ Ð¾Ñ Ð¾Ð±ÑÑнÑÑ
. Ðо-пеÑвÑÑ
, в дополнение к обÑÑнÑм агÑегиÑÑемÑм аÑгÑменÑам, вÑÑиÑлÑемÑÑ
Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ вÑ
одной ÑÑÑоки, ÑоÑÑиÑÑÑÑий агÑÐµÐ³Ð°Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Â«Ð½ÐµÐ¿Ð¾ÑÑедÑÑвеннÑе» аÑгÑменÑÑ, коÑоÑÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð²ÑÑиÑлÑÑÑÑÑ Ð² опеÑаÑии агÑегиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑолÑко один Ñаз. Ðо-вÑоÑÑÑ
, Ð´Ð»Ñ Ð¾Ð±ÑÑнÑÑ
агÑегиÑÑемÑÑ
аÑгÑменÑов поÑÑдок иÑ
ÑоÑÑиÑовки задаÑÑÑÑ Ñвно, а ÑоÑÑиÑÑÑÑий агÑÐµÐ³Ð°Ñ Ð¾Ð±ÑÑно вÑполнÑÐµÑ Ð²ÑÑиÑлениÑ, завиÑÑÑие Ð¾Ñ ÐºÐ¾Ð½ÐºÑеÑного поÑÑдка ÑÑÑок, напÑимеÑ, вÑÑиÑлÑÐµÑ Ñанг или пÑоÑенÑилÑ, Ñак ÑÑо поÑÑдок ÑоÑÑиÑовки кÑиÑиÑен Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ вÑзова. ÐапÑимеÑ, вÑÑÑоенное опÑеделение ÑÑнкÑии percentile_disc ÑавнознаÑно ÑледÑÑÑемÑ:
CREATE FUNCTION ordered_set_transition(internal, anyelement)
RETURNS internal ...;
CREATE FUNCTION percentile_disc_final(internal, float8, anyelement)
RETURNS anyelement ...;
CREATE AGGREGATE percentile_disc (float8 ORDER BY anyelement)
(
sfunc = ordered_set_transition,
stype = internal,
finalfunc = percentile_disc_final,
finalfunc_extra
); ÐÑÐ¾Ñ Ð°Ð³ÑÐµÐ³Ð°Ñ Ð¿ÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð½ÐµÐ¿Ð¾ÑÑедÑÑвеннÑй аÑгÑÐ¼ÐµÐ½Ñ float8 (дÑÐ¾Ð±Ñ Ð¿ÑоÑенÑилÑ) и агÑегиÑÑемÑе даннÑе, коÑоÑÑе могÑÑ Ð±ÑÑÑ Ð»Ñбого ÑпоÑÑдоÑиваемого Ñипа. ÐÑполÑзÑÑ ÐµÐ³Ð¾, можно ÑаÑÑÑиÑаÑÑ ÑÑедний ÑемейнÑй доÑ
од ÑледÑÑÑим обÑазом:
SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households;
percentile_disc
-----------------
50489 Рданном ÑлÑÑае 0.5 â ÑÑо непоÑÑедÑÑвеннÑй аÑгÑменÑ; еÑли Ð±Ñ Ð´ÑÐ¾Ð±Ñ Ð¿ÑоÑенÑÐ¸Ð»Ñ Ð¼ÐµÐ½ÑлаÑÑ Ð¾Ñ ÑÑÑоки к ÑÑÑоке, ÑÑо не имело Ð±Ñ ÑмÑÑла.
РоÑлиÑие Ð¾Ñ ÑлÑÑÐ°Ñ Ñ Ð¾Ð±ÑÑнÑми агÑегаÑами, ÑоÑÑиÑовка вÑ
однÑÑ
ÑÑÑок Ð´Ð»Ñ ÑоÑÑиÑÑÑÑего агÑегаÑа не вÑполнÑеÑÑÑ Ð½Ð° заднем плане, а ÑвлÑеÑÑÑ Ð·Ð°Ð´Ð°Ñей ÑÑнкÑий, ÑеализÑÑÑиÑ
агÑегаÑ. ТипиÑÐ½Ð°Ñ ÑеализаÑÐ¸Ñ Ñакого агÑегаÑа заклÑÑаеÑÑÑ Ð² ÑоÑ
Ñанении ÑÑÑлки на обÑÐµÐºÑ Â«tuplesort» в знаÑении ÑоÑÑоÑÐ½Ð¸Ñ Ð°Ð³ÑегаÑа, загÑÑзке поÑÑÑпаÑÑиÑ
ÑÑÑок в ÑÑÐ¾Ñ Ð¾Ð±ÑекÑ, и ÑобÑÑвенно оконÑании ÑоÑÑиÑовки и вÑдаÑи даннÑÑ
в ÑÑнкÑии завеÑÑениÑ. ÐÑи Ñакой оÑганизаÑии обÑабоÑки ÑÑнкÑÐ¸Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²ÑполнÑÑÑ ÑпеÑиалÑнÑе опеÑаÑии, в ÑаÑÑноÑÑи, вÑÑавлÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе «гипоÑеÑиÑеÑкие» ÑÑÑоки в ÑоÑÑиÑÑемÑе даннÑе. Тогда как обÑÑнÑе агÑегаÑÑ ÑаÑÑо ÑеализÑÑÑÑÑ ÑÑнкÑиÑми, напиÑаннÑми на PL/pgSQL или дÑÑгом пÑоÑедÑÑном ÑзÑке, ÑоÑÑиÑÑÑÑие агÑегаÑнÑе ÑÑнкÑии, как пÑавило, Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð½Ð°Ð¿Ð¸ÑÐ°Ð½Ñ Ð½Ð° C, Ñак как иÑ
знаÑение ÑоÑÑоÑÐ½Ð¸Ñ Ð½ÐµÐ»ÑÐ·Ñ Ð²ÑÑазиÑÑ ÐºÐ°ÐºÐ¸Ð¼-либо Ñипом даннÑÑ
SQL. (ÐбÑаÑиÑе внимание, ÑÑо в пÑиведÑнном вÑÑе пÑимеÑе знаÑение ÑоÑÑоÑÐ½Ð¸Ñ Ð¾Ð±ÑÑвлено как имеÑÑее Ñип internal â ÑÑо ÑипиÑнÑй ваÑианÑ.) РвÑледÑÑвие Ñого, ÑÑо ÑоÑÑиÑÐ¾Ð²ÐºÑ Ð²ÑполнÑÐµÑ ÑÑнкÑÐ¸Ñ Ð·Ð°Ð²ÐµÑÑениÑ, нелÑÐ·Ñ Ð²Ð¾Ð·Ð¾Ð±Ð½Ð¾Ð²Ð¸ÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ вÑ
однÑÑ
ÑÑÑок, пÑÐ¾Ð´Ð¾Ð»Ð¶Ð°Ñ Ð²ÑзÑваÑÑ ÑÑнкÑÐ¸Ñ Ð¿ÐµÑеÑ
ода. ÐÑо ознаÑаеÑ, ÑÑо ÑÑнкÑÐ¸Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ñ
аÑакÑеÑиÑÑÐ¸ÐºÑ READ_ONLY; она должна обÑÑвлÑÑÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ CREATE AGGREGATE Ñ Ñ
аÑакÑеÑиÑÑикой READ_WRITE или SHAREABLE (еÑли она позволÑÐµÑ Ð¿Ñи поÑледÑÑÑиÑ
вÑзоваÑ
ÑÑнкÑии завеÑÑÐµÐ½Ð¸Ñ Ð¸ÑполÑзоваÑÑ Ñже оÑÑоÑÑиÑованное ÑоÑÑоÑние).
ФÑнкÑÐ¸Ñ Ð¿ÐµÑеÑ
ода ÑоÑÑоÑÐ½Ð¸Ñ Ð´Ð»Ñ ÑоÑÑиÑÑÑÑего агÑегаÑа полÑÑÐ°ÐµÑ Ð·Ð½Ð°Ñение ÑекÑÑего ÑоÑÑоÑÐ½Ð¸Ñ Ð¿Ð»ÑÑ Ð°Ð³ÑегиÑÑемÑе вÑ
однÑе даннÑе Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑÑоки и возвÑаÑÐ°ÐµÑ Ð¸Ð·Ð¼ÐµÐ½Ñнное знаÑение ÑоÑÑоÑниÑ. ÐÑо опÑеделение ÑаÑпÑоÑÑÑанÑеÑÑÑ Ð¸ на обÑÑнÑе агÑегаÑÑ, но замеÑÑÑе, ÑÑо непоÑÑедÑÑвеннÑе аÑгÑменÑÑ (еÑли они еÑÑÑ) пÑи ÑÑом не пеÑедаÑÑÑÑ. ФÑнкÑÐ¸Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð¶Ðµ полÑÑÐ°ÐµÑ Ð¿Ð¾Ñледнее знаÑение ÑоÑÑоÑÐ½Ð¸Ñ Ð¸ знаÑÐµÐ½Ð¸Ñ Ð½ÐµÐ¿Ð¾ÑÑедÑÑвеннÑÑ
аÑгÑменÑов (еÑли они еÑÑÑ), а Ñакже (еÑли пÑиÑÑÑÑÑвÑÐµÑ Ñказание finalfunc_extra) знаÑÐµÐ½Ð¸Ñ NULL, ÑооÑвеÑÑÑвÑÑÑие агÑегиÑÑемÑм даннÑм. С обÑÑнÑми агÑегаÑами Ñказание finalfunc_extra дейÑÑвиÑелÑно полезно, ÑолÑко еÑли агÑÐµÐ³Ð°Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾ÑÑнÑй; Ñогда дополниÑелÑнÑе ÑикÑивнÑе аÑгÑменÑÑ Ð½ÐµÐ¾Ð±Ñ
одимÑ, ÑÑÐ¾Ð±Ñ ÑвÑзаÑÑ Ñип ÑезÑлÑÑаÑа ÑÑнкÑии завеÑÑÐµÐ½Ð¸Ñ Ñ Ñипом(ами) вÑ
однÑÑ
даннÑÑ
агÑегаÑа.
РнаÑÑоÑÑее вÑÐµÐ¼Ñ ÑоÑÑиÑÑÑÑие агÑегаÑÑ Ð½Ðµ могÑÑ Ð¸ÑполÑзоваÑÑÑÑ Ð² каÑеÑÑве оконнÑÑ ÑÑнкÑий, поÑÑÐ¾Ð¼Ñ Ð¾Ñ Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð´ÐµÑжка Ñежима движÑÑегоÑÑ Ð°Ð³ÑегаÑа не ÑÑебÑеÑÑÑ.
36.12.4. ЧаÑÑиÑное агÑегиÑование #
ÐополниÑелÑно агÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð´Ð´ÐµÑживаÑÑ ÑаÑÑиÑное агÑегиÑование. ÐÐ´ÐµÑ Ñакого агÑегиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð² Ñом, ÑÑÐ¾Ð±Ñ Ð²ÑзÑваÑÑ ÑÑнкÑии пеÑÐµÑ Ð¾Ð´Ð° ÑоÑÑоÑÐ½Ð¸Ñ Ð´Ð»Ñ ÑазлиÑнÑÑ Ð¿Ð¾Ð´Ð¼Ð½Ð¾Ð¶ÐµÑÑв Ð²Ñ Ð¾Ð´Ð½ÑÑ Ð´Ð°Ð½Ð½ÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимо, а заÑем комбиниÑоваÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÑоÑÑоÑниÑ, вÑÑиÑленнÑе по ÑÑим подмножеÑÑвам, и полÑÑаÑÑ ÑÐ¾Ñ Ð¶Ðµ ÑезÑлÑÑаÑ, ÑÑо бÑл Ð±Ñ Ð¿Ð¾Ð»ÑÑен пÑи ÑканиÑовании ÑÑÐ°Ð·Ñ Ð²ÑÐµÑ Ð²Ñ Ð¾Ð´Ð½ÑÑ Ð´Ð°Ð½Ð½ÑÑ . ÐÑÐ¾Ñ Ñежим Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑименÑÑÑÑÑ Ð´Ð»Ñ Ð¿Ð°ÑаллелÑного агÑегиÑованиÑ, когда ÑазнÑе ÑабоÑие пÑоÑеÑÑÑ ÑканиÑÑÑÑ ÑазлиÑнÑе ÑаÑÑи ÑаблиÑÑ. ÐÑи ÑÑом каждÑй ÑабоÑий пÑоÑеÑÑ Ð²ÑдаÑÑ ÑаÑÑиÑное знаÑение ÑоÑÑоÑниÑ, а в конÑе ÑÑи знаÑÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸ÑÑÑÑÑÑ Ð²Ð¼ÐµÑÑе и полÑÑаеÑÑÑ Ð¾ÐºÐ¾Ð½ÑаÑелÑное знаÑение ÑоÑÑоÑниÑ. (РбÑдÑÑем ÑÑÐ¾Ñ Ñежим Ð¼Ð¾Ð¶ÐµÑ Ñакже пÑименÑÑÑÑÑ, напÑÐ¸Ð¼ÐµÑ Ð´Ð»Ñ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸Ñованного агÑегиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð»Ð¾ÐºÐ°Ð»ÑнÑÑ Ð¸ ÑдалÑннÑÑ ÑаблиÑ, но пока ÑÑо не Ñеализовано.)
ÐÐ»Ñ Ð¿Ð¾Ð´Ð´ÐµÑжки ÑаÑÑиÑного агÑегиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð² опÑеделении агÑегаÑной ÑÑнкÑии должна задаваÑÑÑÑ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸ÑÑÑÑÐ°Ñ ÑÑнкÑиÑ, пÑинимаÑÑÐ°Ñ Ð´Ð²Ð° знаÑÐµÐ½Ð¸Ñ Ñипа ÑоÑÑоÑÐ½Ð¸Ñ Ð°Ð³ÑегаÑа (пÑедÑÑавлÑÑÑие ÑезÑлÑÑаÑÑ Ð°Ð³ÑегиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ двÑм подмножеÑÑвам Ð²Ñ Ð¾Ð´Ð½ÑÑ ÑÑÑок) и вÑдаÑÑÐ°Ñ Ð½Ð¾Ð²Ð¾Ðµ знаÑение Ñипа ÑоÑÑоÑниÑ, пÑедÑÑавлÑÑÑее Ñо ÑоÑÑоÑние, коÑоÑое бÑло Ð±Ñ Ð¿Ð¾Ð»ÑÑено пÑи агÑегиÑовании ÑовокÑпноÑÑи ÑÑÐ¸Ñ Ð¿Ð¾Ð´Ð¼Ð½Ð¾Ð¶ÐµÑÑв ÑÑÑок. ÐÑи ÑÑом оÑноÑиÑелÑнÑй поÑÑдок Ð²Ñ Ð¾Ð´Ð½ÑÑ ÑÑÑок в ÑÑÐ¸Ñ Ð´Ð²ÑÑ Ð¼Ð½Ð¾Ð¶ÐµÑÑÐ²Ð°Ñ Ð½Ðµ оговаÑиваеÑÑÑ. ÐÑо знаÑиÑ, ÑÑо Ð´Ð»Ñ Ð°Ð³ÑегаÑнÑÑ ÑÑнкÑий, завиÑÑÑÐ¸Ñ Ð¾Ñ Ð¿Ð¾ÑÑдка Ð²Ñ Ð¾Ð´Ð½ÑÑ ÑÑÑок, обÑÑно невозможно опÑеделиÑÑ Ð¾ÑмÑÑленнÑÑ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸ÑÑÑÑÑÑ ÑÑнкÑиÑ.
РкаÑеÑÑве пÑоÑÑого пÑимеÑа, ÑаÑÑиÑное агÑегиÑование могÑÑ Ð¿Ð¾Ð´Ð´ÐµÑживаÑÑ ÑÑнкÑии MAX и MIN, еÑли задаÑÑ Ð² каÑеÑÑве комбиниÑÑÑÑей ÑооÑвеÑÑÑвенно ÑÑнкÑÐ¸Ñ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ð·Ð½Ð°Ñений болÑÑее-из-двÑÑ
или менÑÑее-из-двÑÑ
, ÑÑ Ð¶Ðµ, ÑÑо они иÑполÑзÑÑÑ Ð¸ как ÑÑнкÑÐ¸Ñ Ð¿ÐµÑеÑ
ода. ÐÐ»Ñ SUM комбиниÑÑÑÑей ÑÑнкÑией бÑÐ´ÐµÑ Ð¿ÑоÑÑо ÑÑнкÑÐ¸Ñ ÑложениÑ. (Ð ÑÑо опÑÑÑ Ð¶Ðµ ÑÑнкÑÐ¸Ñ Ð¿ÐµÑеÑ
ода, еÑли ÑолÑко знаÑение ÑоÑÑоÑÐ½Ð¸Ñ Ð½Ðµ вÑÑ
Ð¾Ð´Ð¸Ñ Ð·Ð° Ñамки Ñипа вÑ
однÑÑ
даннÑÑ
.)
ÐомбиниÑÑÑÑÐ°Ñ ÑÑнкÑÐ¸Ñ Ð·Ð°Ð´ÐµÐ¹ÑÑвÑеÑÑÑ Ð¿ÑакÑиÑеÑки Ñак же, как ÑÑнкÑÐ¸Ñ Ð¿ÐµÑеÑ
ода, но пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð² каÑеÑÑве вÑоÑого аÑгÑменÑа знаÑение Ñипа ÑоÑÑоÑниÑ, а не нижележаÑего вÑ
одного Ñипа. Ð ÑаÑÑноÑÑи, на Ð½ÐµÑ ÑаÑпÑоÑÑÑанÑÑÑÑÑ Ñе же пÑавила ÑÑÑогоÑÑи ÑÑнкÑии и пеÑедаÑи знаÑений NULL. Также ÑÑÑиÑе, ÑÑо еÑли в опÑеделении агÑегаÑной ÑÑнкÑии задаÑÑÑÑ Ð¾ÑлиÑное Ð¾Ñ NULL знаÑение initcond, оно бÑÐ´ÐµÑ Ð·Ð°Ð´Ð°Ð²Ð°ÑÑ Ð½Ð°ÑалÑное ÑоÑÑоÑние не ÑолÑко Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ пÑоÑ
ода ÑаÑÑиÑного агÑегиÑованиÑ, но Ñакже и наÑалÑное ÑоÑÑоÑние Ð´Ð»Ñ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸ÑÑÑÑей ÑÑнкÑии, коÑоÑÐ°Ñ Ð±ÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ Ð´Ð»Ñ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ ÑаÑÑиÑного ÑезÑлÑÑаÑа в ÑÑом ÑоÑÑоÑнии.
ÐÑли Ñипом ÑоÑÑоÑÐ½Ð¸Ñ Ð°Ð³ÑегаÑной ÑÑнкÑии вÑбÑан internal, комбиниÑÑÑÑÐ°Ñ ÑÑнкÑÐ¸Ñ Ð¾ÑвеÑÐ°ÐµÑ Ð·Ð° Ñо, ÑÑÐ¾Ð±Ñ ÐµÑ ÑезÑлÑÑÐ°Ñ Ð±Ñл помеÑÑн в конÑекÑÑ Ð¿Ð°Ð¼ÑÑи, подÑ
одÑÑий Ð´Ð»Ñ Ð·Ð½Ð°Ñений агÑегаÑного ÑоÑÑоÑниÑ. Ð ÑаÑÑноÑÑи ÑÑо знаÑиÑ, ÑÑо, полÑÑив в пеÑвом аÑгÑменÑе NULL, нелÑÐ·Ñ Ð¿ÑоÑÑо возвÑаÑиÑÑ Ð²ÑоÑой аÑгÑменÑ, Ñак как ÑÑо знаÑение окажеÑÑÑ Ð² невеÑном конÑекÑÑе и не пÑоÑÑÑеÑÑвÑÐµÑ Ð´Ð¾ÑÑаÑоÑное вÑемÑ.
Ðогда Ñипом ÑоÑÑоÑÐ½Ð¸Ñ Ð°Ð³ÑегаÑной ÑÑнкÑии вÑбÑан internal, обÑÑно в опÑеделении агÑегаÑной ÑÑнкÑии Ñакже ÑмеÑÑно задаÑÑ ÑÑнкÑÐ¸Ñ ÑеÑиализаÑии и ÑÑнкÑÐ¸Ñ Ð´ÐµÑеÑиализаÑии, коÑоÑÑе позволÑÑÑ ÐºÐ¾Ð¿Ð¸ÑоваÑÑ Ð·Ð½Ð°Ñение ÑоÑÑоÑÐ½Ð¸Ñ Ð¸Ð· одного пÑоÑеÑÑа в дÑÑгой. Ðез ÑÑиÑ
ÑÑнкÑий паÑаллелÑное агÑегиÑование невозможно, а Ñакже веÑоÑÑно не бÑдÑÑ ÑабоÑаÑÑ Ñакие бÑдÑÑие пÑиложениÑ, как локалÑное/ÑдалÑнное агÑегиÑование.
ФÑнкÑÐ¸Ñ ÑеÑиализаÑии должна пÑинимаÑÑ Ð¾Ð´Ð¸Ð½ аÑгÑÐ¼ÐµÐ½Ñ Ñипа internal и возвÑаÑаÑÑ ÑезÑлÑÑÐ°Ñ Ñипа bytea, пÑедÑÑавлÑÑÑий знаÑение ÑоÑÑоÑниÑ, Ñпакованное в плоÑкий Ð½Ð°Ð±Ð¾Ñ Ð±Ð°Ð¹Ñов. ФÑнкÑÐ¸Ñ Ð´ÐµÑеÑиализаÑии, напÑоÑив, обÑаÑÐ°ÐµÑ ÑÑо пÑеобÑазование. Ðна должна пÑинимаÑÑ Ð´Ð²Ð° аÑгÑменÑа Ñипов bytea и internal и возвÑаÑаÑÑ ÑезÑлÑÑÐ°Ñ Ñипа internal. (ÐÑоÑой ÐµÑ Ð°ÑгÑÐ¼ÐµÐ½Ñ Ð½Ðµ иÑполÑзÑеÑÑÑ Ð¸ вÑегда Ñавен нÑлÑ, но он ÑÑебÑеÑÑÑ Ð¸Ð· ÑообÑажений ÑипобезопаÑноÑÑи.) РезÑлÑÑÐ°Ñ ÑÑнкÑии деÑеÑиализаÑии ÑледÑÐµÑ Ð¿ÑоÑÑо ÑазмеÑÑиÑÑ Ð² ÑекÑÑем конÑекÑÑе памÑÑи, Ñак как в оÑлиÑие Ð¾Ñ ÑезÑлÑÑаÑа комбиниÑÑÑÑей ÑÑнкÑии он недолговеÑен.
Также ÑÑÐ¾Ð¸Ñ Ð·Ð°Ð¼ÐµÑиÑÑ, ÑÑо Ð´Ð»Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð°Ð³ÑегаÑной ÑÑнкÑии в паÑаллелÑном Ñежиме она должна имеÑÑ Ñ
аÑакÑеÑиÑÑÐ¸ÐºÑ PARALLEL SAFE (безопаÑÐ½Ð°Ñ Ð´Ð»Ñ ÑаÑпаÑаллеливаниÑ). ХаÑакÑеÑиÑÑики допÑÑÑимоÑÑи ÑаÑпаÑÐ°Ð»Ð»ÐµÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ ÐµÑ Ð¾Ð¿Ð¾ÑнÑÑ
ÑÑнкÑий знаÑÐµÐ½Ð¸Ñ Ð½Ðµ имеÑÑ.
36.12.5. ÐÑпомогаÑелÑнÑе ÑÑнкÑии Ð´Ð»Ñ Ð°Ð³ÑегаÑов #
ФÑнкÑиÑ, напиÑÐ°Ð½Ð½Ð°Ñ Ð½Ð° C, Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделиÑÑ, бÑла ли она вÑзвана как вÑпомогаÑелÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð°Ð³ÑегиÑованиÑ, вÑзвав AggCheckCallContext, напÑимеÑ, Ñак:
if (AggCheckCallContext(fcinfo, NULL))
СмÑÑл Ñакой пÑовеÑки в Ñом, ÑÑо в ÑлÑÑае положиÑелÑного ÐµÑ ÑезÑлÑÑаÑа пеÑвÑм вÑ
однÑм аÑгÑменÑом ÑвлÑеÑÑÑ Ð²Ñеменное знаÑение ÑоÑÑоÑниÑ, коÑоÑое можно безопаÑно модиÑиÑиÑоваÑÑ Ð½Ð° меÑÑе, не ÑÐ¾Ð·Ð´Ð°Ð²Ð°Ñ Ð½Ð¾Ð²ÑÑ ÐºÐ¾Ð¿Ð¸Ñ. ÐÑÐ¸Ð¼ÐµÑ Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе ÑвидеÑÑ Ð² ÑÑнкÑии int8inc(). (ХоÑÑ Ð°Ð³ÑегаÑнÑе ÑÑнкÑии пеÑеÑ
ода вÑегда могÑÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ Ð½ÐµÐ¿Ð¾ÑÑедÑÑвенно пеÑеÑ
одное знаÑение, агÑегаÑнÑе ÑÑнкÑии завеÑÑÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸Ð·Ð±ÐµÐ³Ð°ÑÑ ÑÑого; еÑли они ÑÑо делаÑÑ, Ñакое поведение должно оÑмеÑаÑÑÑÑ Ð¿Ñи Ñоздании агÑегаÑа. Ðа дополниÑелÑнÑми подÑобноÑÑÑми обÑаÑиÑеÑÑ Ðº CREATE AGGREGATE.)
ÐÑоÑой аÑгÑÐ¼ÐµÐ½Ñ AggCheckCallContext можно иÑполÑзоваÑÑ, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ ÐºÐ¾Ð½ÑекÑÑ Ð¿Ð°Ð¼ÑÑи, в коÑоÑом ÑодеÑжаÑÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð°Ð³ÑегаÑного ÑоÑÑоÑниÑ. ÐÑо полезно Ð´Ð»Ñ ÑÑнкÑий пеÑеÑ
ода, коÑоÑÑе желаÑÑ Ð¸ÑполÑзоваÑÑ Â«ÑазвÑÑнÑÑÑе» обÑекÑÑ (Ñм. ÐодÑаздел 36.13.1) в каÑеÑÑве знаÑений ÑоÑÑоÑниÑ. ÐÑи пеÑвом вÑзове ÑÐ°ÐºÐ°Ñ ÑÑнкÑÐ¸Ñ Ð¿ÐµÑеÑ
ода должна возвÑаÑиÑÑ ÑазвÑÑнÑÑÑй обÑÐµÐºÑ Ð² конÑекÑÑе памÑÑи, оÑноÑÑÑемÑÑ Ðº конÑекÑÑÑ ÑоÑÑоÑÐ½Ð¸Ñ Ð°Ð³ÑегаÑа, а заÑем пÑодолжаÑÑ Ð²Ð¾Ð·Ð²ÑаÑаÑÑ ÑÐ¾Ñ Ð¶Ðµ обÑÐµÐºÑ Ð¿Ñи поÑледÑÑÑиÑ
вÑзоваÑ
. ÐапÑимеÑ, ÑÑÑ Ð»Ð¾Ð³Ð¸ÐºÑ Ð¼Ð¾Ð¶Ð½Ð¾ ÑвидеÑÑ Ð² ÑÑнкÑии array_append(). (ФÑнкÑÐ¸Ñ array_append() не иÑполÑзÑеÑÑÑ Ð² каÑеÑÑве пеÑеÑ
ода никаким вÑÑÑоеннÑм агÑегаÑом, но она напиÑана Ñак, ÑÑÐ¾Ð±Ñ ÑабоÑаÑÑ ÑÑÑекÑивно в Ñаком каÑеÑÑве в дополниÑелÑном агÑегаÑе.)
ÐÑÑ Ð¾Ð´Ð½Ð° вÑпомогаÑелÑÐ½Ð°Ñ Ð¿Ð¾Ð´Ð¿ÑогÑамма, пÑедназнаÑÐµÐ½Ð½Ð°Ñ Ð´Ð»Ñ Ð°Ð³ÑегаÑнÑÑ
ÑÑнкÑий, напиÑаннÑÑ
на C, назÑваеÑÑÑ AggGetAggref. ÐÑа ÑÑнкÑÐ¸Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ Ñзел ÑазбоÑа Aggref, опиÑÑваÑÑий вÑзов агÑегаÑа. ÐÑо в оÑновном полезно Ð´Ð»Ñ ÑоÑÑиÑÑÑÑиÑ
агÑегаÑов, коÑоÑÑе могÑÑ Ð¸ÑÑледоваÑÑ ÑÑÑÑкÑÑÑÑ Ñзла Aggref и вÑÑÑниÑÑ, какой поÑÑдок ÑоÑÑиÑовки они Ð´Ð¾Ð»Ð¶Ð½Ñ ÑеализоваÑÑ.