При тестировании одного из моих приложений для совместимости с Android 5.0 я обнаружил, что one два моих SQL-запроса не работают больше не работают на Lollipop. Обе мои проблемы привели к значительно большим результатам на Lollipop по сравнению со старыми версиями Android.
Ниже я расскажу о тех проблемах и их решениях более глубоко, если у вас возникнут аналогичные проблемы.
Мой главный вопрос довольно прост: не документированы ли какие-либо несоответствующие изменения?
Проблема номер один: MATCH
Кажется, что следующий запрос больше не работает на Lollipop:
SELECT title FROM ents JOIN ctt ON ctt.docid = ents.cttId WHERE (ctt MATCH '*ads*');
Он больше не возвращает никаких результатов, на pre-Lollipop (с той же базой данных и теми же данными, конечно).
Как описано в этом вопросе, например, MATCH соответствует только строковым префиксам. Это действительно так, "*" перед поисковым термином просто игнорировался на Android < 5.0.
Lollipop SQLite, однако, не нравится первый '*' и ничего не возвращает для этого запроса. Мне пришлось изменить запрос на следующий, чтобы он снова работал:
SELECT title FROM ents JOIN ctt ON ctt.docid = ents.cttId WHERE (ctt MATCH 'ads*');
(Я использую FTS3 для полнотекстового поиска.)
Проблема номер два: COLLATE LOCALIZED
Краткая история: GROUPING В столбце с псевдонимом, на который ссылается исходное имя в сочетании с ORDER BY, с использованием специфичного для Android "COLLATE LOCALIZED", выдает ошибку на Lollipop, но работает в предыдущих версиях. WTF!?: -)
Длинная история:
История началась с довольно большого автоматически сгенерированного запроса, поэтому я модифицировал, упрощал и сокращал его до тех частей, которые вызывают проблемы. Я знаю, что запрос не имеет особого смысла, как показано ниже, но он демонстрирует проблему.
SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT types.text AS title FROM types) AS inner
GROUP BY inner.title
UNION SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT types.text AS title FROM types) AS inner
GROUP BY inner.title
ORDER BY title2 COLLATE LOCALIZED ASC
Запрос выше работает на Andriod < 5.0, но приводит к ошибке в Lollipop:
Error: no such column: inner.title
ОК, я сгладил "inner.title" с "title", поэтому я попытался изменить "GROUP BY inner.title" на "GROUP BY title", который действительно является решением для Lollipop SQLite:
SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT types.text AS title FROM types) AS inner
GROUP BY title
UNION SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT types.text AS title FROM types) AS inner
GROUP BY title
ORDER BY title2 COLLATE LOCALIZED ASC
(btw, этот ответ, вы можете найти отличный обзор используемых версий SQLite в Android)
Теперь идет интересная часть: Если конкретный Android "COLLATE LOCALIZED" удаляется в предложении ORDER BY, все начинает работать, даже с "GROUP BY inner.title":
SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT indsntyps.text AS title FROM indsntyps) AS inner
GROUP BY inner.title
UNION SELECT
inner.title AS title,
ltrim(inner.title, '*') AS title2
FROM
(SELECT indsntyps.text AS title FROM indsntyps) AS inner
GROUP BY inner.title
ORDER BY title2 ASC
Мой опыт Lollipop основан на тестах в эмуляторе SDK с использованием образа системы ARM Android 5.0 - API уровня 21.
Эта проблема secon выглядит как ошибка SQLite, специфичная для Android. Или может кто-нибудь объяснить мне это (на мой взгляд) странное поведение? Или, опять же, это даже где-то документировано?: -)
Спасибо заранее!