Armadilha no LISTEN e NOTIFY (PostgreSQL)

por Walter Cruz on 14/03/2007
in PostgreSQL

Tradução do texto de Greg Sabino Mullane em seu blog. O título original é LISTEN AND NOTIFY gotcha. Resolvi traduzir gotcha como armadilha. Primeiro, a definição de gotcha da wikipedia: Em programação, um gotcha é uma característica de um sistema, um programa, ou uma linguagem de programação que funciona da forma como está documentado mas é contra-intuitivo e quase sempre propícia à erro porque é fácil de usar e impredizível em seu resultado.

Existe um problema sutil com os comandos LISTEN e NOTIFY. Enquanto o nome que você atribui no comando LISTEN parece um texto comum, ele é na verdade aquilo que é chamado de "nome" no PostgreSQL, que significa que está sujeito às mesmas estranhas regras e comportamento. Eu pessoalmente adoraria ver isso mudado de uma nome de relação para uma string normal, mas até que isso ocorra, seja cuidadoso com a forma que você usa essa dupla. Aqui está um exemplo de uso comum:

$ LISTEN employee;
LISTEN

$ NOTIFY employee;
NOTIFY
Asynchronous notification "employee" received from server process with PID 8875.

No exemplo acima, nós começamos a ouvir por evemtos com o nome "employee", então disparamos um NOTIFY com o mesmo nome e obtemos uma notificação imediata sobre isso. Porém, como o nome está sujeito a todas as regras de nomes de relações, existem outros problemas:

$ LISTEN host;
LISTEN

$ LISTEN user;
ERROR:  syntax error at or near "user"
LINE 1: listen user;
               ^

$ LISTEN "user";
LISTEN

$ SELECT * FROM pg_listener;
 relname  | listenerpid | notification 
----------+-------------+--------------
 employee |        8875 |            0
 user     |        8875 |            0
 host     |        8875 |            0
(3 rows)

$ NOTIFY user;
ERROR:  syntax error at or near "user"
LINE 1: listen user;
               ^

$ NOTIFY "user";
NOTIFY
Asynchronous notification "employee" received from server process with PID 8875.

Observe que precisamos colocar a palavra "user" entre aspas, pois a palavra user não é válida como um nome de relação sem aspas. Agora note que a tabela pg_listener não nos dá nenhuma dica que isso precisa estar entre aspas. O problema real acontece quando adicionamos pontos ao nosso "nome". O Postgres trata isso como uma sequência de esquema, tabela, e coluna e remove tudo, exceto a parte final do nome:

$ LISTEN newyork.employee;
LISTEN

$ NOTIFY newyork.emplyee;
NOTIFY
Asynchronous notification "employee" received from server process with PID 8875.

$ NOTIFY losangeles.employee;
NOTIFY
Asynchronous notification "employee" received from server process with PID 8875.

$ NOTIFY elephants.makeagood.employee;
NOTIFY
Asynchronous notification "employee" received from server process with PID 8875.

$ LISTEN thisworks.forunquoted.user;
LISTEN

$ LISTEN cannot.handle.three.dots;                       
ERROR:  improper qualified name (too many dotted names): cannot.handle.three.dots                                           

Eu enviei uma correção para a documentação, mas tome cuidado, principalmente se você escreve código que gera nomes automáticos para os seus argumentos LISTEN.

Endereço de trackback para este post

Trackback URL (clique direito e copie atalho/localização do link)

2 comentários


Notice: Undefined index: comment_secret in /home/walter/repositories/whissip-dev/blogs/inc/comments/model/_comment.class.php on line 161
  1. Mande um link da documentação ! :)

    Eu não sei o que são esses comandos e gostaria de lê-la para saber. ;)

    Até mais.

  2. Walter Cruz (Member) Email says :

    De fato, faltaram os links!Lá vão:

    1. LISTEN
    2. NOTIFY

Share Your Thoughts


Seu endereço de e-mail não será revelado nesse site.

Sua URL será exibida.
PobreExcelente
(Quebras de linha se tornam <br />)
(Nome, e-mail & website)
(Permitir que usuários o contatem através de um formulário eletrônico (seu e-mail não será exibido.))
Subscribe to comments by email

You can just use your OpenID to provide your name, e-mail and url.