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.