39.1. PL/Perl ÇÔ¼ö¿Í ÀÎÀÚ

PL/Perl ¾ð¾î·Î ÇÔ¼ö¸¦ ÀÛ¼ºÇÏ·Á¸é, ÀÌÇÏÀÇ Ç¥ÁØÀûÀÎ CREATE FUNCTION ±¸¹®À» »ç¿ëÇØ ÁÖ¼¼¿ä.

CREATE FUNCTION 
funcname
 (
argument-types
) RETURNS 
return-type
 AS $$
    # PL/Perl function body
$$ LANGUAGE plperl;

ÇÔ¼ö º»¹®Àº Åë»óÀÇ PerlÀÇ ÄÚµåÀÔ´Ï´Ù. ½ÇÁ¦, PL/PerlÀÇ Ç®¸ÔÀÓ ÄÚµå´Â, À̰ÍÀ» PerlÀÇ ¼­ºê·çƾÀÇ ³»ºÎ¿¡ ÀúÀåÇÕ´Ï´Ù. PL/Perl ÇÔ¼ö´Â Ç×»ó scalar°ªÀ» µ¹·ÁÁÖÁö ¾ÊÀ¸¸é ¾ÈµË´Ï´Ù. Èļú´ë·Î, ÂüÁ¶¸¦ »ç¿ëÇØ º¹ÀâÇÑ ±¸Á¶(¹è¿­, ·¹ÄÚµå, ÁýÇÕ)¸¦ µ¹·ÁÁÙ ¼ö°¡ ÀÖ½À´Ï´Ù. ¸®½ºÆ®¸¦ µ¹·ÁÁÖÁö ¾Ê½À´Ï´Ù.

Note: Perl, ƯÈ÷ ±× ´ÝÈù ¹üÀ§·Î ±¹¼Ò º¯¼ö¸¦ ÂüÁ¶ÇÏ´Â °Í °°Àº °æ¿ì¿¡¼­´Â, À̸§ ÷ºÎÀÇ »óÀÚÀå ¼­ºê·çƾÀÇ »ç¿ëÀº À§ÇèÇÕ´Ï´Ù. PL/Perl ÇÔ¼ö´Â ¼­ºê·çƾ³»¿¡ ÀúÀåµÇ±â ¶§¹®¿¡, À̸§ ÷ºÎÀÇ ¼­ºê·çƾÀº ¸ðµÎ »óÀÚ·Î µË´Ï´Ù. ÀϹÝÀûÀ¸·Î, ÄÚµå ÂüÁ¶¸¦ °³ÀÔ½ÃÄÑ È£ÃâÇÏ´Â ÀÍ¸í ¼­ºê·çƾÀ» ÀÛ¼ºÇÏ´Â ÆíÀÌ ²Ï ¾ÈÀüÇÕ´Ï´Ù. ÀÚ¼¼ÇÑ °ÍÀº perldiag¸Þ´º¾ó ÆäÀÌÁö¸¦ ÂüÁ¶ÇØ ÁÖ¼¼¿ä.

CREATE FUNCTION¸í·ÉÀÇ ±¸¹®¿¡¼­´Â, ÇÔ¼ö º»Ã¼´Â ¹®ÀÚ¿­ Á¤¼ö·Î¼­ ±â¼úµÇ´Â °ÍÀ» Çʼö·Î Çϰí ÀÖ½À´Ï´Ù. Åë»ó, ¹®ÀÚ¿­ Á¤¼ö¿¡´Â ´Þ·¯ ÀοëºÎÈ£ ºÙÀ̰í(Section 4.1.2.2¸¦ ÂüÁ¶)¸¦ »ç¿ëÇÏ´Â °ÍÀÌ °¡Àå Æí¸®ÇÕ´Ï´Ù. À̽ºÄÉÀÌÇÁ ¹®ÀÚ¿­ ±¸¹® E''¸¦ »ç¿ëÇÏ´Â °ÍÀ» ¼±ÅÃÇßÀ» °æ¿ì, ÇÔ¼ö º»¹®À¸·Î »ç¿ëµÇ´Â ´ÜÀÏ ÀοëºÎÈ£(')¿Í backslash(\)¸¦ ÀÌÁßÀοëºÎÈ£À» ÇÏÁö ¾ÊÀ¸¸é ¾ÈµË´Ï´Ù. (Section 4.1.2.1¸¦ ÂüÁ¶).

ÀÎÀÚ¿Í °á°ú´Â ´Ù¸¥ Perl ¼­ºê·çƾ°ú °°°Ô ´Ù·ç¾îÁý´Ï´Ù. ÀÎÀÚ´Â @_ÀÇ ¾È¿¡°Ô °Ç³×Á® °á°ú°ªÀºreturn, ¶Ç´Â, ±× ÇÔ¼ö·Î ¸¶Áö¸·¿¡ Æò°¡µÈ ½ÄÀ¸·Î¼­ µ¹·ÁÁÖ¾îÁý´Ï´Ù.

¿¹¸¦ µé¸é, 2°³ÀÇ Á¤¼öÀÇ ´õ Å« ÆíÀ» µ¹·ÁÁÖ´Â ÇÔ¼ö´Â ÀÌÇÏ¿Í °°ÀÌ Á¤ÀÇÇÒ ¼ö ÀÖ½À´Ï´Ù.

CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$
    if ($_[0] > $_[1]) { return $_[0]; }
    return $_[1];
$$ LANGUAGE plperl;

SQLÀÇ NULL°ªÀÌ ÇÔ¼ö¿¡°Ô °Ç³×Á³À» °æ¿ì, ±× ÀÎÀÚ°ªÀº Perl¿¡¼­ "Á¤Àǰ¡ ¾ÈµÈ"°ÍÀ¸·Î ³ªÅ¸³³´Ï´Ù. À§ÀÇ ÇÔ¼ö Á¤ÀÇ¿¡¼­´Â, NULL°ªÀÌ ÀԷµǾúÀ» °æ¿ì Àß µ¿ÀÛÇÏÁö ¾ÊÀ» °ÍÀÔ´Ï´Ù(½ÇÁ¦´Â ±×°ÍÀÌ 0ÀÎ°Í °°ÀÌ µ¿ÀÛÇϰÚÁö¿ä). STRICT¸¦ ÇÔ¼ö Á¤ÀÇ¿¡ °¡¼¼ÇÏ´Â °ÍÀ¸·Î, PostgreSQLÀÇ µ¿ÀÛÀ» º¸´Ù ÇÕ¸®ÀûÀ¸·Î ÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. NULL°ª°¡ °Ç³×¹Þ¾ÒÀ» °æ¿ì, ÇÔ¼ö´Â ÀüÇô ºÒ·Á °¡Áö ¾Ê°í, ´ÜÁö NULLÀ̶ó´Â °á°ú°¡ ÀÚµ¿ÀûÀ¸·Î µ¹·ÁÁÖ¾îÁý´Ï´Ù. ´Ù¸¥ ¹æ¹ýÀ¸·Î¼­ ÇÔ¼ö º»Ã¼·Î Á¤ÀǵÇÁö ¾ÊÀº ÀÔ·ÂÀ» üũÇÒ ¼öµµ ÀÖ½À´Ï´Ù. ¿¹¸¦ µé¸é, perl_maxÀÇ ÀÎÀÚÀÇ ´Ù¸¥ ÇÑÂÊÀÌ NULLÀ̰í, ´Ù¸¥ ÇÑÂÊÀÌ NULLÀÌ ¾Æ´Ñ °æ¿ì¿¡, NULL°ª´Â ¾Æ´Ï°í NULLÀÌ ¾Æ´Ñ ÀÎÀÚ¸¦ µ¹·ÁÁÝ´Ï´Ù.

CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$
    my ($x,$y) = @_;
    if (! defined $x) {
        if (! defined $y) { return undef; }
        return $y;
    }
    if (! defined $y) { return $x; }
    if ($x > $y) { return $x; }
    return $y;
$$ LANGUAGE plperl;

À§¿¡¼­ °¡¸®Å² ´ë·Î, PL/Perl ÇÔ¼ö·ÎºÎÅÍ SQLÀÇ NULL°ªÀ» µ¹·ÁÁÖ±â À§Çؼ­´Â, ¹ÌÁ¤ÀǰªÀ» µ¹·ÁÁÖµµ·Ï ÇØ ÁÖ¼¼¿ä. À̰ÍÀº, ÇÔ¼ö°¡ ¾ö¹ÐÇѰ¡ ¾î¶²°¡¿¡ °ü°è¾øÀÌ, ½ÇÇàÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.

Perl´Â, PostgreSQLÀÇ ¹è¿­À» Perl ¹è¿­ÀÇ ÂüÁ¶·Î¼­ µ¹·ÁÁÙ ¼ö°¡ ÀÖ½À´Ï´Ù. ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE OR REPLACE function returns_array()
RETURNS text[][] AS $$
    return [['a"b','c,d'],['e\\f','g']];
$$ LANGUAGE plperl;

select returns_array();

º¹ÇÕÇüÀÇ ÀÎÀÚ´Â ÇØ½Ã¿¡ÀÇ ÂüÁ¶·Î¼­ ÇÔ¼ö¿¡ °Ç³×Áý´Ï´Ù. ÇØ½ÃÀÇ Å°´Â º¹ÇÕÇüÀÇ ¼Ó¼º¸íÀÔ´Ï´Ù. ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE TABLE employee (
    name text,
    basesalary integer,
    bonus integer
);

CREATE FUNCTION empcomp(employee) RETURNS integer AS $$
    my ($emp) = @_;
    return $emp->{basesalary} + $emp->{bonus};
$$ LANGUAGE plperl;

SELECT name, empcomp(employee.*) FROM employee;

ÇÊ¿äÇÑ ¼Ó¼ºÀ» °¡Áö´Â ÇØ½ÃÀÇ ÂüÁ¶¸¦ µ¹·ÁÁÖ´Â °Í°ú °°Àº ¹æ¹ýÀ¸·Î, PL/Perl ÇÔ¼ö´Â º¹ÇÕÇüÀÇ °á°ú¸¦ µ¹·ÁÁÙ ¼ö°¡ ÀÖ½À´Ï´Ù. ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE TYPE testrowperl AS (f1 integer, f2 text, f3 text);

CREATE OR REPLACE FUNCTION perl_row() RETURNS testrowperl AS $$
    return {f2 => 'hello', f1 => 1, f3 => 'world'};
$$ LANGUAGE plperl;

SELECT * FROM perl_row();

¼±¾ðµÈ °á°ú µ¥ÀÌÅÍÇüÀÇ ÀÓÀÇÀÇ ¿­ °¡¿îµ¥, ÇØ½Ã³»¿¡ Á¸ÀçÇÏÁö ¾Ê´Â °ÍÀº NULL°ªÀ¸·Î¼­ µ¹·ÁÁÖ¾îÁý´Ï´Ù.

¶Ç, PL/Perl ÇÔ¼ö´Â ½ºÄ®¶óÇüÀÇ ¹è¿­À̳ª º¹ÇÕÇüÀÇ ¹è¿­À» µ¹·ÁÁÙ ¼öµµ ÀÖ½À´Ï´Ù. Åë»ó, ±âµ¿ ó¸®ÀÇ °í¼ÓÈ­¿Í ¸Þ¸ð¸®³»ÀÇ °á°ú ¼¼Æ® Àüü¸¦ ±â´Ù¸®´Â Çà·Ä ·Î À¯ÁöÇÒ ¼ö ÀÖ´Â °ÍÀ¸·ÎºÎÅÍ, 1¹ø¿¡ 1ÇàÀ» µ¹·ÁÁÖ´Â ÆíÀÌ ÁÁÀ» °ÍÀÔ´Ï´Ù. ÀÌÇÏ¿¡ ³ªÅ¸³»´Â return_next¸¦ »ç¿ëÇØ, À̰ÍÀ» ½Ç½ÃÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. ¸¶Áö¸· return_nextÀÇ ´ÙÀ½¿¡, return ¶Ç´Â return undef(Ãßõ)¸¦ ±â¼úÇØ¾ß ÇÏ´Â °Í¿¡ ÁÖÀÇÇØ ÁÖ¼¼¿ä.

CREATE OR REPLACE FUNCTION perl_set_int(int)
RETURNS SETOF INTEGER AS $$
    foreach (0..$_[0]) {
        return_next($_);
    }
    return undef;
$$ LANGUAGE plperl;

SELECT * FROM perl_set_int(5);

CREATE OR REPLACE FUNCTION perl_set()
RETURNS SETOF testrowperl AS $$
    return_next({ f1 => 1, f2 => 'Hello', f3 => 'World' });
    return_next({ f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' });
    return_next({ f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' });
    return undef;
$$ LANGUAGE plperl;

¼Ò±Ô¸ðÀÇ °á°ú ÁýÇÕ¿¡¼­´Â, °¢°¢ ´Ü¼øÇÑ ÇüÅÂ, ¹è¿­Çü, º¹ÇÕÇü¿¡ ´ëÀÀÇÏ´Â, ½ºÄ®¶ó, ¹è¿­ÀÇ ÂüÁ¶, ÇØ½ÃÀÇ ÂüÁ¶¸¦ Æ÷ÇÔÇÑ ¹è¿­ÀÇ ÂüÁ¶¸¦ µ¹·ÁÁÙ ¼ö°¡ ÀÖ½À´Ï´Ù. ÀÌÇÏ, ¹è¿­¿¡ÀÇ ÂüÁ¶·Î¼­ °á°ú ÁýÇÕ Àüü¸¦ µ¹·ÁÁÖ´Â ´Ü¼øÇÑ ¿¹¸¦ ¸î°³ °¡¸®Åµ´Ï´Ù.

CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$
    return [0..$_[0]];
$$ LANGUAGE plperl;

SELECT * FROM perl_set_int(5);

CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
    return [
        { f1 => 1, f2 => 'Hello', f3 => 'World' },
        { f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' },
        { f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' }
    ];
$$ LANGUAGE plperl;

SELECT * FROM perl_set();

Äڵ峻¿¡¼­ strictÇÁ¶ó±×¸¶¸¦ »ç¿ëÇÏ°í ½ÍÀ¸¸é, SET plperl.use_strict¸¦ ÂüÀ¸·Î ÇÏ´Â °ÍÀÌ °¡Àå °£´ÜÇÑ ¹æ¹ýÀÔ´Ï´Ù. ÀÌ ¸Å°³º¯¼ö´Â, ±× ÈÄÀÇ PL/PerlÇÔ¼öÀÇ º¯¿ª¿¡ ¿µÇâÀ» ÁÝ´Ï´Ù. ÇöÀçÀÇ ¼¼¼ÇÀ¸·Î º¯¿ªÀÌ ³¡³­ ÇÔ¼ö¿¡´Â ¿µÇâÀ» ÁÖÁö ¾Ê½À´Ï´Ù. PL/Perl¸¦ ·ÎµåÇϱâ Àü¿¡ ÀÌ ¸Å°³º¯¼ö¸¦ ¼³Á¤ÇÏ·Á¸é, postgresql.conf³»ÀÇ custom_variable_classesÀ϶÷¿¡ "plperl"¸¦ Ãß°¡ÇÏÁö ¾ÊÀ¸¸é ¾ÈµË´Ï´Ù.

strictÇÁ¶ó±×¸¶¸¦ »ç¿ëÇϱâ À§ÇÑ ´Ù¸¥ ¹æ¹ýÀº, ÀÌÇϸ¦ ÇÔ¼ö º»¹®¿¡ ±âÀçÇÏ´Â °ÍÀÔ´Ï´Ù.

use strict;

±×·¯³ª, À̰ÍÀº PL/PerlUÇÔ¼ö·Î ¹Û¿¡ µ¿ÀÛÇÏÁö ¾Ê½À´Ï´Ù. use´Â ½Å·ÚÇÒ ¼ö ÀÖ´Â Á¶ÀÛÀº ¾Æ´Ï±â ¶§¹®ÀÔ´Ï´Ù. ´ë½Å, PL/PerlÇÔ¼ö¿¡¼­´Â ÀÌÇÏ¿Í °°ÀÌ ÇØ ÁÖ¼¼¿ä.

BEGIN { strict->import(); }