Documentation Source Text

Check-in [23603e03cd]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Update the constraint documentation to clarify that constraints are checked during INSERT and UPDATE but not during query operations. See forum thread 47dae2beebf94254.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 23603e03cdaffd9652d15728f30136c7394eacc89d5756eee20b48825e84b724
User & Date: drh 2021-11-20 13:21:11
Context
2021-11-26
14:04
Update the speed-size spreadsheet. (check-in: 071c9e56ed user: drh tags: trunk)
2021-11-20
13:21
Update the constraint documentation to clarify that constraints are checked during INSERT and UPDATE but not during query operations. See forum thread 47dae2beebf94254. (check-in: 23603e03cd user: drh tags: trunk)
12:38
Updates to the speed-size graph spreadsheet. (check-in: 40702937bb user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to pages/lang_createtable.in.

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  <li><p> A set of SQL constraints for each table. SQLite supports UNIQUE, NOT
       NULL, CHECK and FOREIGN KEY constraints.

  <li><p> Optionally, a [generated column] constraint.

  <li><p> Whether the table is a [WITHOUT ROWID] table.

  <li><p> Whether the table is subject to "STRICT" typename rules.
</ul>

<p>Every CREATE TABLE statement must specify a name for the new table.
  ^(Table names that begin with "sqlite_" are reserved for internal use. It
  is an error to attempt to create a table with a name that starts with
  "sqlite_".)^








|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  <li><p> A set of SQL constraints for each table. SQLite supports UNIQUE, NOT
       NULL, CHECK and FOREIGN KEY constraints.

  <li><p> Optionally, a [generated column] constraint.

  <li><p> Whether the table is a [WITHOUT ROWID] table.

  <li><p> Whether the table is subject to [strict type checking].
</ul>

<p>Every CREATE TABLE statement must specify a name for the new table.
  ^(Table names that begin with "sqlite_" are reserved for internal use. It
  is an error to attempt to create a table with a name that starts with
  "sqlite_".)^

201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
  all other values, including other NULLs. ^If an [INSERT] or [UPDATE]
  statement attempts to modify the table content so that two or more rows
  have identical primary key values, that is a constraint violation.

<p> According to the SQL standard, PRIMARY KEY should always imply NOT NULL.
  Unfortunately, due to a bug in some early versions, this is not the
  case in SQLite. ^Unless the column is an [INTEGER PRIMARY KEY] or
  the table is a [WITHOUT ROWID] table or the column is declared NOT NULL,

  SQLite allows NULL values in a PRIMARY KEY column.  SQLite could be fixed to
  conform to the standard, but doing so might break legacy applications.
  Hence, it has been decided to merely document the fact that SQLite
  allows NULLs in most PRIMARY KEY columns.

<tcl>hd_fragment uniqueconst {UNIQUE} {unique constraint} {UNIQUE constraint} \
           {UNIQUE constraints}</tcl>







|
>







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  all other values, including other NULLs. ^If an [INSERT] or [UPDATE]
  statement attempts to modify the table content so that two or more rows
  have identical primary key values, that is a constraint violation.

<p> According to the SQL standard, PRIMARY KEY should always imply NOT NULL.
  Unfortunately, due to a bug in some early versions, this is not the
  case in SQLite. ^Unless the column is an [INTEGER PRIMARY KEY] or
  the table is a [WITHOUT ROWID] table or a [STRICT] table 
  or the column is declared NOT NULL,
  SQLite allows NULL values in a PRIMARY KEY column.  SQLite could be fixed to
  conform to the standard, but doing so might break legacy applications.
  Hence, it has been decided to merely document the fact that SQLite
  allows NULLs in most PRIMARY KEY columns.

<tcl>hd_fragment uniqueconst {UNIQUE} {unique constraint} {UNIQUE constraint} \
           {UNIQUE constraints}</tcl>
246
247
248
249
250
251
252






253
254
255
256
257
258
259
260
261



262
263























264

265
266
267
268
269
270
271
272
  time a new row is inserted into the table or an existing row is updated,
  the expression associated with each CHECK constraint is evaluated and
  cast to a NUMERIC value in the same way as a [CAST expression]. If the 
  result is zero (integer value 0 or real value 0.0), then a constraint
  violation has occurred.)^ ^If the CHECK expression evaluates to NULL, or
  any other non-zero value, it is not a constraint violation.
  ^The expression of a CHECK constraint may not contain a subquery.







<tcl>hd_fragment {notnullconst} {NOT NULL} {NOT NULL constraint}\
                 {NOT NULL constraints}</tcl>
<h2>NOT NULL constraints</h2>
<p>^A NOT NULL constraint may only be attached to a column definition,
  not specified as a table constraint.  Not surprisingly, ^(a NOT NULL
  constraint dictates that the associated column may not contain a NULL value.
  Attempting to set the column value to NULL when inserting a new row or
  updating an existing one causes a constraint violation.)^




























<h1>Constraint violations</h1>

<p>Exactly how a constraint violation is dealt with is determined by the
  [conflict clause|constraint conflict resolution algorithm]. Each 
  PRIMARY KEY, UNIQUE, NOT NULL and CHECK constraint has a default conflict
  resolution algorithm. ^PRIMARY KEY, UNIQUE and NOT NULL constraints may be
  explicitly assigned a default conflict resolution algorithm by including
  a [conflict-clause] in their definitions. ^Or, if a constraint definition
  does not include a [conflict-clause] or it is a CHECK constraint, the default
  conflict resolution algorithm is ABORT. ^Different constraints within the







>
>
>
>
>
>








|
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|







247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
  time a new row is inserted into the table or an existing row is updated,
  the expression associated with each CHECK constraint is evaluated and
  cast to a NUMERIC value in the same way as a [CAST expression]. If the 
  result is zero (integer value 0 or real value 0.0), then a constraint
  violation has occurred.)^ ^If the CHECK expression evaluates to NULL, or
  any other non-zero value, it is not a constraint violation.
  ^The expression of a CHECK constraint may not contain a subquery.

<p>CHECK constraints are only verified when the table is written, not when
   it is read.  Furthermore, verification of CHECK constraints can be
   temporarily disabled using the "[PRAGMA ignore_check_constraints=ON;]"
   statement.  Hence, it is possible that a query might produce results that
   violate the CHECK constraints.

<tcl>hd_fragment {notnullconst} {NOT NULL} {NOT NULL constraint}\
                 {NOT NULL constraints}</tcl>
<h2>NOT NULL constraints</h2>
<p>^A NOT NULL constraint may only be attached to a column definition,
  not specified as a table constraint.  Not surprisingly, ^(a NOT NULL
  constraint dictates that the associated column may not contain a NULL value.
  Attempting to set the column value to NULL when inserting a new row or
  updating an existing one causes a constraint violation.)^  NOT NULL
  constraints are not verified during queries, so a query of a column might
  produce a NULL value even though the column is marked as NOT NULL, if the
  database file is corrupt.


<h1>Constraint enforcement</h1>

<p>Constraints are checked during [INSERT] and [UPDATE] and by
[PRAGMA integrity_check] and [PRAGMA quick_check] and sometimes
by [ALTER TABLE].  Queries and [DELETE]
statements do not normally verify constraints.
Hence, if a database file has been corrupted (perhaps by an external
program making direct changes to the database file without going through 
the SQLite library) a query might return data that violates a constraint.
For example:

<codeblock>
CREATE TABLE t1(x INT CHECK( x>3 ));
/* Insert a row with X less than 3 by directly writing into the
** database file using an external program */
PRAGMA integrity_check;  -- Reports row with x less than 3 as corrupt
INSERT INTO t1(x) VALUES(2);  -- Fails with SQLITE_CORRUPT
SELECT x FROM t1;  -- Returns an integer less than 3 in spite of the CHECK constraint
</codeblock>

<p>Enforcement of CHECK constraints can be temporarily disabled using
the [PRAGMA ignore_check_constraints=ON;] statement.

<h2>Response to constraint violations</h2>

<p>The response to a constraint violation is determined by the
  [conflict clause|constraint conflict resolution algorithm]. Each 
  PRIMARY KEY, UNIQUE, NOT NULL and CHECK constraint has a default conflict
  resolution algorithm. ^PRIMARY KEY, UNIQUE and NOT NULL constraints may be
  explicitly assigned a default conflict resolution algorithm by including
  a [conflict-clause] in their definitions. ^Or, if a constraint definition
  does not include a [conflict-clause] or it is a CHECK constraint, the default
  conflict resolution algorithm is ABORT. ^Different constraints within the

Changes to pages/stricttables.in.

1
2
3
4
5
6
7
8
9
10
<title>STRICT Tables</title>
<tcl>
hd_keywords {STRICT tables} {STRICT table} {strict type checking}
</tcl>
<fancy_format>

<h1>Introduction</h1>

<p>^SQLite strives to be flexible regarding the datatype of
the content that it stores.  ^For example, if a table column has a type of


|







1
2
3
4
5
6
7
8
9
10
<title>STRICT Tables</title>
<tcl>
hd_keywords {STRICT tables} {STRICT table} {strict type checking} {STRICT}
</tcl>
<fancy_format>

<h1>Introduction</h1>

<p>^SQLite strives to be flexible regarding the datatype of
the content that it stores.  ^For example, if a table column has a type of