33.10. »ç¿ëÀÚ Á¤ÀÇÀÇ Áý°è

PostgreSQL¿¡ À־ÀÇ Áý°è ÇÔ¼ö´Â, »óÅÂÄ¡¿Í »óÅ Àüȯ ÇÔ¼ö·Î Ç¥ÇöµÇ°í ÀÖ½À´Ï´Ù. Áï, 1°³ÀÇ Áý°è´Â, ÀÔ·ÂÇàÀÌ Ã³¸®µÉ ¶§ º¯°æµÇ´Â »óŰªÀ» »ç¿ëÇØ ¿¬»êµË´Ï´Ù. »õ·Î¿î Áý°è ÇÔ¼ö¸¦ Á¤ÀÇÇϱâ À§Çؼ­´Â, »óŰªÀÇ µ¥ÀÌÅÍÇü, »óÅÂÀÇ ÃʱⰪ, ±×¸®°í »óÅ Àüȯ ÇÔ¼ö¸¦ ¼±ÅÃÇÕ´Ï´Ù. »óÅ Àüȯ ÇÔ¼ö´Â ´Ü¼øÇÑ º¸Åë ÇÔ¼ö·Î, Áý°è ÀÌ¿ÜÀÇ ¹®¸Æ¿¡¼­µµ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù. ¿ä±¸µÇ´Â Áý°èÀÇ °á°ú°¡ »óŰªÀ» À¯ÁöÇØ¾ß ÇÏ´Â µ¥ÀÌÅÍ¿Í ´Ù¸¥ °æ¿ì´Â, ÃÖÁ¾ ÇÔ¼öµµ ÁöÁ¤ÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.

µû¶ó¼­, Áý°èÀÇ »ç¿ëÀÚ·Î º¸ÀÌ´Â Àμö¿Í °á°ú µ¥ÀÌÅÍÇü À̿ܿ¡µµ, µÎ Àμö¿Í °á°úÇü°ú ¸ðµÎ ´Ù¸¥ ³»ºÎ »óŰªÀÇ µ¥ÀÌÅÍÇüÀÌ ÀÖ½À´Ï´Ù.

¸¸¾à ÃÖÁ¾ ÇÔ¼ö¸¦ »ç¿ëÇÏÁö ¾Ê´Â Áý°è¸¦ Á¤ÀÇÇß´Ù°í Çϸé, °¢°¢ÀÇ ÇàÀÇ ¿­°ªÀÇ ½ÇÇà ÇÔ¼ö·Î °è»êµÈ °á°ú¸¦ Áý°è ÇÒ ¼ö ÀÖ½À´Ï´Ù. sum´Â ±×·¯ÇÑ Áý°èÀÇ ÀÏ·ÊÀÔ´Ï´Ù. sum´Â 0À¸·ÎºÎÅÍ ½ÃÀ۵Ǿî, Ç×»ó ÇöÀçÀÇ ÇàÀÇ °ªÀ» ±× ½ÃÁ¡±îÁöÀÇ ÃÑ ½ÇÇà°ª¿¡ Ãß°¡ÇÕ´Ï´Ù. ¿¹¸¦ µé¸é, ¸¸¾à sumÁý°è¸¦ º¹¼Ò¼öÀÇ µ¥ÀÌÅÍÇüÀ¸·Î µ¿ÀÛÇÏ°Ô ÇÏ°í ½ÍÀ¸¸é, ±× µ¥ÀÌÅÍÇüÀÇ °¡»ê ÇÔ¼ö¸¸ÀÌ ÇÊ¿äÇÏ°Ô µË´Ï´Ù. Áý°è Á¤ÀÇ´Â ÀÌÇÏ¿Í °°ÀÌ µË´Ï´Ù.

CREATE AGGREGATE sum (complex)
(
    sfunc = complex_add,
    stype = complex,
    initcond = '(0,0)'
);

SELECT sum(a) FROM test_complex;

   sum
-----------
 (34,53.9)

(ÇÔ¼öÀÇ ¿À¹ö¶óÀ̵å(override) ±â´É¿¡ ÀÇÁ¸Çϰí ÀÖ´Â °Í¿¡ ÁÖÀÇÇØ ÁÖ¼¼¿ä. sum¶ó´Â À̸§ÀÇ Áý°è ÇÔ¼ö´Â º¹¼ö Á¸ÀçÇÏÁö¸¸, PostgreSQL´Â ¿­ÀÇ ÇüÅÂcomplex¿¡ Àû¿ëÇÒ ¼ö ÀÖ´Â sum ÇÔ¼ö¸¦ ã¾Æ³¾ ¼ö ÀÖ½À´Ï´Ù. )

»ó±âÀÇ sumÀÇ Á¤ÀÇ´Â, ¸¸¾à ºñNULLÀÇ ÀԷ°ªÀÌ ¾øÀ¸¸é 0(Ãʱ⠻óÅÂ)À» µ¹·ÁÁÝ´Ï´Ù. ±× °æ¿ì, NULL¸¦ µ¹·ÁÁÖ°í ½ÍÀº °ÍÀÌ ¾Æ´Ò±î »ý°¢Çϰí, Ç¥ÁØ SQL¿¡¼­´Â sum°¡ ±×ó·³ µ¿ÀÛÇÏ´Â °ÍÀ» ±â´ëÇϰí ÀÖ½À´Ï´Ù. ±×·¸°Ô Çϱâ À§Çؼ­ ´ÜÁö initcond±¸¸¦ »ý·« Çϸé, Ãʱ⠻óŰ¡ NULL°¡ µË´Ï´Ù. Åë»ó sfunc°¡ NULL »óÅÂÀÇ ÀÔ·ÂÀ» Ã¼Å©ÇØ¾ß¸¸ ÇÑ´Ù´Â °ÍÀ» ÀǹÌÇÕ´Ï´Ù¸¸, sum³ª, ±× ¿Ü max,min¿Í °°ÀÌ ´Ü¼øÇÑ Áý°è¿¡ À־´Â, ÃÖÃÊÀÇ ºñNULL ÀԷ°ªÀ» »óÅ º¯¼ö¿¡ »ðÀÔÇØ, 2¹øÂ°ÀÇ ºñNULL ÀԷ°ªÀ¸·Î »óÅ Àüȯ ÇÔ¼ö¸¦ Àû¿ë½ÃŰ±â ½ÃÀÛÇϸé ÃæºÐÇÕ´Ï´Ù. PostgreSQL´Â, ¸¸¾à Ãʱ⠻óŰ¡ NULL·Î »óÅ Àüȯ ÇÔ¼ö°¡"¾ö¹Ð(strict)"°ú ¼³Á¤µÇ¾î ÀÖ´Â °æ¿ì, ÀÚµ¿ÀûÀ¸·Î ±×°ÍÀ» ½ÇÇàÇÕ´Ï´Ù(Áï NULL ÀÔ·ÂÀ¸·Î´Â ºÒ·Á °¡Áö ¾Ê°Ô µË´Ï´Ù).

¶Ç´Ù¸¥ "¾ö¹Ð(strict)"ÀÎ »óÅ Àüȯ ÇÔ¼öÀÇ µðÆúÆ® µ¿ÀÛÀº NULL ÀԷ°ªÀÌ ³ªÅ¸³ª±â Àü »óŰªÀÌ º¯ÇÔ¾øÀÌ¿¡ À¯ÁöµÇ´Â °ÍÀÌ ÀÖ½À´Ï´Ù. µû¶ó¼­, NULL°ªÀº ¹«½ÃµË´Ï´Ù. ¸¸¾à NULL ÀԷ¿¡ ´ëÇØ ´Ù¸¥ µ¿ÀÛÀÌ ÇÊ¿äÇÑ °æ¿ì´Â, »óÅ Àüȯ ÇÔ¼ö¸¦ strict·Î Á¤ÀÇÇÏÁö ¾Ê°í, NULL ÀÔ·ÂÀÇ °Ë»ç¸¦ ½Ç½ÃÇϵµ·Ï ÄÚµù ÇØ, ÇÊ¿ä½Ã »ç¿ëÇϸé ÁÁ½À´Ï´Ù.

avg(Æò±Õ°ª °è»ê)´Â Á» ´õ º¹ÀâÇÑ Áý°èÀÇ ÀÏ·ÊÀÔ´Ï´Ù. °Å±â¿¡´Â 2°³ÀÇ º¯µ¿ÇÏ´Â »óŰ¡ ÇÊ¿äÇÏ°Ô µË´Ï´Ù. ÀÔ·ÂÀÇ ÇÕ°è¿Í ÀԷ¼öÀÇ Ä«¿îÆ®ÀÔ´Ï´Ù. ÃÖÁ¾ °á°ú´Â ÀÌ µÎ °ªÀ» ³ª´°¼ÀÇÏ´Â °Í¿¡ ÀÇÇØ ¾òÀ» ¼ö ÀÖ½À´Ï´Ù. Æò±Õ°ª °è»êÀº ÀüÇüÀûÀ¸·Î 2 ¿ä¼ÒÀÇ ¹è¿­À» »óÅ Àüȯ°ªÀ¸·Î »ç¿ëÇØ ±¸ÇöµË´Ï´Ù. ¿¹¸¦ µé¸é, avg(float8)ÀÇ ³»ºÎÀûÀÎ ±¸ÇöÀº ÀÌÇÏ¿Í °°ÀÌ µÇ¾î ÀÖ½À´Ï´Ù.

CREATE AGGREGATE avg (float8)
(
    sfunc = float8_accum,
    stype = float8[],
    finalfunc = float8_avg,
    initcond = '{0,0}'
);

Áý°è ÇÔ¼ö´Â ´Ù¾çÇÑ »óÅ Àüȯ ÇÔ¼ö³ª ÃÖÁ¾ ÇÔ¼ö¸¦ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù. À̰Ϳ¡ ÀÇÇØ, °°Àº ÇÔ¼ö¸¦ »ç¿ëÇØ º¹¼öÀÇ Áý°è¸¦ ±¸ÇöÇÒ ¼ö ÀÖ½À´Ï´Ù. Section 33.2.5¿¡ ´Ù¾çÇÑ ÇÔ¼öÀÇ ¼³¸íÀÌ ÀÖ½À´Ï´Ù. Á» ´õ ¼¼¼¼ÇÏ°Ô ¸»Çϸé, Áý°è ÇÔ¼ö ÀÚ½ÅÀº, ´ÜÀÏÀÇ Áý°è Á¤ÀÇ·Î º¹¼öÀÇ ÀÔ·Â µ¥ÀÌÅÍÇüÀ» Ãë±ÞÇÒ ¼ö°¡ ÀÖµíÀÌ, ´Ù¾çÇÑ ÀÔ·ÂÇü°ú »óÅÂÇüÀ» ÁöÁ¤ÇÒ ¼ö ÀÖ½À´Ï´Ù. ÀÌÇÏ¿¡ ´Ù¾ç Áý°èÀÇ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE AGGREGATE array_accum (anyelement)
(
    sfunc = array_append,
    stype = anyarray,
    initcond = '{}'
);

¿©±â¼­, Áý°è¸¦ ½Ç½ÃÇϴ ȣÃâÀÇ ½ÇÁ¦ »óÅ´Â, ±× ¿ä¼Ò°¡ µÇ´Â ½ÇÁ¦ÀÇ ÀÔ·ÂÇüÀ» °¡Áø ¹è¿­ÇüÀÔ´Ï´Ù.

ÀÌÇÏ¿¡ ¼­·Î ´Ù¸¥ µÎ °¡ÁöÀÇ ½ÇÁ¦ µ¥ÀÌÅÍÇüÀ» Àμö·Î¼­ »ç¿ëÇÑ Ãâ·Â¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

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,spclocation,spcacl}
(1 row)

SELECT attrelid::regclass, array_accum(atttypid)
    FROM pg_attribute
    WHERE attnum > 0 AND attrelid = 'pg_tablespace'::regclass
    GROUP BY attrelid;

   attrelid    |   array_accum   
---------------+-----------------
 pg_tablespace | {19,26,25,1034}
(1 row)

C¾ð¾î·Î ÀÛ¼ºµÈ ÇÔ¼ö´Â, ¿¹¸¦ µé¸é ÀÌÇÏ¿Í °°ÀÌ ÇÔ¼ö È£Ãâ"¹®¸Æ"À¸·Î¼­AggState³ëµå·ÎºÎÅÍ °Ç³×¹Þ¾Ò´ÂÁö ¾î¶°Çß´ÂÁö¸¦ È®ÀÎÇÏ´Â °ÍÀ¸·Î, Áý°èÀÇ Àüȯ ÇÔ¼ö·Î¼­ ºÒ·Á °¬´ÂÁö ÃÖÁ¾ ÇÔ¼ö·Î¼­ ºÒ·Á °¬´ÂÁö¸¦ °ËÃâÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.

        if (fcinfo->context && IsA(fcinfo->context, AggState))

ÀÌ Á¡°ËÀ» ½Ç½ÃÇÏ´Â ÀÌÀ¯ÀÇ Çϳª´Â, ù¹øÂ° ÀÔ·ÂÀº Àӽà Àüȯ °ªÀ̾î¾ß Çϸç, »õ·Î¿î º¹»çº»À» ÇÒ´çÇϱ⺸´Ù´Â ¾ÈÀüÇÏ°Ô ¼öÁ¤µÇ¾î¾ß ÇÑ´Ù´Â °ÍÀÔ´Ï´Ù. (À̰ÍÀº ÇÔ¼ö³»¿¡¼­ ÂüÁ¶ ÀεµÀÇ ÀÔ·ÂÀ» ¾ÈÀüÇÏ°Ô º¯°æÇÒ ¼ö ÀÖ´Â À¯ÀÏÇÑ °æ¿ìÀÔ´Ï´Ù). ¿¹´Â, int8inc()¸¦ ÂüÁ¶ÇØ ÁÖ¼¼¿ä.

´õ ÀÚ¼¼ÇÑ Á¤º¸´Â, CREATE AGGREGATE ¸í·ÉÀ» ÂüÁ¶ÇØ ÁÖ¼¼¿ä.