SQL dinâmico nas rotinas armazenadas do MySQL

13

De acordo com as restrições nas rotinas e gatilhos armazenados , o sql dinâmico não pode ser usado (restrição levantada para procedimentos armazenados na versão 5.0.13 e posterior). Por que essa limitação existe? E por que levantá-lo para procedimentos, mas não para funções ou gatilhos?

Derek Downey
fonte

Respostas:

8

Apenas ouvir a pergunta me faz pensar em dois aspectos:

ASPECTO Nº 1: As funções devem ser DETERMINÍSTICAS

Nesse caso, isso implica que uma função deve apresentar os mesmos dados de retorno de forma consistente para um determinado conjunto de parâmetros, NÃO IMPORTA QUANDO CHAMAR A FUNÇÃO.

Agora, imagine uma função que produza uma resposta diferente devido à coleta de dados em diferentes horários do dia com base no SQL estático na função. De certa forma, isso ainda pode ser considerado DETERMINÍSTICO se você consultar o mesmo conjunto de tabelas e colunas todas as vezes, considerando o mesmo conjunto de parâmetros.

E se você pudesse alterar as tabelas subjacentes de uma função via Dynamic SQL? Você está violando a definição de uma função DETERMINÍSTICA.

Observe que o MySQL adicionou esta opção no /etc/my.cnf

log-bin-trust-function-creators

Embora possa ser uma simplificação excessiva, isso permite que funções permitam gravar dados em logs binários sem impor rigorosamente a propriedade DETERMINISTIC.

ASPECTO Nº 2: Os gatilhos devem poder ser revertidos

  • Você poderia imaginar um gatilho com os mesmos comportamentos de uma função e, em seguida, introduzir o Dynamic SQL no mix?
  • Você poderia imaginar tentando aplicar o MVCC (Multiversion Concurrecy Control) ao Dynamic SQL após aplicar o MVCC à tabela base para a qual o acionador foi criado?

Você teria essencialmente dados que crescem quadraticamente (mesmo exponencialmente) apenas no MVCC. O processo de gerenciar a reversão do SQL com gatilhos que podem não ser DETERMINÍSTICOS seria incrivelmente complexo, para dizer o mínimo.

À luz desses dois aspectos, tenho certeza que os desenvolvedores do MySQL pensaram nessas coisas e as descartaram rapidamente, impondo restrições.

Então, por que suspender a restrição de procedimentos? Simplificando, não há preocupação com as propriedades DETERMINÍSTICAS ou a reversão.

RolandoMySQLDBA
fonte
3
Não pode ser tão "complexo demais" se outros DBMS puderem suportar muito bem o MVCC e o SQL dinâmico nos gatilhos.
A_horse_with_no_name 24/04
1
Na verdade, @a_horse_with_no_name, você está certo. Para Oracle e PostgreSQL, o complexo ímpio foi codificado. +1 no seu comentário. O MySQL tem a desvantagem de lidar com vários mecanismos de armazenamento, portanto a reversão e o determinismo podem exigir sobreposição das operações do mecanismo de armazenamento. Isso é um pouco assustador. Talvez alguém tenha a coragem de empurrar o "complexo ímpio" para o InnoDB por inteiro. Ainda mais desejável seria criar a implementação de acionador específico do mecanismo de armazenamento, de forma que não permita misturar mecanismos de armazenamento na mesma consulta.
RolandoMySQLDBA
5

Esta é uma ótima pergunta, mas não sei a resposta. Eu imagino que isso vai ter que ir para a equipe interna, mas não sei se eles serão grandes nesse site. Enquanto isso, eu posso ajudá-lo a deduzir algumas respostas.

Para iniciantes, vejo o seguinte:

O cache do acionador não detecta quando os metadados dos objetos subjacentes foram alterados. Se um gatilho usa uma tabela e a tabela mudou desde que o gatilho foi carregado no cache, o gatilho operará usando os metadados desatualizados.

O que me faz pensar que isso tem algo a ver com isso. Não recompilará o SQL se nem estiver monitorando os metadados. O que significa que é uma preocupação do motor.

Da mesma forma, quando li este bloco, penso a mesma coisa (mecanismo):

Para evitar problemas de interação entre os encadeamentos do servidor, quando um cliente emite uma instrução, o servidor usa uma captura instantânea de rotinas e gatilhos disponíveis para execução da instrução. Ou seja, o servidor calcula uma lista de procedimentos, funções e gatilhos que podem ser usados ​​durante a execução da instrução, carrega-os e prossegue para executá-la. Isso significa que, embora a instrução seja executada, ela não verá alterações nas rotinas executadas por outros threads.

Então, apesar de tudo, não sei ao certo por que eles não permitem, mas posso adivinhar. Desculpe por não poder ajudá-lo mais, estou aberto a discutir isso um pouco mais. O melhor é esperar por alguns desenvolvedores ativos do MySQL assim que deixarmos o beta privado;)

jcolebrand
fonte
1

Em grande parte, é devido à segurança. A exceção para os procedimentos é porque o SQL dinâmico dentro do procedimento pode ser atribuído ao contexto de segurança do usuário em execução. Isso significa que, embora o mecanismo não saiba o que será executado, ele pode garantir que o usuário tenha permissão para acessar o (s) objeto (s) referenciado (s).

Além disso, você pode levantar as questões feias do que poderia acontecer, se isso fosse permitido.

dba4life
fonte