奇怪的SQLite行为 - 在某些情况下计算列的NULL值

时间:2010-06-09 10:31:14

标签: sqlite

我刚刚发现了一个非常奇怪的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中发生的。

1 个答案:

答案 0 :(得分:0)

(代表OP发布)

在最新版本的SQLite(3.6.23.1)中看起来已经修复了这个bug。