Hello,

The following code

-- beg --
CREATE TEMP TABLE t (pk INTEGER PRIMARY KEY, i);
CREATE TEMP TABLE b (before_pk, i);
CREATE TEMP TABLE a (after_pk, i);

CREATE TEMP TRIGGER tb BEFORE INSERT ON t FOR EACH ROW
BEGIN
  INSERT INTO b VALUES (NEW.pk, NEW.i);
END;

CREATE TEMP TRIGGER ta AFTER INSERT ON t FOR EACH ROW
BEGIN
  INSERT INTO a VALUES (NEW.pk, NEW.i);
END;

INSERT INTO t VALUES (-1, -1);
INSERT INTO t VALUES (0, 0);
INSERT INTO t VALUES (NULL, 1);
INSERT INTO t (i) VALUES (2);

.header on
.mode column
.width -2 -9 -8
SELECT pk, before_pk, after_pk
FROM t NATURAL JOIN b NATURAL JOIN a;
-- end --

with SQLite 3.8.10.2 (also 3.8.9 and possibly earlier) produces

-- beg --
pk  before_pk  after_pk
--  ---------  --------
-1         -1        -1
 0          0         0
 1         -1         1
 2         -1         2
-- end --

As you can see BEFORE INSERT trigger observes -1 in NEW.pk for INTEGER
PRIMARY KEY field when NULL is passed explicitly or implicitly.  Such magic
-1 makes it impossible to distinguish in BEFORE INSERT trigger the NULL (a
command to generate new PK) from explicit -1 (which is a valid value for
integer PK).  I couldn't find a description of this feature in either
https://www.sqlite.org/autoinc.html (section Background),
https://www.sqlite.org/lang_createtable.html#rowid or
https://www.sqlite.org/lang_createtrigger.html , so I consider this a bug
(expect to see NULL in NEW.pk for the last two inserts).

-- 
  Tomash Brechko

Reply via email to