Как получить более 1000 элементов в HSQLDB в операторе CASE WHEN?

StackOverflow https://stackoverflow.com/questions/437207

  •  22-07-2019
  •  | 
  •  

Вопрос

Я выполняю следующий запрос в гиперзвуковой базе данных (HSQLDB):

SELECT (CASE foo WHEN 'a' THEN 'bar' WHEN 'b' THEN 'biz' ....
        ELSE 'fin' END ) FROM MyTable LIMIT 1

Когда число " КОГДА " предложения превышает около 1000, я получаю Java StackOverflowError , брошенный драйвером JDBC в org.hsqldb.jdbc.Util.sqlException () .

Вот действительно странная часть: я попытался разбить свой оператор CASE на куски, например, 100 КОГДА пункты следуют ELSE (CASE foo WHEN ...) END . Но даже с этим переписыванием я получаю точно такое же поведение!

Я не вижу ссылки на ограничение 1000 или что-либо еще в руководстве по HSQLDB. Помогите!

Это было полезно?

Решение

Вы никогда не должны приближаться к 1000 терминам в выражении CASE . Задолго до этого вы должны поместить другие значения в отдельную таблицу и выбрать их, присоединившись.

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 говорит о StackOverflowError:

  

Брошенный, когда переполнение стека происходит, потому что приложение возвращается слишком глубоко.

Поэтому я бы предположил, что когда HSQLDB анализирует выражение CASE , каждый термин WHEN добавляет еще один слой в стек времени выполнения (на самом деле, вероятно, несколько слоев на WHEN ).

Вероятно, вы бы получили похожее StackOverflowError, если бы у вас было арифметическое выражение с 1000 уровнями вложенных скобок.

Предел 1000, вероятно, является переменной величиной, в зависимости от реализации виртуальной машины Java, версии Java, платформы, на которой вы работаете, объема доступной памяти и т. д. Они могут не документировать это в документации HSQLDB. потому что это предел для конкретной платформы, а не что-то встроенное в HSQLDB.

Другие советы

Исключите оператор CASE полностью.

Создайте таблицу, используя эти 1000 значений, затем просто выполните внутреннее соединение с этой таблицей.

Как сказал Билл, удалить ограничение невозможно, учитывая очевидный дизайн синтаксического анализатора HSQL.

С точки зрения смягчения ограничения (т. е. позволяя себе добраться до 1000 переключателей, просто увеличив предел до ... где-то более 1000), у вас есть два варианта.

<Ол>
  • Увеличьте размер стека в виртуальной машине при запуске приложения. Если вы используете виртуальную машину Sun Hotspot, вы должны пройти, например, -XX: ThreadStackSize = 1024 для использования стека 1 МБ на поток вместо 512 КБ по умолчанию. Это может позволить вам достичь большей глубины рекурсии.
  • Вы можете запустить свою работу в потоке, созданном конструктором Thread (ThreadGroup, Runnable, String, long), где последним параметром является запрошенный размер стека. Это может или не может работать; если вы читаете Javadoc, это предложение - виртуальные машины более чем рады игнорировать этот запрос. Не знаю, что конкретно делает Hotspot, но это может помочь.
  • Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top