Ticket Hash: | 830277d9db6c3ba10df1c79c6c2be58323553240 | ||
Title: | Non-deterministic date/time functions allowed in CHECK constraints | ||
Status: | Closed | Type: | Code_Defect |
Severity: | Critical | Priority: | Low |
Subsystem: | Unknown | Resolution: | Not_A_Bug |
Last Modified: |
2020-01-18 21:35:33 5.29 years ago |
Created: |
2019-10-30 02:09:39 5.51 years ago |
Version Found In: |
User Comments: | ||||
drh added on 2019-10-30 02:09:39:
The functions found in CHECK constraints should be deterministic - meaning that they should aways give the same answer for the same inputs. Date and time functions can sometimes be deterministic and sometimes now. They are deterministic if they avoid arguments like 'now' and 'localtime'. The functions are coded in such a way that if those arguments are used in a context where a deterministic function is required, then the function throws an error at run-time. But this mechanism sometimes does not work. Example: CREATE TABLE t1(a REAL CHECK( a<julianday('now') )); INSERT INTO t1(a) VALUES(julianday('now')-0.01); -- works INSERT INTO t1(a) VALUES(julianday('now')+0.01); -- error Because of the use of "julianday('now')" inside of a CHECK constraint, *every* insert into table t1 ought to fail. But sometimes the inserts run to completion without error. drh added on 2019-10-30 10:33:09: This same problem can lead to index corruption: CREATE TABLE t1(a,b); CREATE INDEX t1x1 ON t1(julianday('now')+b); INSERT INTO t1(a,b) VALUES(12345, 15); .shell sleep 1 SELECT a FROM t1 WHERE julianday('now')+b=julianday('now')+15; -- previous query returns zero row, but should return one row of 12345 PRAGMA integrity_check; -- reports missing index entry drh added on 2020-01-18 21:35:33: It turns out that PostgreSQL, MySQL, and SQLServer all allow non-deterministic functions like CURRENT_TIMESTAMP and RANDOM() inside of CHECK constraints. So, SQLite will too. |