43.4. Valores globais no PL/Perl #

Pode ser usado o hash global %_SHARED para armazenar dados, incluindo referências a código, entre as chamadas de função durante o tempo de vida da sessão corrente.

A seguir está um exemplo simples para dados compartilhados:

CREATE OR REPLACE FUNCTION set_var(nome text, valor text) RETURNS text AS $$
    if ($_SHARED{$_[0]} = $_[1]) {
        return 'ok';
    } else {
        return "não foi possível definir variável compartilhada $_[0] como $_[1]";
    }
$$ LANGUAGE plperl;

CREATE OR REPLACE FUNCTION get_var(nome text) RETURNS text AS $$
    return $_SHARED{$_[0]};
$$ LANGUAGE plperl;

SELECT set_var('amostra', 'Olá, PL/Perl! Como vão as coisas?');

 set_var
---------
 ok
(1 linha)

SELECT get_var('amostra');

              get_var
-----------------------------------
 Olá, PL/Perl! Como vão as coisas?
(1 linha)

A seguir está um exemplo um pouco mais complicado usando uma referência a código:

CREATE OR REPLACE FUNCTION minhas_funcoes()
  RETURNS void
AS $$
    $_SHARED{meu_escape} = sub {
        my $arg = shift;
        $arg =~ s/(['\\])/\\$1/g;
        return "'$arg'";
    };
$$ LANGUAGE plperl;

SELECT minhas_funcoes(); /* inicializar a função */

/* Definir a função que usa a função de escape */

CREATE OR REPLACE FUNCTION usa_escape(text)
  RETURNS text
AS $$
    my $texto_para_delimitar = shift;
    my $qfunc = $_SHARED{meu_escape};
    return &$qfunc($texto_para_delimitar);
$$ LANGUAGE plperl;

SELECT usa_escape('ae''io\\u');

  usa_escape
---------------
 'ae\'io\\\\u'
(1 linha)

(Poderia ser substituído o corpo da função acima pela linha

return $_SHARED{meu_escape}->($_[0]);

em detrimento da legibilidade.)

Por motivos de segurança, o PL/Perl executa as funções chamadas por qualquer função de banco de dados (identificador de autorização/role), em um interpretador Perl separado para esta função de banco de dados. Isto evita a interferência acidental, ou maliciosa, de um usuário no comportamento das funções PL/Perl de outro usuário. Cada um desses interpretadores tem seu próprio valor da variável %_SHARED, e outro estado global. Assim, duas funções PL/Perl vão compartilhar o mesmo valor de %_SHARED se, e somente se, forem executadas pela mesma função de banco de dados. Em uma aplicação onde, em uma única sessão, é executado código em várias funções de banco de dados do SQL (via funções SECURITY DEFINER, uso de SET ROLE, etc.) pode ser necessário tomar medidas explícitas para garantir que as funções escritas em PL/Perl possam compartilhar dados via %_SHARED. Para fazer isto, deve-se verificar se as funções que devem se comunicar pertencem ao mesmo usuário, e marcá-las com SECURITY DEFINER. É claro que se deve tomar cuidado para que estas funções não possam ser usadas para fazer algo não pretendido.