Armadilha no LISTEN e NOTIFY (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.

This entry was posted in PostgreSQL and tagged , , , . Bookmark the permalink.

2 Responses to Armadilha no LISTEN e NOTIFY (PostgreSQL)

  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. De fato, faltaram os links!Lá vão:

    LISTEN
    NOTIFY

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>