xref: /sqlite-3.40.0/test/autoinc.test (revision dddca286)
1# 2004 November 12
2#
3# The author disclaims copyright to this source code.  In place of
4# a legal notice, here is a blessing:
5#
6#    May you do good and not evil.
7#    May you find forgiveness for yourself and forgive others.
8#    May you share freely, never taking more than you give.
9#
10#*************************************************************************
11# This file implements regression tests for SQLite library.  The
12# focus of this script is testing the AUTOINCREMENT features.
13#
14# $Id: autoinc.test,v 1.9 2006/01/03 00:33:50 drh Exp $
15#
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
20# If the library is not compiled with autoincrement support then
21# skip all tests in this file.
22#
23ifcapable {!autoinc} {
24  finish_test
25  return
26}
27
28# The database is initially empty.
29#
30do_test autoinc-1.1 {
31  execsql {
32    SELECT name FROM sqlite_master WHERE type='table';
33  }
34} {}
35
36# Add a table with the AUTOINCREMENT feature.  Verify that the
37# SQLITE_SEQUENCE table gets created.
38#
39do_test autoinc-1.2 {
40  execsql {
41    CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
42    SELECT name FROM sqlite_master WHERE type='table';
43  }
44} {t1 sqlite_sequence}
45
46# The SQLITE_SEQUENCE table is initially empty
47#
48do_test autoinc-1.3 {
49  execsql {
50    SELECT * FROM sqlite_sequence;
51  }
52} {}
53
54# Close and reopen the database.  Verify that everything is still there.
55#
56do_test autoinc-1.4 {
57  db close
58  sqlite3 db test.db
59  execsql {
60    SELECT * FROM sqlite_sequence;
61  }
62} {}
63
64# We are not allowed to drop the sqlite_sequence table.
65#
66do_test autoinc-1.5 {
67  catchsql {DROP TABLE sqlite_sequence}
68} {1 {table sqlite_sequence may not be dropped}}
69do_test autoinc-1.6 {
70  execsql {SELECT name FROM sqlite_master WHERE type='table'}
71} {t1 sqlite_sequence}
72
73# Insert an entries into the t1 table and make sure the largest key
74# is always recorded in the sqlite_sequence table.
75#
76do_test autoinc-2.1 {
77  execsql {
78    SELECT * FROM sqlite_sequence
79  }
80} {}
81do_test autoinc-2.2 {
82  execsql {
83    INSERT INTO t1 VALUES(12,34);
84    SELECT * FROM sqlite_sequence;
85  }
86} {t1 12}
87do_test autoinc-2.3 {
88  execsql {
89    INSERT INTO t1 VALUES(1,23);
90    SELECT * FROM sqlite_sequence;
91  }
92} {t1 12}
93do_test autoinc-2.4 {
94  execsql {
95    INSERT INTO t1 VALUES(123,456);
96    SELECT * FROM sqlite_sequence;
97  }
98} {t1 123}
99do_test autoinc-2.5 {
100  execsql {
101    INSERT INTO t1 VALUES(NULL,567);
102    SELECT * FROM sqlite_sequence;
103  }
104} {t1 124}
105do_test autoinc-2.6 {
106  execsql {
107    DELETE FROM t1 WHERE y=567;
108    SELECT * FROM sqlite_sequence;
109  }
110} {t1 124}
111do_test autoinc-2.7 {
112  execsql {
113    INSERT INTO t1 VALUES(NULL,567);
114    SELECT * FROM sqlite_sequence;
115  }
116} {t1 125}
117do_test autoinc-2.8 {
118  execsql {
119    DELETE FROM t1;
120    SELECT * FROM sqlite_sequence;
121  }
122} {t1 125}
123do_test autoinc-2.9 {
124  execsql {
125    INSERT INTO t1 VALUES(12,34);
126    SELECT * FROM sqlite_sequence;
127  }
128} {t1 125}
129do_test autoinc-2.10 {
130  execsql {
131    INSERT INTO t1 VALUES(125,456);
132    SELECT * FROM sqlite_sequence;
133  }
134} {t1 125}
135do_test autoinc-2.11 {
136  execsql {
137    INSERT INTO t1 VALUES(-1234567,-1);
138    SELECT * FROM sqlite_sequence;
139  }
140} {t1 125}
141do_test autoinc-2.12 {
142  execsql {
143    INSERT INTO t1 VALUES(234,5678);
144    SELECT * FROM sqlite_sequence;
145  }
146} {t1 234}
147do_test autoinc-2.13 {
148  execsql {
149    DELETE FROM t1;
150    INSERT INTO t1 VALUES(NULL,1);
151    SELECT * FROM sqlite_sequence;
152  }
153} {t1 235}
154do_test autoinc-2.14 {
155  execsql {
156    SELECT * FROM t1;
157  }
158} {235 1}
159
160# Manually change the autoincrement values in sqlite_sequence.
161#
162do_test autoinc-2.20 {
163  execsql {
164    UPDATE sqlite_sequence SET seq=1234 WHERE name='t1';
165    INSERT INTO t1 VALUES(NULL,2);
166    SELECT * FROM t1;
167  }
168} {235 1 1235 2}
169do_test autoinc-2.21 {
170  execsql {
171    SELECT * FROM sqlite_sequence;
172  }
173} {t1 1235}
174do_test autoinc-2.22 {
175  execsql {
176    UPDATE sqlite_sequence SET seq=NULL WHERE name='t1';
177    INSERT INTO t1 VALUES(NULL,3);
178    SELECT * FROM t1;
179  }
180} {235 1 1235 2 1236 3}
181do_test autoinc-2.23 {
182  execsql {
183    SELECT * FROM sqlite_sequence;
184  }
185} {t1 1236}
186do_test autoinc-2.24 {
187  execsql {
188    UPDATE sqlite_sequence SET seq='a-string' WHERE name='t1';
189    INSERT INTO t1 VALUES(NULL,4);
190    SELECT * FROM t1;
191  }
192} {235 1 1235 2 1236 3 1237 4}
193do_test autoinc-2.25 {
194  execsql {
195    SELECT * FROM sqlite_sequence;
196  }
197} {t1 1237}
198do_test autoinc-2.26 {
199  execsql {
200    DELETE FROM sqlite_sequence WHERE name='t1';
201    INSERT INTO t1 VALUES(NULL,5);
202    SELECT * FROM t1;
203  }
204} {235 1 1235 2 1236 3 1237 4 1238 5}
205do_test autoinc-2.27 {
206  execsql {
207    SELECT * FROM sqlite_sequence;
208  }
209} {t1 1238}
210do_test autoinc-2.28 {
211  execsql {
212    UPDATE sqlite_sequence SET seq='12345678901234567890'
213      WHERE name='t1';
214    INSERT INTO t1 VALUES(NULL,6);
215    SELECT * FROM t1;
216  }
217} {235 1 1235 2 1236 3 1237 4 1238 5 1239 6}
218do_test autoinc-2.29 {
219  execsql {
220    SELECT * FROM sqlite_sequence;
221  }
222} {t1 1239}
223
224# Test multi-row inserts
225#
226do_test autoinc-2.50 {
227  execsql {
228    DELETE FROM t1 WHERE y>=3;
229    INSERT INTO t1 SELECT NULL, y+2 FROM t1;
230    SELECT * FROM t1;
231  }
232} {235 1 1235 2 1240 3 1241 4}
233do_test autoinc-2.51 {
234  execsql {
235    SELECT * FROM sqlite_sequence
236  }
237} {t1 1241}
238
239ifcapable tempdb {
240  do_test autoinc-2.52 {
241    execsql {
242      CREATE TEMP TABLE t2 AS SELECT y FROM t1;
243      INSERT INTO t1 SELECT NULL, y+4 FROM t2;
244      SELECT * FROM t1;
245    }
246  } {235 1 1235 2 1240 3 1241 4 1242 5 1243 6 1244 7 1245 8}
247  do_test autoinc-2.53 {
248    execsql {
249      SELECT * FROM sqlite_sequence
250    }
251  } {t1 1245}
252  do_test autoinc-2.54 {
253    execsql {
254      DELETE FROM t1;
255      INSERT INTO t1 SELECT NULL, y FROM t2;
256      SELECT * FROM t1;
257    }
258  } {1246 1 1247 2 1248 3 1249 4}
259  do_test autoinc-2.55 {
260    execsql {
261      SELECT * FROM sqlite_sequence
262    }
263  } {t1 1249}
264}
265
266# Create multiple AUTOINCREMENT tables.  Make sure all sequences are
267# tracked separately and do not interfere with one another.
268#
269do_test autoinc-2.70 {
270  catchsql {
271    DROP TABLE t2;
272  }
273  execsql {
274    CREATE TABLE t2(d, e INTEGER PRIMARY KEY AUTOINCREMENT, f);
275    INSERT INTO t2(d) VALUES(1);
276    SELECT * FROM sqlite_sequence;
277  }
278} [ifcapable tempdb {list t1 1249 t2 1} else {list t1 1241 t2 1}]
279do_test autoinc-2.71 {
280  execsql {
281    INSERT INTO t2(d) VALUES(2);
282    SELECT * FROM sqlite_sequence;
283  }
284} [ifcapable tempdb {list t1 1249 t2 2} else {list t1 1241 t2 2}]
285do_test autoinc-2.72 {
286  execsql {
287    INSERT INTO t1(x) VALUES(10000);
288    SELECT * FROM sqlite_sequence;
289  }
290} {t1 10000 t2 2}
291do_test autoinc-2.73 {
292  execsql {
293    CREATE TABLE t3(g INTEGER PRIMARY KEY AUTOINCREMENT, h);
294    INSERT INTO t3(h) VALUES(1);
295    SELECT * FROM sqlite_sequence;
296  }
297} {t1 10000 t2 2 t3 1}
298do_test autoinc-2.74 {
299  execsql {
300    INSERT INTO t2(d,e) VALUES(3,100);
301    SELECT * FROM sqlite_sequence;
302  }
303} {t1 10000 t2 100 t3 1}
304
305
306# When a table with an AUTOINCREMENT is deleted, the corresponding entry
307# in the SQLITE_SEQUENCE table should also be deleted.  But the SQLITE_SEQUENCE
308# table itself should remain behind.
309#
310do_test autoinc-3.1 {
311  execsql {SELECT name FROM sqlite_sequence}
312} {t1 t2 t3}
313do_test autoinc-3.2 {
314  execsql {
315    DROP TABLE t1;
316    SELECT name FROM sqlite_sequence;
317  }
318} {t2 t3}
319do_test autoinc-3.3 {
320  execsql {
321    DROP TABLE t3;
322    SELECT name FROM sqlite_sequence;
323  }
324} {t2}
325do_test autoinc-3.4 {
326  execsql {
327    DROP TABLE t2;
328    SELECT name FROM sqlite_sequence;
329  }
330} {}
331
332# AUTOINCREMENT on TEMP tables.
333#
334ifcapable tempdb {
335  do_test autoinc-4.1 {
336    execsql {
337      SELECT 1, name FROM sqlite_master WHERE type='table';
338      SELECT 2, name FROM sqlite_temp_master WHERE type='table';
339    }
340  } {1 sqlite_sequence}
341  do_test autoinc-4.2 {
342    execsql {
343      CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
344      CREATE TEMP TABLE t3(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
345      SELECT 1, name FROM sqlite_master WHERE type='table';
346      SELECT 2, name FROM sqlite_temp_master WHERE type='table';
347    }
348  } {1 sqlite_sequence 1 t1 2 t3 2 sqlite_sequence}
349  do_test autoinc-4.3 {
350    execsql {
351      SELECT 1, * FROM main.sqlite_sequence;
352      SELECT 2, * FROM temp.sqlite_sequence;
353    }
354  } {}
355  do_test autoinc-4.4 {
356    execsql {
357      INSERT INTO t1 VALUES(10,1);
358      INSERT INTO t3 VALUES(20,2);
359      INSERT INTO t1 VALUES(NULL,3);
360      INSERT INTO t3 VALUES(NULL,4);
361    }
362  } {}
363
364  ifcapable compound {
365  do_test autoinc-4.4.1 {
366    execsql {
367      SELECT * FROM t1 UNION ALL SELECT * FROM t3;
368    }
369  } {10 1 11 3 20 2 21 4}
370  } ;# ifcapable compound
371
372  do_test autoinc-4.5 {
373    execsql {
374      SELECT 1, * FROM main.sqlite_sequence;
375      SELECT 2, * FROM temp.sqlite_sequence;
376    }
377  } {1 t1 11 2 t3 21}
378  do_test autoinc-4.6 {
379    execsql {
380      INSERT INTO t1 SELECT * FROM t3;
381      SELECT 1, * FROM main.sqlite_sequence;
382      SELECT 2, * FROM temp.sqlite_sequence;
383    }
384  } {1 t1 21 2 t3 21}
385  do_test autoinc-4.7 {
386    execsql {
387      INSERT INTO t3 SELECT x+100, y  FROM t1;
388      SELECT 1, * FROM main.sqlite_sequence;
389      SELECT 2, * FROM temp.sqlite_sequence;
390    }
391  } {1 t1 21 2 t3 121}
392  do_test autoinc-4.8 {
393    execsql {
394      DROP TABLE t3;
395      SELECT 1, * FROM main.sqlite_sequence;
396      SELECT 2, * FROM temp.sqlite_sequence;
397    }
398  } {1 t1 21}
399  do_test autoinc-4.9 {
400    execsql {
401      CREATE TEMP TABLE t2(p INTEGER PRIMARY KEY AUTOINCREMENT, q);
402      INSERT INTO t2 SELECT * FROM t1;
403      DROP TABLE t1;
404      SELECT 1, * FROM main.sqlite_sequence;
405      SELECT 2, * FROM temp.sqlite_sequence;
406    }
407  } {2 t2 21}
408  do_test autoinc-4.10 {
409    execsql {
410      DROP TABLE t2;
411      SELECT 1, * FROM main.sqlite_sequence;
412      SELECT 2, * FROM temp.sqlite_sequence;
413    }
414  } {}
415}
416
417# Make sure AUTOINCREMENT works on ATTACH-ed tables.
418#
419ifcapable tempdb {
420  do_test autoinc-5.1 {
421    file delete -force test2.db
422    file delete -force test2.db-journal
423    sqlite3 db2 test2.db
424    execsql {
425      CREATE TABLE t4(m INTEGER PRIMARY KEY AUTOINCREMENT, n);
426      CREATE TABLE t5(o, p INTEGER PRIMARY KEY AUTOINCREMENT);
427    } db2;
428    execsql {
429      ATTACH 'test2.db' as aux;
430      SELECT 1, * FROM main.sqlite_sequence;
431      SELECT 2, * FROM temp.sqlite_sequence;
432      SELECT 3, * FROM aux.sqlite_sequence;
433    }
434  } {}
435  do_test autoinc-5.2 {
436    execsql {
437      INSERT INTO t4 VALUES(NULL,1);
438      SELECT 1, * FROM main.sqlite_sequence;
439      SELECT 2, * FROM temp.sqlite_sequence;
440      SELECT 3, * FROM aux.sqlite_sequence;
441    }
442  } {3 t4 1}
443  do_test autoinc-5.3 {
444    execsql {
445      INSERT INTO t5 VALUES(100,200);
446      SELECT * FROM sqlite_sequence
447    } db2
448  } {t4 1 t5 200}
449  do_test autoinc-5.4 {
450    execsql {
451      SELECT 1, * FROM main.sqlite_sequence;
452      SELECT 2, * FROM temp.sqlite_sequence;
453      SELECT 3, * FROM aux.sqlite_sequence;
454    }
455  } {3 t4 1 3 t5 200}
456}
457
458# Requirement REQ00310:  Make sure an insert fails if the sequence is
459# already at its maximum value.
460#
461ifcapable {rowid32} {
462  do_test autoinc-6.1 {
463    execsql {
464      CREATE TABLE t6(v INTEGER PRIMARY KEY AUTOINCREMENT, w);
465      INSERT INTO t6 VALUES(2147483647,1);
466      SELECT seq FROM main.sqlite_sequence WHERE name='t6';
467    }
468  } 2147483647
469}
470ifcapable {!rowid32} {
471  do_test autoinc-6.1 {
472    execsql {
473      CREATE TABLE t6(v INTEGER PRIMARY KEY AUTOINCREMENT, w);
474      INSERT INTO t6 VALUES(9223372036854775807,1);
475      SELECT seq FROM main.sqlite_sequence WHERE name='t6';
476    }
477  } 9223372036854775807
478}
479do_test autoinc-6.2 {
480  catchsql {
481    INSERT INTO t6 VALUES(NULL,1);
482  }
483} {1 {database or disk is full}}
484
485# Allow the AUTOINCREMENT keyword inside the parentheses
486# on a separate PRIMARY KEY designation.
487#
488do_test autoinc-7.1 {
489  execsql {
490    CREATE TABLE t7(x INTEGER, y REAL, PRIMARY KEY(x AUTOINCREMENT));
491    INSERT INTO t7(y) VALUES(123);
492    INSERT INTO t7(y) VALUES(234);
493    DELETE FROM t7;
494    INSERT INTO t7(y) VALUES(345);
495    SELECT * FROM t7;
496  }
497} {3 345.0}
498
499# Test that if the AUTOINCREMENT is applied to a non integer primary key
500# the error message is sensible.
501do_test autoinc-7.2 {
502  catchsql {
503    CREATE TABLE t8(x TEXT PRIMARY KEY AUTOINCREMENT);
504  }
505} {1 {AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY}}
506
507
508# Ticket #1283.  Make sure that preparing but never running a statement
509# that creates the sqlite_sequence table does not mess up the database.
510#
511do_test autoinc-8.1 {
512  catch {db2 close}
513  catch {db close}
514  file delete -force test.db
515  sqlite3 db test.db
516  set DB [sqlite3_connection_pointer db]
517  set STMT [sqlite3_prepare $DB {
518     CREATE TABLE t1(
519       x INTEGER PRIMARY KEY AUTOINCREMENT
520     )
521  } -1 TAIL]
522  sqlite3_finalize $STMT
523  set STMT [sqlite3_prepare $DB {
524     CREATE TABLE t1(
525       x INTEGER PRIMARY KEY AUTOINCREMENT
526     )
527  } -1 TAIL]
528  sqlite3_step $STMT
529  sqlite3_finalize $STMT
530  execsql {
531    INSERT INTO t1 VALUES(NULL);
532    SELECT * FROM t1;
533  }
534} {1}
535
536finish_test
537