AE
By A. Elein Mustain
Traduzidos por Juliano da Silva Ignacio
General Bits 30-Jun-2003 Edição: 32

 
General Bits é uma coluna baseada na lista de discussão do PostgreSQL pgsql-general.
Para saber mais sobre a lista de discussão pgsql-general e sobre o PostgreSQL, procure em http://www.postgresql.org/.
Arquivos
General Tidbits
Artigos Português
Google General Bits
Notícias
Para receber um aviso via email sobre as novas edições do General Bits, envie um email para Elein.
ae Consulting PostgreSQL Support, Design & Implementation
Assinaturas Support General Bits
pghoster.com
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Correção da função fixdupes()
Identificando e Removendo Registros Duplicados 13/Jun/2003

Houve um erro de edição na Edição 30 no artigo sobre "encontrando e corrigindo registros duplicados". (Porque ninguém encontrou este erro e me notificou?)

A função fixdupes() tinha uma lista de destino (target list) incorreta para a seleção de dentro da função. A função fixdupes() corrigida e completa é:

   create or replace function fixdupes()
   returns void as '
      DECLARE
         d record;
      BEGIN
         for d in select * 
               from rawlog 
               group by ldate, ltime, doc, ip, method, qs, code, dsize
               having count(*) > 1 limit 1
         loop
               delete from rawlog  
               where ldate=d.ldate and ltime=d.ltime and 
               doc=d.doc and ip=d.ip and method=d.method and
               qs=d.qs and code=d.code and dsize=d.dsize;

               insert into rawlog values (d.ip, d.ldate, d.ltime,
               d.method, d.doc, d.qs, d.code, d.dsize);
         end loop;
      RETURN;
   END;
   ' language 'plpgsql';

Colaboradores: elein em varlena.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Linguagens Confiáveis e Não Confiáveis
[GENERAL] PlPython (Foi: plpython? (Foi: Re: Malditos gatilhos e NEW)) 18/Jun/2003

O PostgreSQL suporta linguagens confiáveis e não confiáveis para funções que rodam no servidor. Como regra geral (exceto para C) linguagens não confiáveis contém o sufixo u em seu nome. Por exemplo, plperl é confiável, mas plperlu é não confiável.

Uma função escrita em uma linguagem confiável, ou seja, uma função confiável, é segura para uso genérico. Uma função escrita em uma linguagem não confiável, ou seja, uma função não confiável, pode ser escrita para ser segura, mas a possibilidade para abusos sempre existe.

Tom Laine escreve, "[uma] linguagem PL-confiável deve ser capaz de definir o arbítrio de processos computacionais reservados (aritmética, padrões, entre outros), e deve ser capaz de acessar o banco de dados no mesmo nível que comandos SQL regulares. Ela não deve ser capaz de se desviar das abstrações do SQL, nem executar quaisquer operações do nível do Sistema Operacional (SO) usando os direitos do usuário postgres." Linguagens confiáveis limitam suas funcionalidades explicitamente via permissões e por interpretadores de linguagens para previnir invocar funcionalidades "perigosas".

Então, uma linguagem não confiável não é, como alguns pensam, defeituosa ou uma má implementação da linguagem, mas preferivelmente, uma que permite expandir funcionalidades a serem realizadas em uma função que roda no servidor sob as permissões do superusuário postgres.

Estas funcionalidades "expandidas" ou "perigosas" são largamente definidas como qualquer coisa que é executada fora do banco de dados, sobre o entendimento que, qualquer coisa que é executada fora do banco de dados poderia ser explorada para causar danos. Sistemas de E/S de arquivos, chamadas específicas do SO, gerenciamento de memória, criação de processos e comunicação interprocessos são algumas das coisas que são classificadas como perigosas.

Linguagens não confiáveis devem ser explicitamente instaladas pelo superusuário do banco de dados e, permissão para criar funções e gatilhos (triggers) usando linguagens não confiáveis é limitada à usuários com direitos de superusuário. A responsabilidade da boa cidadania é colocada sobre o(s) superusuário(s).

Depois de entender todos os avisos, funções não confiáveis podem ser extremamente importantes para uma aplicação. Há muitos casos autênticos e de grande valor onde linguagens e operações não confiáveis são extremamente úteis, por exemplo, enviando mensagens de correio eletrônico (email), leitura e escrita segura do sistema de arquivo e chamadas de informações do SO. Também é possível escrever uma função em uma linguagem não confiável que não faça uso de qualquer característica não confiável, por exemplo, a maioria das funções em C disponíveis no diretório contrib se encontram nesta categoria.

Não Confiável não significa que a linguagem não deve ser usada. Significa que deve ser usada com precaução. Uma linguagem não confiável pode ser usada beneficamente por alguém que entende exatamente as repercussões de seu código.

Colaboradores: scott.marlowe scott.marlowe em ihs.com, Karsten Hilbert Karsten.Hilbert em gmx.net, Mikhail Terekhov terekhov em emc.com, Tom Lane tgl em sss.pgh.pa.us, DeJuan Jackson djackson em speedfc.com, Kevin Jacobs jacobs em penguin.theopalgroup.com, Doug McNaught doug em mcnaught.org, elein em varlena.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Plpython muda para uma Linguagem Não Confiável
[GENERAL] PlPython (Foi: plpython? (Foi: Re: Malditos gatilhos e NEW)) 18/Jun/2003

Na versão 7.4, o plpython será movido de uma linguagem confiável para uma linguagem não confiável e seu nome será alterado para plpythonu. A mudança do nome enfatiza que a linguagem é agora não confiável. (Veja o artigo acima nesta edição para uma explanação sobre linguagens confiáveis e não confiáveis.)

Guido Van Rossum, do time de desenvolvimento do Python, determinou que o rexec (execução restrita) se tornou fundamentalmente inseguro no python e então será removido da linguagen como a versão 2.3.

A mais recente versão do plpython habilita um limitado conjunto de chamadas do python via rexec. Com o novo entendimento das fragilidades do rexec, o plpython ficou então desprotegido, não possuindo um embiente seguro, de execução restrita e foi também incompatível com o python 2.3.

Kevin Jacobs cedeu uma correção para o plpython removendo as referências ao rexec e marcando a linguagem como não confiável. A correção foi aplicada à parte do desenvolvimento destinada à versão 7.4.

Pessoas usando plpython provavelmente irão precisar recarregar suas funções com a linguagem mudada para plpythonu na versão 7.4. Verifique as notas e observações para o manuseio apropriado quando a versão 7.4 for liberada. Mais uma coisa, somente as pessoas com direitos de superusuário serão capazes de definir funções usando plpythonu.

Colaboradores: Kevin Jacobs jacobs em penguin.theopalgroup.com, Bruce Momjian pgman em candle.pha.pa.us, Tom Lane tgl em sss.pgh.pa.us, Mikhail Terekhov terekhov em emc.com, Karsten Hilbert Karsten.Hilbert em gmx.net, elein em varlena.com, scott.marlowe scott.marlowe em ihs.com, Doug McNaught doug em mcnaught.org, Ron Johnson ron.l.johnson em cox.net, Jason Earl jason.earl em simplot.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Tipos de Registro (Rowtypes) mantém colunas removidas
[GENERAL] plpgsql, tipos de registro e colunas removidas 11/Jun/2003

Tipos de Registro (ROWTYPEs) de tabelas com colunas removidas podem ser frustrantes e confusas. Se você declara uma variável para ser do tipo de registro da sua tabela e, selecionar registros para serem inseridos nela, o conjunto da seleção e o tipo do registro de destino serão diferentes porque o tipo de registro destino ainda irá conter quaisquer colunas removidas.

Um tipo de registro com colunas removidas pode ser visualizado usando \d e as colunas removidas não serão mostradas. No entanto, selecionando os dados à partir da tabela pg_attribute você pode ver onde as colunas removidas se encontram. Isto se pareceria com isso:

 attnum |           attname            |  typname  |      case      
--------+------------------------------+-----------+----------------
     -7 | tableoid                     | oid       | '-7'::oid
     -6 | cmax                         | cid       | '-6'::cid
     -5 | xmax                         | xid       | '-5'::xid
     -4 | cmin                         | cid       | '-4'::cid
     -3 | xmin                         | xid       | '-3'::xid
     -2 | oid                          | oid       | '-2'::oid
     -1 | ctid                         | tid       | '-1'::tid
      1 | col_int                      | int4      | '1'::int4
      2 | col_timestamp                | timestamp | '2'::timestamp
      3 | col_float                    | float8    | '3'::float8
      4 | col_text                     | text      | '4'::text
      5 | ........pg.dropped.5........ | text      | 
      6 | mod_timestamp                | timestamp | '6'::timestamp
(13 rows)

Uma função como esta não irá funcionar como esperado. O * irá selecionar os atributos 1, 2, 3, 4 e 6. No entanto, o tipo de registro (rowtype) terá os atributos 1, 2, 3, 4, 5 e 6, causando um erro de tipo (mismatch) para os tipos retornados.

   CREATE OR REPLACE FUNCTION testrows ( integer )
      RETURNS foo
      AS '
      DECLARE
         myrec   foo%ROWTYPE;
      BEGIN

         SELECT INTO myrec *
         FROM foo 
         WHERE foo.col_int = $1;

         RETURN myrec;
      END;
   '
   LANGUAGE 'plpgsql';

   select * from do_testrows(2);
   WARNING:  Error occurred while executing PL/pgSQL function testrows
   WARNING:  line 5 at select into variables
   ERROR:  Bad timestamp external representation '2.3'

Se você não recebeu um erro de tipo errado para os tipos retornados, você irá receber o seguinte erro:
ERROR:  Function bartest() does not exist
        Unable to identify a function that satisfies the given argument types
        You may need to add explicit typecasts

Este comportamento é um problema conhecido. Uma maneira de contornar este problema é usar um tipo RECORD ao invés de um tipo ROWTYPE ou a possibilidade de designar sua lista de destino explicitamente, incluindo valores para as colunas "faltantes", ou definir um tipo de registro (ROWTYPE) que combine com sua tabela alterada usando-a ao invés do ROWTYPE da própria tabela.

A correção para este problema irá requerer mudanças em todos os lugares do código onde os tipos de registro (rowtypes) são acessados. São muitos lugares. Ninguém determinou ainda uma maneira de corrigir o problema com uma alteração universal.

Entretanto, tenha cuidado quando usar ROWTYPES com tabelas alteradas.

Colaboradores: Nigel J. Andrews nandrews em investsystems.co.uk Tom Lane tgl em sss.pgh.pa.us

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Removendo funções plpgsql usadas em índices
[GENERAL] Curiosa mensagem de erro 16/Jun/2003

Funções plpgsql criam dependências entre objetos que se utilizam de suas consultas. Objetos incluem índices, outras funções, tabelas e visões (views).

Quando uma função em plpgsql é executada pela primeira vez, um plano é criado e armazenado para as consultas descritas na função. Isto habilita o plpgsql a ser muito rápido.

Se o plano possui objetos dependentes, a função não irá executar. Você deve achar que removendo um índice não deveria afetar a função, no entanto, afeta a consulta armazenada que o plano criou.

Se uma consulta em uma função plpgsql armazena um plano que usa um índice e este índice é removido, então, a execução da função irá causar um erro sobre a falta de uma relação:

	ERROR:  Relation 3912941 does not exist

Removendo e recriando a função irá reparar o problema. O plano é removido quando a função é removida e, um novo plano é salvo quando a função é executada novamente.

Colaboradores: nolan em celery.tssi.com, Richard Huxton dev em archonet.com


Comentários e Correções são bem vindos. Sugestões e contribuições de itens também são bem vindos. Envie-os!.
Copyright A. Elein Mustain 2003
Traduzidos por Juliano da Silva Ignacio

Google
Search General Bits & varlena.com Search WWW