Para criar uma função na linguagem PL/Tcl, deve ser usada a sintaxe padrão do comando CREATE FUNCTION:
CREATE FUNCTIONnome_da_função(tipos_de_dados_dos_argumentos) RETURNStipo_de_dados_retornadoAS $$ # PL/Tcl corpo da função $$ LANGUAGE pltcl;
PL/TclU é idêntico, exceto que a linguagem deve
ser especificada como pltclu.
O corpo da função é simplesmente um trecho de script
Tcl.
Quando a função é chamada, os valores dos argumentos são passados
para o script Tcl como variáveis com nomes de
$1 ... .
O resultado é retornado do código Tcl da maneira
usual, com uma instrução $nreturn.
Num procedimento, o valor retornado pelo código
Tcl é ignorado.
Por exemplo, uma função que retorna o maior de dois valores inteiros poderia ser definida como:
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
if {$1 > $2} {return $1}
return $2
$$ LANGUAGE pltcl STRICT;
Note a cláusula STRICT, que evita ter que se
lidar com os valores de entrada nulos: se for passado um valor nulo,
a função não será chamada, apenas retornará um resultado nulo
automaticamente.
Em uma função não estrita, se o valor de um argumento for nulo,
a variável $
correspondente será definida como uma cadeia de caracteres vazia.
Para detectar se um determinado argumento é nulo, deve ser usada
a função nargisnull.
Por exemplo, supondo que fosse desejado que a função
tcl_max recebendo um argumento nulo e um
argumento não-nulo retorne o argumento não-nulo, em vez de nulo:
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
if {[argisnull 1]} {
if {[argisnull 2]} { return_null }
return $2
}
if {[argisnull 2]} { return $1 }
if {$1 > $2} {return $1}
return $2
$$ LANGUAGE pltcl;
Como mostrado acima, para retornar um valor nulo de uma função
PL/Tcl deve-se executar
return_null.
Isto pode ser feito independentemente da função ser estrita ou não.
Argumentos com tipo de dados composto são passados para a função como matrizes Tcl. Os nomes dos elementos da matriz são os nomes dos atributos do tipo de dados composto. Se um atributo na linha passada tiver valor nulo, ele não irá aparecer na matriz. A seguir está um exemplo:
CREATE TABLE funcionario (
nome text,
salario integer,
idade integer
);
CREATE FUNCTION sobrepago(funcionario) RETURNS boolean AS $$
if {200000.0 < $1(salario)} {
return "t"
}
if {$1(idade) < 30 && 100000.0 < $1(salario)} {
return "t"
}
return "f"
$$ LANGUAGE pltcl;
-- Exemplo do tradutor
SELECT F.nome, F.salario, F.idade, sobrepago(F) FROM funcionario F;
nome | salario | idade | sobrepago -------+---------+-------+----------- Maria | 100000 | 50 | f João | 300000 | 60 | t José | 110000 | 20 | t (3 linhas)
As funções PL/Tcl também podem retornar resultados do tipo de dados composto. Para fazer isto, o código Tcl deve retornar uma lista de pares nome/valor de coluna que correspondam ao tipo de dados do resultado esperado. Quaisquer nomes de colunas omitidos da lista serão retornados como nulos, e será gerado um erro se houver nomes de colunas inesperados. A seguir está um exemplo:
CREATE FUNCTION quadrado_cubo(in int, out quadrado int, out cubo int) AS $$
return [list quadrado [expr {$1 * $1}] cubo [expr {$1 * $1 * $1}]]
$$ LANGUAGE pltcl;
-- Exemplo do tradutor
SELECT quadrado_cubo(3);
quadrado_cubo --------------- (9,27) (1 linha)
Os argumentos de saída dos procedimentos são retornados da mesma maneira. Por exemplo:
CREATE PROCEDURE tcl_triplo(INOUT a integer, INOUT b integer) AS $$
return [list a [expr {$1 * 3}] b [expr {$2 * 3}]]
$$ LANGUAGE pltcl;
CALL tcl_triplo(5, 10);
a | b ----+---- 15 | 30 (1 linha)
A lista de resultados pode ser feita a partir de uma representação
matricial da tupla desejada com o comando array get
do Tcl. Por exemplo:
CREATE FUNCTION aumenta_salario(funcionario, delta int) RETURNS funcionario AS $$
set 1(salario) [expr {$1(salario) + $2}]
return [array get 1]
$$ LANGUAGE pltcl;
-- Exemplo do tradutor
SELECT aumenta_salario(funcionario::funcionario,1000) FROM funcionario;
-- ou
SELECT aumenta_salario(funcionario.*,1000) FROM funcionario;
aumenta_salario ------------------- (Maria,101000,50) (João,301000,60) (José,111000,20) (3 linhas)
As funções PL/Tcl podem retornar conjuntos.
Para fazer isto, o código Tcl deve chamar
return_next uma vez para cada linha a ser
retornada, passando o valor apropriado ao retornar um tipo escalar,
ou uma lista de pares nome/valor de coluna ao retornar um
tipo de dados composto.
A seguir está um exemplo retornando um tipo de dados escalar:
CREATE FUNCTION sequencia(int, int) RETURNS SETOF int AS $$
for {set i $1} {$i < $2} {incr i} {
return_next $i
}
$$ LANGUAGE pltcl;
SELECT sequencia(1,3);
sequencia
-----------
1
2
(2 linhas)
e a seguir está um exemplo retornando um tipo de dados composto:
CREATE FUNCTION tabela_de_quadrados(int, int) RETURNS TABLE (x int, x2 int) AS $$
for {set i $1} {$i < $2} {incr i} {
return_next [list x $i x2 [expr {$i * $i}]]
}
$$ LANGUAGE pltcl;
SELECT tabela_de_quadrados(3,6);
tabela_de_quadrados --------------------- (3,9) (4,16) (5,25) (3 linhas)
Veja também Validação do CPF em PL/Tcl . (N.T.)