Eu tenho uma lista de adjacências composta por duas tabelas:
CREATE TABLE permission (id SMALLINT AUTO_INCREMENT(-32768, 1) PRIMARY KEY);
CREATE TABLE permission_graph (parent_id SMALLINT NOT NULL, child_id SMALLINT NOT NULL,
UNIQUE KEY (parent_id, child_id),
FOREIGN KEY (parent_id) REFERENCES permission(id) ON DELETE CASCADE,
FOREIGN KEY (child_id) REFERENCES permission(id) ON DELETE CASCADE);
Quando executo o seguinte CTE , obtenho um conjunto vazio:
WITH RECURSIVE cte (parent_id, child_id)
AS
(
(
SELECT anchor.parent_id, anchor.child_id
FROM permission_graph anchor
WHERE anchor.child_id = -32763
)
UNION ALL
(
SELECT recursive.parent_id, recursive.child_id
FROM cte, permission_graph recursive
WHERE recursive.child_id = cte.child_id
)
)
SELECT cte.parent_id, cte.child_id
FROM cte
Mas se eu executar a condição de âncora:
SELECT anchor.parent_id, anchor.child_id
FROM permission_graph anchor
WHERE anchor.child_id = -32763
Eu recebo:
[parent_id = -32767, child_id = -32763]
[parent_id = -32768, child_id = -32763]
Por que o CTE está retornando um conjunto vazio quando o resultado da âncora não está vazio? O resultado CTE não deveria conter o resultado âncora?
Eu descobri. (Peço desculpas àqueles que tentaram me ajudar. Não havia como você descobrir isso.)
Depois de muita experimentação, notei que as consultas dinâmicas (
Connection.createStatement()
) retornavam resultados, mas as consultas parametrizadas (Connection.prepareStatement()
) retornavam um conjunto vazio. Você não tinha como saber disso porque minha pergunta listou incorretamente a consulta como:Considerando que, na verdade, era um
PreparedStatement
com um valor de
-32763
.Nas notas de lançamento do H2, encontrei esta frase maravilhosa:
Resumindo, isso parece uma limitação/bug do H2. Eu realmente gostaria que H2 tivesse lançado uma exceção em vez de retornar um conjunto vazio.
https://groups.google.com/d/msg/h2-database/OJfqNF_Iqyo/Z748UP7W3NAJ confirma esse problema (estou obtendo um conjunto vazio em vez de nulo, mas, caso contrário, a descrição do problema é idêntica).
Obrigado a vocês que tentaram ajudar!