SQLite

View Ticket
Login
Ticket Hash: 16c9801ceba4923939085fcd5275b536f3d26534
Title: Segfault on DELETE with WHERE containing OR
Status: Fixed Type: Code_Defect
Severity: Severe Priority: Immediate
Subsystem: Unknown Resolution: Fixed
Last Modified: 2016-05-06 16:49:58
Version Found In: 3.12.2
User Comments:
drh added on 2016-05-06 03:26:38:

The following causes an assertion fault, or segfaults if asserts are disabled. The problem occurs on the DELETE statement.

CREATE TABLE t1(x INTEGER PRIMARY KEY, y TEXT);
INSERT INTO t1(x,y) VALUES(1,'zebra');
CREATE INDEX t1x ON t1(x);
DELETE FROM t1 WHERE x IS NULL OR x<2;

This problem was introduced in version 3.12.0 by check-in [96ea990942]. A simple work-around is to drop the redundant "t1x" index. As far as I can tell, this problem only comes up when there is an index on the INTEGER PRIMARY KEY, as illustrated by t1x above.


drh added on 2016-05-06 03:56:34:

Another problem is that the SELECT statement below does a full table scan:

CREATE TABLE t2(x INTEGER PRIMARY KEY, y TEXT);
SELECT * FROM t2 WHERE x IS NULL;

If this optimization is fixed, the situation that causes the bug in this ticket would never come up, as far as I can tell.


drh added on 2016-05-06 14:33:25:

Another crashing example that does not use the degenerate index:

CREATE TABLE t1(x INTEGER PRIMARY KEY, y TEXT);
INSERT INTO t1(x,y) VALUES(1,'zebra');
CREATE INDEX t1x ON t1(abs(x));
DELETE FROM t1 WHERE abs(x)=99 OR abs(x)<2;

These seem to be the requirements to cause the crash:

  1. A rowid table with an integer primary key
  2. No indexes reference any columns of the table other than the primary key
  3. DELETE with an OR in the WHERE clause

The OR clause uses the OP_Seek opcode to do a deferred seek of the main table. That deferred seek is resolved at the first OP_Column. But if none of the indexes ever reference a column (because they all only reference the integer primary key) then the seek does not occur prior to the OP_Delete.