Como obter mais de 1000 itens no HSQLDB no caso de uma instrução?
-
22-07-2019 - |
Pergunta
Estou executando a seguinte consulta em db hipersônico (HSQLDB):
SELECT (CASE foo WHEN 'a' THEN 'bar' WHEN 'b' THEN 'biz' ....
ELSE 'fin' END ) FROM MyTable LIMIT 1
Quando o número de cláusulas "quando" excede cerca de 1000, eu recebo um java StackOverflowError
jogado pelo motorista JDBC em org.hsqldb.jdbc.Util.sqlException()
.
Aqui está a parte realmente estranha: tentei quebrar meu CASE
declaração em pedaços com por exemplo, 100 quando cláusulas seguidas por ELSE ( CASE foo WHEN ... ) END
. Mas mesmo com esta reescrita eu recebo exatamente O mesmo comportamento!
Não vejo nenhuma referência a um limite de 1000 ou qualquer outra coisa no manual do HSQLDB. Ajuda!
Solução
Você nunca deve chegar a um lugar perto de 1000 termos em um CASE
declaração. Muito antes disso, você deve colocar os outros valores em uma tabela separada e escolhê -los juntando -se.
INSERT INTO MappingTable (foo, string) VALUES
('a', 'bar'), ('b', 'biz'), ...
SELECT COALESCE(m.string, 'fin')
FROM MyTable t LEFT OUTER JOIN MappingTable m USING (foo)
LIMIT 1;
Java API diz sobre StackOverflowerRor:
Jogado quando um transbordamento de pilha ocorre porque um aplicativo é reduzido muito profundamente.
Então, eu acho que quando o hsqldb passa um CASE
expressão, cada um WHEN
O termo adiciona outra camada à pilha de tempo de execução (na verdade provavelmente várias camadas por WHEN
).
Você provavelmente obteria um StackOverflowerRor semelhante se tivesse uma expressão aritmética com 1.000 níveis de parênteses aninhados.
O limite de 1.000 é provavelmente variável, dependendo da implementação da VM Java, a versão do Java, a plataforma em que você está executando, a quantidade de memória disponível etc. Eles podem não documentar na documentação do HSQLDB porque é um Limite específico da plataforma, não algo incorporado no HSQLDB.
Outras dicas
Elimine completamente a declaração do caso.
Faça uma tabela usando esses 1000 valores e basta fazer uma união interna para essa tabela.
Como Bill disse, é impossível remover O limite, dado o aparente design do analisador HSQL.
Em termos de aliviar o limite (ou seja, deixando -se chegar a 1000 interruptores apenas pressionando o limite até ... em algum lugar mais de 1000), você tem duas opções.
- Aumente o tamanho da pilha na VM ao executar seu aplicativo. Se você estiver usando o Hotspot VM da Sun, poderá passar por EG -xx: ThreadStackSize = 1024 para usar uma pilha de 1 MB por thread, em vez do 512K padrão. Isso pode permitir que você chegue a uma maior profundidade de recursão.
- Você pode executar seu trabalho em um encadeamento criado pelo Thread do construtor (ThreadGroup, Runnable, String, Long), onde o último parâmetro é um tamanho de pilha solicitado. Isso pode ou não funcionar; Se você ler o Javadoc, é uma sugestão - as VMs são mais do que bem -vindas a ignorar essa solicitação. Não tenho certeza do que o hotspot faz especificamente, mas pode ajudar.