Android Lollipop - verändertes Verhalten von SQLite
Wenn ich eine meiner Apps auf Android 5.0-Kompatibilität teste, habe ich festgestellt, dasseine zwei meiner SQL-Abfragen does funktioniert bei Lollipop nicht mehr wie erwartet. Beide meiner Probleme führten auf Lollipop zu signifikant unterschiedlichen Ergebnissen im Vergleich zu älteren Android-Versionen.
Below, ich werde diese Probleme und ihre Lösungen genauer beschreiben, falls Sie ähnliche Probleme haben.
Meine Hauptfrage ist ganz einfach: Sind diese nicht abwärtskompatiblen Änderungen irgendwo dokumentiert?
Problem Nummer eins: MATCHEs scheint, dass die folgende Abfrage auf Lollipop nicht mehr funktioniert:
SELECT title FROM ents JOIN ctt ON ctt.docid = ents.cttId WHERE (ctt MATCH '*ads*');
Es werden keine Ergebnisse mehr zurückgegeben, dies war vor Lollipop der Fall (natürlich mit derselben Datenbank und denselben Daten).
Wie in @ beschriebdiese Frag MATCH stimmt beispielsweise nur mit Zeichenfolgepräfixen überein. Das ist tatsächlich wahr, das '*' vor dem Suchbegriff wurde bei Android <5.0 einfach ignoriert.
Lollipops SQLite mag jedoch das erste '*' nicht und gibt für diese Abfrage nichts zurück. Ich musste die Abfrage folgendermaßen ändern, damit sie wieder funktioniert:
SELECT title FROM ents JOIN ctt ON ctt.docid = ents.cttId WHERE (ctt MATCH 'ads*');
(Ich verwende FTS3 für die Volltextsuche.)
Problem Nummer zwei: COLLATE LOCALIZEDKurzgeschichte GROUPing BY Eine mit Alias versehene Spalte, auf die der ursprüngliche Name in Verbindung mit einem ORDER BY mit dem Android-spezifischen Befehl "COLLATE LOCALIZED" verweist, löst einen Fehler bei Lollipop aus, funktioniert jedoch bei früheren Versionen. WTF !? : -)
Lange Geschichte
Die Geschichte begann mit einer ziemlich großen automatisch generierten Abfrage, daher habe ich sie geändert, vereinfacht und auf die Teile gekürzt, die die Probleme verursachen. Ich bin mir der Tatsache bewusst, dass die Abfrage, wie unten gezeigt, nicht viel Sinn macht, aber das Problem demonstriert.
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
Die obige Abfrage funktioniert auf Andriod <5.0, führt jedoch zu einem Fehler in Lollipop:
Error: no such column: inner.title
OK, ich habe "inner.title" mit "title" aliasiert, also habe ich versucht, "GROUP BY inner.title" in "GROUP BY title" zu ändern, was wirklich die Lösung für Lollipops SQLite ist:
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
(übrigens indiese Antwort finden Sie eine gute Übersicht über die verwendeten SQLite-Versionen in Android)
Nun kommt der interessante Teil: Wenn das Android-spezifische "COLLATE LOCALIZED" in der ORDER BY-Klausel entfernt wird, funktioniert auch mit "GROUP BY inner.title" alles:
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
Meine Lollipop-Erfahrungen basieren auf Tests im SDK-Emulator unter Verwendung des ARM-Systemabbilds für Android 5.0 - API Level 21.
Dieses zweite Problem scheint mir ein Android-spezifischer SQLite-Fehler zu sein. Oder kann mir jemand dieses (für meine Augen) seltsame Verhalten erklären? Oder ist das überhaupt irgendwo dokumentiert? : -)
Danke im Voraus