Mic*_*ier 22 sqlite android backwards-compatibility android-5.0-lollipop
在测试我的Android 5.0兼容应用程序时,我发现了这一点 一 我的两个SQL查询 不在棒棒糖上不再按预期工作了.与旧的Android版本相比,我的两个问题导致Lollipop的结果显着不同.
下面,我将更深入地描述这些问题及其解决方案,以防您遇到类似问题.
我的主要问题很简单:这些非向后兼容的变更是否记录在案?
似乎以下查询在Lollipop上不再起作用:
SELECT title FROM ents JOIN ctt ON ctt.docid = ents.cttId WHERE (ctt MATCH '*ads*');
Run Code Online (Sandbox Code Playgroud)
它不再返回任何结果,在它之前的Lollipop上(当然使用相同的数据库和相同的数据).
例如,如本问题所述,MATCH仅匹配字符串前缀.事实确实如此,搜索词前面的'*'在Android <5.0时被忽略了.
然而,Lollipop的SQLite不喜欢第一个'*',并且不会为此查询返回任何内容.我不得不将查询更改为以下内容以使其再次起作用:
SELECT title FROM ents JOIN ctt ON ctt.docid = ents.cttId WHERE (ctt MATCH 'ads*');
Run Code Online (Sandbox Code Playgroud)
(我使用FTS3进行全文搜索.)
简短的故事: GROUPing BY由原始名称引用的别名列与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
Run Code Online (Sandbox Code Playgroud)
上面的查询适用于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
Run Code Online (Sandbox Code Playgroud)
(顺便说一下,在这个答案中,您可以找到Android中使用过的SQLite版本的精彩概述)
现在出现了一个有趣的部分:如果在ORDER BY子句中删除了特定于Android的"COLLATE LOCALIZED",一切都会开始工作,即使是"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
Run Code Online (Sandbox Code Playgroud)
我的棒棒糖体验基于使用Android 5.0 - API Level 21 ARM系统映像的SDK模拟器中的测试.
这个secon问题对我来说似乎是特定于Android的SQLite错误.或者有人可以解释我(在我看来)奇怪的行为?或者,这甚至在某处记录了吗?:-)
提前致谢!
我不是一个SQLite专家,我认为你打算这个问题主要是修辞,但请允许我提出一些想法.
正如您已经指出的那样,MATCH 只考虑前缀术语.将前缀(如果愿意)加上星号前缀会产生意外和不可预测的行为,这并不奇怪.
这似乎是一个有趣的错误.但是,您可以尝试使用它EXPLAIN QUERY PLAN来尝试和诊断它.
显然,我没有告诉你任何你不知道的事情.然而,你的"问题"是关于文档的.对于初学者,可以在此处找到SQLite发行说明.它们通常相当详细地说明版本之间的变化.
你的第一个问题是编程错误.关于如何使用FTS前缀的文档已经存在.您不会得到关于为什么您的特定语法停止工作的解释.可以说,它从来都不应该开始.
这个LOCALIZED问题很可能是一个错误因此缺乏"文档"(我鼓励你向Google报告).还要记住,SQLite是Android核心的一部分,它不仅具有自定义(如LOCALIZED),还具有本机Java绑定.基础SQLite核心实现和绑定都可能随每个版本而变化.这让我想到了我的主要观点:
考虑使用私有SQLite实现部署您的应用程序.这样做的指令可以在这里找到.这将使您能够控制应用程序使用的SQLite版本,并为您提供如何以及何时升级它的精确控制.然而,这确实是有代价的,因为你丢失LOCALIZED关键字,例如,绑定只支持API 15或更高,我相信.
| 归档时间: |
|
| 查看次数: |
3664 次 |
| 最近记录: |