Files
turso/testing/autoincr.test
Pavan-Nambi bd9ce7c485 add test
2025-10-12 15:58:10 +05:30

191 lines
7.6 KiB
Tcl
Executable File

#!/usr/bin/env tclsh
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Test: Create an AUTOINCREMENT table and verify sqlite_sequence is also created.
do_execsql_test_on_specific_db {:memory:} autoinc-create-sequence-table {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;
} {sqlite_sequence t1}
# Test: The sqlite_sequence table is initially empty after table creation.
do_execsql_test_on_specific_db {:memory:} autoinc-sequence-table-is-initially-empty {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
SELECT * FROM sqlite_sequence;
} {}
# Test: You cannot drop the sqlite_sequence table.
do_execsql_test_in_memory_any_error autoinc-fail-drop-sequence-table {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
DROP TABLE sqlite_sequence;
}
# Test: You cannot create an index on the sqlite_sequence table.
do_execsql_test_in_memory_any_error autoinc-fail-index-sequence-table {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
CREATE INDEX seqidx ON sqlite_sequence(name);
}
# Test: First insert populates sqlite_sequence.
do_execsql_test_on_specific_db {:memory:} autoinc-first-insert-populates-sequence {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
INSERT INTO t1 VALUES(12,34);
SELECT * FROM sqlite_sequence;
} {t1|12}
# Test: Inserting a value larger than the current sequence updates the sequence.
do_execsql_test_on_specific_db {:memory:} autoinc-larger-insert-updates-sequence {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
INSERT INTO t1 VALUES(12,34);
INSERT INTO t1 VALUES(123,456);
SELECT * FROM sqlite_sequence;
} {t1|123}
# Test: Inserting NULL generates a key one greater than the max.
do_execsql_test_on_specific_db {:memory:} autoinc-null-insert-increments-sequence {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
INSERT INTO t1 VALUES(123,456);
INSERT INTO t1 VALUES(NULL,567);
SELECT * FROM sqlite_sequence;
} {t1|124}
# Test: Sequence value is not decreased after a DELETE.
do_execsql_test_on_specific_db {:memory:} autoinc-sequence-not-decremented-by-delete {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
INSERT INTO t1 VALUES(123,456);
INSERT INTO t1 VALUES(NULL,567);
DELETE FROM t1 WHERE y=567;
SELECT * FROM sqlite_sequence;
} {t1|124}
# Test: A NULL insert after a DELETE continues from the previous high-water mark.
do_execsql_test_on_specific_db {:memory:} autoinc-insert-after-delete-uses-high-water-mark {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
INSERT INTO t1 VALUES(125, 1);
DELETE FROM t1;
INSERT INTO t1 VALUES(NULL, 2);
SELECT x FROM t1;
} {126}
# Test: Clearing a table does not reset the sequence.
do_execsql_test_on_specific_db {:memory:} autoinc-delete-all-does-not-reset-sequence {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
INSERT INTO t1 VALUES(125, 456);
DELETE FROM t1;
SELECT * FROM sqlite_sequence;
} {t1|125}
# Test: Manually updating the sequence table affects the next generated key.
do_execsql_test_on_specific_db {:memory:} autoinc-manual-update-to-sequence-table {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
INSERT INTO t1 VALUES(1, 1);
UPDATE sqlite_sequence SET seq=1234 WHERE name='t1';
INSERT INTO t1 VALUES(NULL, 2);
SELECT * FROM t1 ORDER BY x;
} {1|1 1235|2}
# Test: AUTOINCREMENT works for multiple tables independently.
do_execsql_test_on_specific_db {:memory:} autoinc-multiple-tables {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
CREATE TABLE t2(d, e INTEGER PRIMARY KEY AUTOINCREMENT, f);
CREATE TABLE t3(g INTEGER PRIMARY KEY AUTOINCREMENT, h);
INSERT INTO t1(y) VALUES('a');
INSERT INTO t2(d) VALUES('b');
INSERT INTO t2(d) VALUES('c');
INSERT INTO t3(h) VALUES('d');
INSERT INTO t1(x) VALUES(100);
SELECT name, seq FROM sqlite_sequence ORDER BY name;
} {t1|100 t2|2 t3|1}
# Test: Dropping an AUTOINCREMENT table removes its entry from sqlite_sequence.
do_execsql_test_on_specific_db {:memory:} autoinc-drop-table-removes-sequence-entry {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
CREATE TABLE t2(d, e INTEGER PRIMARY KEY AUTOINCREMENT, f);
INSERT INTO t1(y) VALUES('a');
INSERT INTO t2(d) VALUES('b');
DROP TABLE t1;
SELECT name FROM sqlite_sequence;
} {t2}
# Test: When the last AUTOINCREMENT table is dropped, the sequence table remains but is empty.
do_execsql_test_on_specific_db {:memory:} autoinc-drop-last-table-empties-sequence {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
DROP TABLE t1;
SELECT * FROM sqlite_sequence;
} {}
# Test: AUTOINCREMENT fails if the maximum rowid is reached. (Assumes 64-bit rowid)
do_execsql_test_in_memory_any_error autoinc-fail-on-max-rowid {
CREATE TABLE t6(v INTEGER PRIMARY KEY AUTOINCREMENT, w);
INSERT INTO t6 VALUES(9223372036854775807, 1);
INSERT INTO t6 VALUES(NULL, 2);
}
# Test: AUTOINCREMENT keyword is allowed in a separate PRIMARY KEY clause.
do_execsql_test_on_specific_db {:memory:} autoinc-keyword-in-pk-clause {
CREATE TABLE t7(x INTEGER, y REAL, PRIMARY KEY(x AUTOINCREMENT));
INSERT INTO t7(y) VALUES(123);
INSERT INTO t7(y) VALUES(234);
DELETE FROM t7;
INSERT INTO t7(y) VALUES(345);
SELECT * FROM t7;
} {3|345.0}
# Test: AUTOINCREMENT fails if the primary key is not an INTEGER.
do_execsql_test_in_memory_any_error autoinc-fail-on-non-integer-pk {
CREATE TABLE t8(x TEXT PRIMARY KEY AUTOINCREMENT);
}
# Test: An empty INSERT...SELECT does not damage the sequence table. (Ticket #3148)
do_execsql_test_on_specific_db {:memory:} autoinc-empty-insert-select-is-safe {
CREATE TABLE t2(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
INSERT INTO t2 VALUES(NULL, 1);
CREATE TABLE t3(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
INSERT INTO t3 SELECT * FROM t2 WHERE y > 1;
SELECT * FROM sqlite_sequence WHERE name='t3';
} {t3|0}
# Test: AUTOINCREMENT with the xfer optimization. (Ticket 7b3328086a5c1)
do_execsql_test_on_specific_db {:memory:} autoinc-with-xfer-optimization {
CREATE TABLE t10a(a INTEGER PRIMARY KEY AUTOINCREMENT, b UNIQUE);
INSERT INTO t10a VALUES(888,9999);
CREATE TABLE t10b(x INTEGER PRIMARY KEY AUTOINCREMENT, y UNIQUE);
INSERT INTO t10b SELECT * FROM t10a;
SELECT * FROM sqlite_sequence ORDER BY name;
} {t10a|888 t10b|888}
# Test: AUTOINCREMENT works correctly with UPSERT.
do_execsql_test_on_specific_db {:memory:} autoinc-with-upsert {
CREATE TABLE t11(a INTEGER PRIMARY KEY AUTOINCREMENT, b UNIQUE);
INSERT INTO t11(a,b) VALUES(2,3),(5,6),(4,3),(1,2)
ON CONFLICT(b) DO UPDATE SET a=a+1000;
SELECT seq FROM sqlite_sequence WHERE name='t11';
} {5}
# refer https://github.com/tursodatabase/turso/pull/2983#issuecomment-3322404270 was discovered while adding autoincr to fuzz tests
do_execsql_test_on_specific_db {:memory:} autoinc-conflict-on-nothing {
CREATE TABLE t (id INTEGER PRIMARY KEY AUTOINCREMENT, k TEXT);
CREATE UNIQUE INDEX idx_k_partial ON t(k) WHERE id > 1;
INSERT INTO t (k) VALUES ('a');
INSERT INTO t (k) VALUES ('a');
INSERT INTO t (k) VALUES ('a') ON CONFLICT DO NOTHING;
INSERT INTO t (k) VALUES ('b');
SELECT * FROM t ORDER BY id;
} {1|a 2|a 4|b}
# https://github.com/tursodatabase/turso/issues/3664
do_execsql_test_on_specific_db {:memory:} autoinc-skips-manually-updated-pk {
CREATE TABLE t(a INTEGER PRIMARY KEY AUTOINCREMENT);
INSERT INTO t DEFAULT VALUES;
select * from sqlite_sequence;
UPDATE t SET a = a + 1;
SELECT * FROM sqlite_sequence;
INSERT INTO t DEFAULT VALUES;
SELECT * FROM sqlite_sequence;
} {t|1
t|1
t|3}