Autoincrement is now working and has regression tests. (CVS 2095)
FossilOrigin-Name: 10c712a21961dbc3bff89c49d5ec3b84b9187c80
This commit is contained in:
parent
b92b70bb0a
commit
f338814455
23
manifest
23
manifest
@ -1,5 +1,5 @@
|
||||
C Change\spragmas\sschema_cookie\sand\suser_cookie\sto\sschema_version\sand\suser_version.\s(CVS\s2094)
|
||||
D 2004-11-12T16:12:00
|
||||
C Autoincrement\sis\snow\sworking\sand\shas\sregression\stests.\s(CVS\s2095)
|
||||
D 2004-11-13T03:48:07
|
||||
F Makefile.in c4d2416860f472a1e3393714d0372074197565df
|
||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
|
||||
@ -31,14 +31,14 @@ F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
|
||||
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
|
||||
F src/btree.c 9fd74df65bad768a441afefc3b73174d45b85d5b
|
||||
F src/btree.h 861e40b759a195ba63819740e484390012cf81ab
|
||||
F src/build.c 45ba40523aa4f9130c5a5af8b7db5d0d878443a3
|
||||
F src/build.c a95eb1181247368b0ffe2eed121a43735976a964
|
||||
F src/date.c 4fd4e90b3880dacd67305e96330940dc243ffc10
|
||||
F src/delete.c f0af21a1ede15524a5edd59fe10ef486283a1ee9
|
||||
F src/expr.c 4ee3e47358c92a919062255b14057a7a8f641e01
|
||||
F src/func.c b68572e79ada56dd038b7e71755212215092b717
|
||||
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||
F src/insert.c e80b009f9ef2864bbaaaae836286f56125a180f6
|
||||
F src/insert.c 9524a6c3e86cbdbae3313f6a083bb9a3e7a2462b
|
||||
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
||||
F src/main.c c7dc54c62c86cab8b2e2883aef607c179eefa611
|
||||
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
||||
@ -54,7 +54,7 @@ F src/os_win.c 9482dfc92f289b68205bb2c9315757c7e3946bfb
|
||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||
F src/pager.c ee88fcecb081e3635c281bc09d604e934429e2f5
|
||||
F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
|
||||
F src/parse.y b64ebeb91d9fc1c813f4517b80e3a3659e94b032
|
||||
F src/parse.y 7978be173379fc72abf8004301577b90408d50e5
|
||||
F src/pragma.c 32ce8fad1a1e05eff97a3dfe02acc61b6936eeee
|
||||
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
|
||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||
@ -64,7 +64,7 @@ F src/sqlite.h.in a44eac0716bf4751447160d5c8ed049ece66d45a
|
||||
F src/sqliteInt.h 8569ce94e891a854de71d7bd628da1d25ee6dfe4
|
||||
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
|
||||
F src/tclsqlite.c 7f1a1a678140e6901c8954590ca2aabe50b48f71
|
||||
F src/test1.c f4dca9e072971dd0207a2d09913da48dac7f7871
|
||||
F src/test1.c bbd404d6ee6bfe326ebf04699a0fabcc28e50a91
|
||||
F src/test2.c b11fa244fff02190707dd0879987c37c75e61fc8
|
||||
F src/test3.c 6f1ec93e13632a004b527049535079eda84c459d
|
||||
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
||||
@ -75,7 +75,7 @@ F src/update.c 3cc67f6053495152e82a6a48c93ed331218e936e
|
||||
F src/utf.c f4f83acd73389090e32d6589d307fc55d794c7ed
|
||||
F src/util.c 005fdf2d008f3429d081766ad6098fdd86d8d8e6
|
||||
F src/vacuum.c ecb4a2c6f1ac5cc9b394dc64d3bb14ca650c4f60
|
||||
F src/vdbe.c 0fd9437a288b19681856ef3f803bfde6858567f1
|
||||
F src/vdbe.c 312df85707ed3d2a90ac2ccec4e614b6996842d9
|
||||
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
|
||||
F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
|
||||
F src/vdbeapi.c 3965bf4678ae32c05f73550c1b5be3268f9f3006
|
||||
@ -88,6 +88,7 @@ F test/attach.test e305dd59a375e37c658c6d401f19f8a95880bf9a
|
||||
F test/attach2.test 399128a7b3b209a339a8dbf53ca2ed42eb982d1a
|
||||
F test/attach3.test 8a0309e284cf9aa1d7d6cc444989031881f7a21c
|
||||
F test/auth.test cf13e449cb253f75d6584b376202c94bbdd53ec9
|
||||
F test/autoinc.test 11330758197e0301d3600a071230d45b2f6a65b7
|
||||
F test/autovacuum.test e52b8fab3b82f6b51b7fde5b7140827ce8e86b1c
|
||||
F test/autovacuum_crash.test 2dca85cbcc497098e45e8847c86407eb3554f3d4
|
||||
F test/bigfile.test d3744a8821ce9abb8697f2826a3e3d22b719e89f
|
||||
@ -256,7 +257,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
|
||||
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
|
||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||
F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c
|
||||
P c4115aa3a1b010704af76c5ae9f6dcbfa4038df8
|
||||
R aad8608531c726385c6e9788af9bc8b9
|
||||
U danielk1977
|
||||
Z 1177c79f2e60c6c7d6713520bedefc82
|
||||
P 5e058318441bb5043c609cc8fba1653995e90efb
|
||||
R c2b0cdd20fba53e39338d096ea4e7b99
|
||||
U drh
|
||||
Z af7f52e053f24291ed6aecd06da0eb9b
|
||||
|
@ -1 +1 @@
|
||||
5e058318441bb5043c609cc8fba1653995e90efb
|
||||
10c712a21961dbc3bff89c49d5ec3b84b9187c80
|
15
src/build.c
15
src/build.c
@ -22,7 +22,7 @@
|
||||
** COMMIT
|
||||
** ROLLBACK
|
||||
**
|
||||
** $Id: build.c,v 1.278 2004/11/12 15:53:37 danielk1977 Exp $
|
||||
** $Id: build.c,v 1.279 2004/11/13 03:48:07 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -1465,13 +1465,8 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){
|
||||
Db *pDb = &db->aDb[p->iDb];
|
||||
if( pDb->pSeqTab==0 ){
|
||||
sqlite3NestedParse(pParse,
|
||||
"CREATE TABLE %Q.sqlite_sequence AS SELECT %Q AS name, 0 AS seq;",
|
||||
pDb->zName, p->zName
|
||||
);
|
||||
}else{
|
||||
sqlite3NestedParse(pParse,
|
||||
"INSERT INTO %Q.sqlite_sequence VALUES(%Q,0)",
|
||||
pDb->zName, p->zName
|
||||
"CREATE TABLE %Q.sqlite_sequence(name,seq)",
|
||||
pDb->zName
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1811,9 +1806,8 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if( pTab->readOnly ){
|
||||
if( pTab->readOnly || pTab==db->aDb[iDb].pSeqTab ){
|
||||
sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
|
||||
pParse->nErr++;
|
||||
goto exit_drop_table;
|
||||
}
|
||||
if( isView && pTab->pSelect==0 ){
|
||||
@ -3006,4 +3000,3 @@ void sqlite3AlterRenameTable(
|
||||
sqliteFree(zName);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
59
src/insert.c
59
src/insert.c
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle INSERT statements in SQLite.
|
||||
**
|
||||
** $Id: insert.c,v 1.125 2004/11/12 03:56:15 drh Exp $
|
||||
** $Id: insert.c,v 1.126 2004/11/13 03:48:07 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -199,6 +199,10 @@ void sqlite3Insert(
|
||||
int after_triggers; /* True if there are AFTER triggers */
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||
int counterRowid; /* Memory cell holding rowid of autoinc counter */
|
||||
#endif
|
||||
|
||||
if( pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;
|
||||
db = pParse->db;
|
||||
|
||||
@ -275,16 +279,29 @@ void sqlite3Insert(
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||
/* If this is an AUTOINCREMENT table, look up the sequence number in the
|
||||
** sqlite_sequence table and store it in a memory cell. Create a new
|
||||
** sqlite_sequence table entry if one does not already exist.
|
||||
** sqlite_sequence table and store it in memory cell counterMem. Also
|
||||
** remember the rowid of the sqlite_sequence table entry in memory cell
|
||||
** counterRowid.
|
||||
*/
|
||||
if( pTab->autoInc ){
|
||||
counterMem = ++pParse->nMem;
|
||||
assert( counterMem>0 ); /* Must be so for OP_NewRecno to work right */
|
||||
sqlite3NestedParse(pParse,
|
||||
"SELECT seq FROM %Q.sqlite_sequence WHERE name=%Q INTO %d",
|
||||
pDb->zName, pTab->zName, counterMem
|
||||
);
|
||||
int iCur = pParse->nTab;
|
||||
int base = sqlite3VdbeCurrentAddr(v);
|
||||
counterRowid = pParse->nMem++;
|
||||
counterMem = pParse->nMem++;
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pDb->pSeqTab->tnum);
|
||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
|
||||
sqlite3VdbeAddOp(v, OP_Rewind, iCur, base+13);
|
||||
sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12);
|
||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, base+13);
|
||||
sqlite3VdbeAddOp(v, OP_Next, iCur, base+4);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_AUTOINCREMENT */
|
||||
|
||||
@ -566,7 +583,7 @@ void sqlite3Insert(
|
||||
sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem);
|
||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||
}else{
|
||||
sqlite3VdbeAddOp(v, OP_NewRecno, base, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||
if( pTab->autoInc ){
|
||||
@ -657,13 +674,25 @@ void sqlite3Insert(
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||
/* Update the sqlite_sequence table
|
||||
/* Update the sqlite_sequence table by storing the content of the
|
||||
** counter value in memory counterMem back into the sqlite_sequence
|
||||
** table.
|
||||
*/
|
||||
if( pTab->autoInc ){
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE %Q.sqlite_sequence SET seq=#-%d WHERE name=%Q",
|
||||
pDb->zName, counterMem+1, pTab->zName
|
||||
);
|
||||
int iCur = pParse->nTab;
|
||||
int base = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pDb->pSeqTab->tnum);
|
||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NewRecno, iCur, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
|
||||
sqlite3VdbeAddOp(v, OP_PutIntKey, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
19
src/parse.y
19
src/parse.y
@ -14,7 +14,7 @@
|
||||
** the parser. Lemon will also generate a header file containing
|
||||
** numeric codes for all of the tokens.
|
||||
**
|
||||
** @(#) $Id: parse.y,v 1.154 2004/11/12 13:42:31 danielk1977 Exp $
|
||||
** @(#) $Id: parse.y,v 1.155 2004/11/13 03:48:07 drh Exp $
|
||||
*/
|
||||
%token_prefix TK_
|
||||
%token_type {Token}
|
||||
@ -268,7 +268,7 @@ conslist ::= conslist COMMA tcons.
|
||||
conslist ::= conslist tcons.
|
||||
conslist ::= tcons.
|
||||
tcons ::= CONSTRAINT nm.
|
||||
tcons ::= PRIMARY KEY LP idxlist(X) RP onconf(R) autoinc(I).
|
||||
tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R).
|
||||
{sqlite3AddPrimaryKey(pParse,X,R,I);}
|
||||
tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
|
||||
{sqlite3CreateIndex(pParse,0,0,0,X,R,0,0);}
|
||||
@ -320,21 +320,6 @@ cmd ::= select(X). {
|
||||
sqlite3SelectDelete(X);
|
||||
}
|
||||
|
||||
%ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||
// The INTO clause after a select only works in nested mode. It causes
|
||||
// the result of the SELECT to be stored in a memory register of the
|
||||
// virtual machine.
|
||||
//
|
||||
cmd ::= select(X) INTO INTEGER(M). {
|
||||
if( pParse->nested ){
|
||||
sqlite3Select(pParse, X, SRT_Mem, atoi(M.z), 0, 0, 0, 0);
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "near \"INTO\": syntax error");
|
||||
}
|
||||
sqlite3SelectDelete(X);
|
||||
}
|
||||
%endif // SQLITE_OMIT_AUTOINCREMENT
|
||||
|
||||
%type select {Select*}
|
||||
%destructor select {sqlite3SelectDelete($$);}
|
||||
%type oneselect {Select*}
|
||||
|
12
src/test1.c
12
src/test1.c
@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test1.c,v 1.110 2004/11/12 15:53:37 danielk1977 Exp $
|
||||
** $Id: test1.c,v 1.111 2004/11/13 03:48:07 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@ -2568,16 +2568,22 @@ static void set_options(Tcl_Interp *interp){
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
#ifdef SQLITE_OMIT_AUTOINCREMENT
|
||||
Tcl_SetVar2(interp, "sqlite_options", "autoinc", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "autoinc", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_AUTOVACUUM
|
||||
Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "1", TCL_GLOBAL_ONLY);
|
||||
#if SQLITE_DEFAULT_AUTOVACUUM==0
|
||||
#endif /* SQLITE_OMIT_AUTOVACUUM */
|
||||
#if !defined(SQLITE_DEFAULT_AUTOVACCUM) || SQLITE_DEFAULT_AUTOVACUUM==0
|
||||
Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","0",TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","1",TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
#endif /* SQLITE_OMIT_AUTOVACUUM */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -43,7 +43,7 @@
|
||||
** in this file for details. If in doubt, do not deviate from existing
|
||||
** commenting and indentation practices when changing or adding code.
|
||||
**
|
||||
** $Id: vdbe.c,v 1.426 2004/11/12 03:56:15 drh Exp $
|
||||
** $Id: vdbe.c,v 1.427 2004/11/13 03:48:07 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -2895,6 +2895,7 @@ case OP_NewRecno: {
|
||||
Mem *pMem;
|
||||
assert( pOp->p2>0 && pOp->p2<p->nMem ); /* P2 is a valid memory cell */
|
||||
pMem = &p->aMem[pOp->p2];
|
||||
Integerify(pMem);
|
||||
assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P2) holds an integer */
|
||||
if( pMem->i==0x7fffffffffffffff || pC->useRandomRowid ){
|
||||
rc = SQLITE_FULL;
|
||||
@ -4126,7 +4127,7 @@ case OP_MemMax: {
|
||||
assert( pTos>=p->aStack );
|
||||
assert( i>=0 && i<p->nMem );
|
||||
pMem = &p->aMem[i];
|
||||
assert( pMem->flags==MEM_Int );
|
||||
Integerify(pMem);
|
||||
Integerify(pTos);
|
||||
if( pMem->i<pTos->i){
|
||||
pMem->i = pTos->i;
|
||||
|
487
test/autoinc.test
Normal file
487
test/autoinc.test
Normal file
@ -0,0 +1,487 @@
|
||||
# 2004 November 12
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the AUTOINCREMENT features.
|
||||
#
|
||||
# $Id: autoinc.test,v 1.1 2004/11/13 03:48:07 drh Exp $
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# If the library is not compiled with autoincrement support then
|
||||
# skip all tests in this file.
|
||||
#
|
||||
ifcapable {!autoinc} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# The database is initially empty.
|
||||
#
|
||||
do_test autoinc-1.1 {
|
||||
execsql {
|
||||
SELECT name FROM sqlite_master WHERE type='table';
|
||||
}
|
||||
} {}
|
||||
|
||||
# Add a table with the AUTOINCREMENT feature. Verify that the
|
||||
# SQLITE_SEQUENCE table gets created.
|
||||
#
|
||||
do_test autoinc-1.2 {
|
||||
execsql {
|
||||
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
|
||||
SELECT name FROM sqlite_master WHERE type='table';
|
||||
}
|
||||
} {t1 sqlite_sequence}
|
||||
|
||||
# The SQLITE_SEQUENCE table is initially empty
|
||||
#
|
||||
do_test autoinc-1.3 {
|
||||
execsql {
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {}
|
||||
|
||||
# Close and reopen the database. Verify that everything is still there.
|
||||
#
|
||||
do_test autoinc-1.4 {
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
execsql {
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {}
|
||||
|
||||
# We are not allowed to drop the sqlite_sequence table.
|
||||
#
|
||||
do_test autoinc-1.5 {
|
||||
catchsql {DROP TABLE sqlite_sequence}
|
||||
} {1 {table sqlite_sequence may not be dropped}}
|
||||
do_test autoinc-1.6 {
|
||||
execsql {SELECT name FROM sqlite_master WHERE type='table'}
|
||||
} {t1 sqlite_sequence}
|
||||
|
||||
# Insert an entries into the t1 table and make sure the largest key
|
||||
# is always recorded in the sqlite_sequence table.
|
||||
#
|
||||
do_test autoinc-2.1 {
|
||||
execsql {
|
||||
SELECT * FROM sqlite_sequence
|
||||
}
|
||||
} {}
|
||||
do_test autoinc-2.2 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(12,34);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 12}
|
||||
do_test autoinc-2.3 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(1,23);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 12}
|
||||
do_test autoinc-2.4 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(123,456);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 123}
|
||||
do_test autoinc-2.5 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(NULL,567);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 124}
|
||||
do_test autoinc-2.6 {
|
||||
execsql {
|
||||
DELETE FROM t1 WHERE y=567;
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 124}
|
||||
do_test autoinc-2.7 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(NULL,567);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 125}
|
||||
do_test autoinc-2.8 {
|
||||
execsql {
|
||||
DELETE FROM t1;
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 125}
|
||||
do_test autoinc-2.9 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(12,34);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 125}
|
||||
do_test autoinc-2.10 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(125,456);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 125}
|
||||
do_test autoinc-2.11 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(-1234567,-1);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 125}
|
||||
do_test autoinc-2.12 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(234,5678);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 234}
|
||||
do_test autoinc-2.13 {
|
||||
execsql {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1 VALUES(NULL,1);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 235}
|
||||
do_test autoinc-2.14 {
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {235 1}
|
||||
|
||||
# Manually change the autoincrement values in sqlite_sequence.
|
||||
#
|
||||
do_test autoinc-2.20 {
|
||||
execsql {
|
||||
UPDATE sqlite_sequence SET seq=1234 WHERE name='t1';
|
||||
INSERT INTO t1 VALUES(NULL,2);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {235 1 1235 2}
|
||||
do_test autoinc-2.21 {
|
||||
execsql {
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 1235}
|
||||
do_test autoinc-2.22 {
|
||||
execsql {
|
||||
UPDATE sqlite_sequence SET seq=NULL WHERE name='t1';
|
||||
INSERT INTO t1 VALUES(NULL,3);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {235 1 1235 2 1236 3}
|
||||
do_test autoinc-2.23 {
|
||||
execsql {
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 1236}
|
||||
do_test autoinc-2.24 {
|
||||
execsql {
|
||||
UPDATE sqlite_sequence SET seq='a-string' WHERE name='t1';
|
||||
INSERT INTO t1 VALUES(NULL,4);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {235 1 1235 2 1236 3 1237 4}
|
||||
do_test autoinc-2.25 {
|
||||
execsql {
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 1237}
|
||||
do_test autoinc-2.26 {
|
||||
execsql {
|
||||
DELETE FROM sqlite_sequence WHERE name='t1';
|
||||
INSERT INTO t1 VALUES(NULL,5);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {235 1 1235 2 1236 3 1237 4 1238 5}
|
||||
do_test autoinc-2.27 {
|
||||
execsql {
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 1238}
|
||||
do_test autoinc-2.28 {
|
||||
execsql {
|
||||
UPDATE sqlite_sequence SET seq='12345678901234567890'
|
||||
WHERE name='t1';
|
||||
INSERT INTO t1 VALUES(NULL,6);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {235 1 1235 2 1236 3 1237 4 1238 5 1239 6}
|
||||
do_test autoinc-2.29 {
|
||||
execsql {
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 1239}
|
||||
|
||||
# Test multi-row inserts
|
||||
#
|
||||
do_test autoinc-2.50 {
|
||||
execsql {
|
||||
DELETE FROM t1 WHERE y>=3;
|
||||
INSERT INTO t1 SELECT NULL, y+2 FROM t1;
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {235 1 1235 2 1240 3 1241 4}
|
||||
do_test autoinc-2.51 {
|
||||
execsql {
|
||||
SELECT * FROM sqlite_sequence
|
||||
}
|
||||
} {t1 1241}
|
||||
do_test autoinc-2.52 {
|
||||
execsql {
|
||||
CREATE TEMP TABLE t2 AS SELECT y FROM t1;
|
||||
INSERT INTO t1 SELECT NULL, y+4 FROM t2;
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {235 1 1235 2 1240 3 1241 4 1242 5 1243 6 1244 7 1245 8}
|
||||
do_test autoinc-2.53 {
|
||||
execsql {
|
||||
SELECT * FROM sqlite_sequence
|
||||
}
|
||||
} {t1 1245}
|
||||
do_test autoinc-2.54 {
|
||||
execsql {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1 SELECT NULL, y FROM t2;
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1246 1 1247 2 1248 3 1249 4}
|
||||
do_test autoinc-2.55 {
|
||||
execsql {
|
||||
SELECT * FROM sqlite_sequence
|
||||
}
|
||||
} {t1 1249}
|
||||
|
||||
# Create multiple AUTOINCREMENT tables. Make sure all sequences are
|
||||
# tracked separately and do not interfere with one another.
|
||||
#
|
||||
do_test autoinc-2.70 {
|
||||
execsql {
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t2(d, e INTEGER PRIMARY KEY AUTOINCREMENT, f);
|
||||
INSERT INTO t2(d) VALUES(1);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 1249 t2 1}
|
||||
do_test autoinc-2.71 {
|
||||
execsql {
|
||||
INSERT INTO t2(d) VALUES(2);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 1249 t2 2}
|
||||
do_test autoinc-2.72 {
|
||||
execsql {
|
||||
INSERT INTO t1(x) VALUES(10000);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 10000 t2 2}
|
||||
do_test autoinc-2.73 {
|
||||
execsql {
|
||||
CREATE TABLE t3(g INTEGER PRIMARY KEY AUTOINCREMENT, h);
|
||||
INSERT INTO t3(h) VALUES(1);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 10000 t2 2 t3 1}
|
||||
do_test autoinc-2.74 {
|
||||
execsql {
|
||||
INSERT INTO t2(d,e) VALUES(3,100);
|
||||
SELECT * FROM sqlite_sequence;
|
||||
}
|
||||
} {t1 10000 t2 100 t3 1}
|
||||
|
||||
|
||||
# When a table with an AUTOINCREMENT is deleted, the corresponding entry
|
||||
# in the SQLITE_SEQUENCE table should also be deleted. But the SQLITE_SEQUENCE
|
||||
# table itself should remain behind.
|
||||
#
|
||||
do_test autoinc-3.1 {
|
||||
execsql {SELECT name FROM sqlite_sequence}
|
||||
} {t1 t2 t3}
|
||||
do_test autoinc-3.2 {
|
||||
execsql {
|
||||
DROP TABLE t1;
|
||||
SELECT name FROM sqlite_sequence;
|
||||
}
|
||||
} {t2 t3}
|
||||
do_test autoinc-3.3 {
|
||||
execsql {
|
||||
DROP TABLE t3;
|
||||
SELECT name FROM sqlite_sequence;
|
||||
}
|
||||
} {t2}
|
||||
do_test autoinc-3.4 {
|
||||
execsql {
|
||||
DROP TABLE t2;
|
||||
SELECT name FROM sqlite_sequence;
|
||||
}
|
||||
} {}
|
||||
|
||||
# AUTOINCREMENT on TEMP tables.
|
||||
#
|
||||
do_test autoinc-4.1 {
|
||||
execsql {
|
||||
SELECT 1, name FROM sqlite_master WHERE type='table'
|
||||
UNION ALL
|
||||
SELECT 2, name FROM sqlite_temp_master WHERE type='table'
|
||||
}
|
||||
} {1 sqlite_sequence}
|
||||
do_test autoinc-4.2 {
|
||||
execsql {
|
||||
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
|
||||
CREATE TEMP TABLE t3(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||
SELECT 1, name FROM sqlite_master WHERE type='table'
|
||||
UNION ALL
|
||||
SELECT 2, name FROM sqlite_temp_master WHERE type='table'
|
||||
}
|
||||
} {1 sqlite_sequence 1 t1 2 t3 2 sqlite_sequence}
|
||||
do_test autoinc-4.3 {
|
||||
execsql {
|
||||
SELECT 1, * FROM main.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 2, * FROM temp.sqlite_sequence
|
||||
}
|
||||
} {}
|
||||
do_test autoinc-4.4 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(10,1);
|
||||
INSERT INTO t3 VALUES(20,2);
|
||||
INSERT INTO t1 VALUES(NULL,3);
|
||||
INSERT INTO t3 VALUES(NULL,4);
|
||||
SELECT * FROM t1 UNION ALL SELECT * FROM t3;
|
||||
}
|
||||
} {10 1 11 3 20 2 21 4}
|
||||
do_test autoinc-4.5 {
|
||||
execsql {
|
||||
SELECT 1, * FROM main.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 2, * FROM temp.sqlite_sequence
|
||||
}
|
||||
} {1 t1 11 2 t3 21}
|
||||
do_test autoinc-4.6 {
|
||||
execsql {
|
||||
INSERT INTO t1 SELECT * FROM t3;
|
||||
SELECT 1, * FROM main.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 2, * FROM temp.sqlite_sequence
|
||||
}
|
||||
} {1 t1 21 2 t3 21}
|
||||
do_test autoinc-4.7 {
|
||||
execsql {
|
||||
INSERT INTO t3 SELECT x+100, y FROM t1;
|
||||
SELECT 1, * FROM main.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 2, * FROM temp.sqlite_sequence
|
||||
}
|
||||
} {1 t1 21 2 t3 121}
|
||||
do_test autoinc-4.8 {
|
||||
execsql {
|
||||
DROP TABLE t3;
|
||||
SELECT 1, * FROM main.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 2, * FROM temp.sqlite_sequence
|
||||
}
|
||||
} {1 t1 21}
|
||||
do_test autoinc-4.9 {
|
||||
execsql {
|
||||
CREATE TEMP TABLE t2(p INTEGER PRIMARY KEY AUTOINCREMENT, q);
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
SELECT 1, * FROM main.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 2, * FROM temp.sqlite_sequence
|
||||
}
|
||||
} {2 t2 21}
|
||||
do_test autoinc-4.10 {
|
||||
execsql {
|
||||
DROP TABLE t2;
|
||||
SELECT 1, * FROM main.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 2, * FROM temp.sqlite_sequence
|
||||
}
|
||||
} {}
|
||||
|
||||
# Make sure AUTOINCREMENT works on ATTACH-ed tables.
|
||||
#
|
||||
do_test autoinc-5.1 {
|
||||
file delete -force test2.db
|
||||
file delete -force test2.db-journal
|
||||
sqlite3 db2 test2.db
|
||||
execsql {
|
||||
CREATE TABLE t4(m INTEGER PRIMARY KEY AUTOINCREMENT, n);
|
||||
CREATE TABLE t5(o, p INTEGER PRIMARY KEY AUTOINCREMENT);
|
||||
} db2;
|
||||
execsql {
|
||||
ATTACH 'test2.db' as aux;
|
||||
SELECT 1, * FROM main.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 2, * FROM temp.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 3, * FROM aux.sqlite_sequence
|
||||
}
|
||||
} {}
|
||||
do_test autoinc-5.2 {
|
||||
execsql {
|
||||
INSERT INTO t4 VALUES(NULL,1);
|
||||
SELECT 1, * FROM main.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 2, * FROM temp.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 3, * FROM aux.sqlite_sequence
|
||||
}
|
||||
} {3 t4 1}
|
||||
do_test autoinc-5.3 {
|
||||
execsql {
|
||||
INSERT INTO t5 VALUES(100,200);
|
||||
SELECT * FROM sqlite_sequence
|
||||
} db2
|
||||
} {t4 1 t5 200}
|
||||
do_test autoinc-5.4 {
|
||||
execsql {
|
||||
SELECT 1, * FROM main.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 2, * FROM temp.sqlite_sequence
|
||||
UNION ALL
|
||||
SELECT 3, * FROM aux.sqlite_sequence
|
||||
}
|
||||
} {3 t4 1 3 t5 200}
|
||||
|
||||
# Requirement REQ00310: Make sure an insert fails if the sequence is
|
||||
# already at its maximum value.
|
||||
#
|
||||
do_test autoinc-6.1 {
|
||||
execsql {
|
||||
CREATE TABLE t6(v INTEGER PRIMARY KEY AUTOINCREMENT, w);
|
||||
INSERT INTO t6 VALUES(9223372036854775807,1);
|
||||
SELECT seq FROM main.sqlite_sequence WHERE name='t6';
|
||||
}
|
||||
} 9223372036854775807
|
||||
do_test autoinc-6.2 {
|
||||
catchsql {
|
||||
INSERT INTO t6 VALUES(NULL,1);
|
||||
}
|
||||
} {1 {database is full}}
|
||||
|
||||
# Allow the AUTOINCREMENT keyword inside the parentheses
|
||||
# on a separate PRIMARY KEY designation.
|
||||
#
|
||||
do_test autoinc-7.1 {
|
||||
execsql {
|
||||
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}
|
||||
|
||||
catch {db2 close}
|
||||
finish_test
|
Loading…
Reference in New Issue
Block a user