我刚刚发现了一个非常奇怪的SQLite行为。我希望我在这里遗漏了一些东西,这不是实施中的错误。
问题在于:
a)如果查询包含计算列,该列将另一个实列作为其输入,AND
b)计算列用于where子句AND
c)真实列被索引
...有时会导致计算列的返回值为NULL,而不是它应该具有的任何值。
以下是重现和说明问题的示例SQL:
CREATE TABLE records (
record_id INTEGER PRIMARY KEY,
record_type INTEGER
);
CREATE INDEX records_record_type_index ON records (record_type);
INSERT INTO records (record_id, record_type) VALUES (101, 0);
INSERT INTO records (record_id, record_type) VALUES (102, 1);
INSERT INTO records (record_id, record_type) VALUES (103, 0);
INSERT INTO records (record_id, record_type) VALUES (104, 1);
INSERT INTO records (record_id, record_type) VALUES (105, 0);
.headers on
-- 1st select
SELECT * FROM records;
-- 2nd select
SELECT record_id, record_type, (record_type * 5) AS zzzA FROM records WHERE ((record_id > 0) OR ((record_type = 2) AND (1 == zzzA)));
-- 3rd select
SELECT record_id, record_type, (record_type * 5) AS zzzB FROM records WHERE ((record_id > 0) OR ((+record_type = 2) AND (1 == zzzB)));
-- 4th select
SELECT record_id, record_type, (record_type * 5) AS zzzA FROM records WHERE ((record_id > 0) OR ((record_type = 2) AND (1 == zzzA)));
DROP INDEX records_record_type_index;
-- 5th select
SELECT record_id, record_type, (record_type * 5) AS zzzC FROM records WHERE ((record_id > 0) OR ((record_type = 2) AND (1 == zzzC)));
CREATE INDEX records_record_type_index ON records (record_type);
-- 6th select
SELECT record_id, record_type, (record_type * 5) AS zzzA FROM records WHERE ((record_id > 0) OR ((record_type = 2) AND (1 == zzzA)));
INSERT INTO records (record_id, record_type) VALUES (106, 2);
-- 7th select
SELECT record_id, record_type, (record_type * 5) AS zzzD FROM records WHERE ((record_id > 0) OR ((record_type = 2) AND (1 == zzzD)));
输出是:
record_id|record_type
101|0
102|1
103|0
104|1
105|0
record_id|record_type|zzzA
101|0|
102|1|
103|0|
104|1|
105|0|
record_id|record_type|zzzB
101|0|0
102|1|5
103|0|0
104|1|5
105|0|0
record_id|record_type|zzzA
101|0|
102|1|
103|0|
104|1|
105|0|
record_id|record_type|zzzC
101|0|0
102|1|5
103|0|0
104|1|5
105|0|0
record_id|record_type|zzzA
101|0|
102|1|
103|0|
104|1|
105|0|
record_id|record_type|zzzD
101|0|10
102|1|10
103|0|10
104|1|10
105|0|10
106|2|10
如您所见,
a)在第二次选择中,计算出的zzzA列值为NULL;
b)如果record_type索引被明确禁止(第三次选择)或掉线(第五次选择),一切都按预期工作;
c)如果我们添加一个记录,其中一个where子句部分正在检查record_type值,那么一切都有效(第7次选择)。
这是在SQLite 3.6.12中发生的。
答案 0 :(得分:0)
(代表OP发布)。
在最新版本的SQLite(3.6.23.1)中看起来已经修复了这个bug。