mirror of https://github.com/sqlite/sqlite
Autoincrement code installed. Simple smoke-testing only. No regression
tests developed yet. (CVS 2091) FossilOrigin-Name: 8fde833c812b91c5a574208a70b5f92b9d4b0a87
This commit is contained in:
parent
817c60bd66
commit
2958a4e6a5
24
manifest
24
manifest
|
@ -1,5 +1,5 @@
|
||||||
C Website\supdates.\s(CVS\s2090)
|
C Autoincrement\scode\sinstalled.\s\sSimple\ssmoke-testing\sonly.\s\sNo\sregression\ntests\sdeveloped\syet.\s(CVS\s2091)
|
||||||
D 2004-11-11T19:32:40
|
D 2004-11-12T03:56:15
|
||||||
F Makefile.in c4d2416860f472a1e3393714d0372074197565df
|
F Makefile.in c4d2416860f472a1e3393714d0372074197565df
|
||||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||||
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
|
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
|
||||||
|
@ -31,14 +31,14 @@ F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
|
||||||
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
|
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
|
||||||
F src/btree.c 9fd74df65bad768a441afefc3b73174d45b85d5b
|
F src/btree.c 9fd74df65bad768a441afefc3b73174d45b85d5b
|
||||||
F src/btree.h 861e40b759a195ba63819740e484390012cf81ab
|
F src/btree.h 861e40b759a195ba63819740e484390012cf81ab
|
||||||
F src/build.c 27e3cc9e5d5187fa6f23d2e60b76e82c4bc0e7b0
|
F src/build.c 6d1687c66138af18e210981465ee342fe36985d3
|
||||||
F src/date.c 4fd4e90b3880dacd67305e96330940dc243ffc10
|
F src/date.c 4fd4e90b3880dacd67305e96330940dc243ffc10
|
||||||
F src/delete.c f0af21a1ede15524a5edd59fe10ef486283a1ee9
|
F src/delete.c f0af21a1ede15524a5edd59fe10ef486283a1ee9
|
||||||
F src/expr.c 5f9afecf27e048b8f3627b5a9be3136bc1d9bdf1
|
F src/expr.c 4ee3e47358c92a919062255b14057a7a8f641e01
|
||||||
F src/func.c 600e506bccf7648df8ad03efb417560d0f7ad4c1
|
F src/func.c 600e506bccf7648df8ad03efb417560d0f7ad4c1
|
||||||
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
||||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||||
F src/insert.c 8bd40dc5a8e470cba5b9b14211fa88ea0350d2fa
|
F src/insert.c e80b009f9ef2864bbaaaae836286f56125a180f6
|
||||||
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
|
||||||
F src/main.c c7dc54c62c86cab8b2e2883aef607c179eefa611
|
F src/main.c c7dc54c62c86cab8b2e2883aef607c179eefa611
|
||||||
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
||||||
|
@ -54,14 +54,14 @@ F src/os_win.c 9482dfc92f289b68205bb2c9315757c7e3946bfb
|
||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c ee88fcecb081e3635c281bc09d604e934429e2f5
|
F src/pager.c ee88fcecb081e3635c281bc09d604e934429e2f5
|
||||||
F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
|
F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
|
||||||
F src/parse.y 02e0d88a6d465f6fd5ea79a200a8c23c92a877dc
|
F src/parse.y 91a01b5f1170a574b4b9f19871b32bd0f00923a9
|
||||||
F src/pragma.c bb1c76dae9911b9312997b353c1e316fa603a0c6
|
F src/pragma.c bb1c76dae9911b9312997b353c1e316fa603a0c6
|
||||||
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
|
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
|
||||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||||
F src/select.c 156990c636102bb6b8de85e7ff3396a62568476b
|
F src/select.c 156990c636102bb6b8de85e7ff3396a62568476b
|
||||||
F src/shell.c 55adda3cf3c1cc2f6c1919aac17b2318f9c2a96f
|
F src/shell.c 55adda3cf3c1cc2f6c1919aac17b2318f9c2a96f
|
||||||
F src/sqlite.h.in 4f97b5907acfd2a5068cb0cec9d5178816734db7
|
F src/sqlite.h.in 4f97b5907acfd2a5068cb0cec9d5178816734db7
|
||||||
F src/sqliteInt.h 701cbd435750eb854032eaa42e9a12499934e6ce
|
F src/sqliteInt.h 0fdf2b0cf6f2db12c4abefad0f1085268d911f74
|
||||||
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
|
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
|
||||||
F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
|
F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
|
||||||
F src/test1.c e80e070fe794cdc204ec144ce03bd7b27dab4946
|
F src/test1.c e80e070fe794cdc204ec144ce03bd7b27dab4946
|
||||||
|
@ -69,13 +69,13 @@ F src/test2.c b11fa244fff02190707dd0879987c37c75e61fc8
|
||||||
F src/test3.c 6f1ec93e13632a004b527049535079eda84c459d
|
F src/test3.c 6f1ec93e13632a004b527049535079eda84c459d
|
||||||
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
||||||
F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1
|
F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1
|
||||||
F src/tokenize.c c48221284e729be067237a8cfd7848fb62ee4a92
|
F src/tokenize.c 4dc14256d80d25da622d506bfe3b817153b97032
|
||||||
F src/trigger.c f9a0a8d3a87238de1a934eeb7d0b6b1f13e6a55b
|
F src/trigger.c f9a0a8d3a87238de1a934eeb7d0b6b1f13e6a55b
|
||||||
F src/update.c 3cc67f6053495152e82a6a48c93ed331218e936e
|
F src/update.c 3cc67f6053495152e82a6a48c93ed331218e936e
|
||||||
F src/utf.c f4f83acd73389090e32d6589d307fc55d794c7ed
|
F src/utf.c f4f83acd73389090e32d6589d307fc55d794c7ed
|
||||||
F src/util.c 005fdf2d008f3429d081766ad6098fdd86d8d8e6
|
F src/util.c 005fdf2d008f3429d081766ad6098fdd86d8d8e6
|
||||||
F src/vacuum.c ecb4a2c6f1ac5cc9b394dc64d3bb14ca650c4f60
|
F src/vacuum.c ecb4a2c6f1ac5cc9b394dc64d3bb14ca650c4f60
|
||||||
F src/vdbe.c 8bc549adf596ee792facd229ee7f7bfc0b690ad4
|
F src/vdbe.c 0fd9437a288b19681856ef3f803bfde6858567f1
|
||||||
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
|
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
|
||||||
F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
|
F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
|
||||||
F src/vdbeapi.c 3965bf4678ae32c05f73550c1b5be3268f9f3006
|
F src/vdbeapi.c 3965bf4678ae32c05f73550c1b5be3268f9f3006
|
||||||
|
@ -255,7 +255,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
|
||||||
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
|
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
|
||||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||||
F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c
|
F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c
|
||||||
P d28d1d68e5104726e6088361dfa7bf2cdd9985c7
|
P 60fb0cef093b9827ac2d36b8a94e37f4b79dd2ea
|
||||||
R d5f119c36b99dc5061fef0d1b11f7246
|
R ab6b6f9534118088586ec8c53a8170c1
|
||||||
U drh
|
U drh
|
||||||
Z f55195d01ac4ebd4d023505baea63851
|
Z 72c9d0289de8ee06d1a20ab843f47f3d
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
60fb0cef093b9827ac2d36b8a94e37f4b79dd2ea
|
8fde833c812b91c5a574208a70b5f92b9d4b0a87
|
58
src/build.c
58
src/build.c
|
@ -22,7 +22,7 @@
|
||||||
** COMMIT
|
** COMMIT
|
||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.275 2004/11/10 11:55:12 danielk1977 Exp $
|
** $Id: build.c,v 1.276 2004/11/12 03:56:15 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -321,6 +321,7 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
|
||||||
sqlite3DeleteTable(db, pTab);
|
sqlite3DeleteTable(db, pTab);
|
||||||
}
|
}
|
||||||
sqlite3HashClear(&temp1);
|
sqlite3HashClear(&temp1);
|
||||||
|
pDb->pSeqTab = 0;
|
||||||
DbClearProperty(db, i, DB_SchemaLoaded);
|
DbClearProperty(db, i, DB_SchemaLoaded);
|
||||||
if( iDb>0 ) return;
|
if( iDb>0 ) return;
|
||||||
}
|
}
|
||||||
|
@ -517,12 +518,15 @@ void sqlite3OpenMasterTable(Vdbe *v, int iDb){
|
||||||
int findDb(sqlite3 *db, Token *pName){
|
int findDb(sqlite3 *db, Token *pName){
|
||||||
int i;
|
int i;
|
||||||
Db *pDb;
|
Db *pDb;
|
||||||
|
char *zName = sqlite3NameFromToken(pName);
|
||||||
|
int n = strlen(zName);
|
||||||
for(pDb=db->aDb, i=0; i<db->nDb; i++, pDb++){
|
for(pDb=db->aDb, i=0; i<db->nDb; i++, pDb++){
|
||||||
if( pName->n==strlen(pDb->zName) &&
|
if( n==strlen(pDb->zName) && 0==sqlite3StrICmp(pDb->zName, zName) ){
|
||||||
0==sqlite3StrNICmp(pDb->zName, pName->z, pName->n) ){
|
sqliteFree(zName);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sqliteFree(zName);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -720,7 +724,6 @@ void sqlite3StartTable(
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||||
if( strcmp(zName, "sqlite_sequence")==0 ){
|
if( strcmp(zName, "sqlite_sequence")==0 ){
|
||||||
assert( db->aDb[iDb].pSeqTab==0 );
|
|
||||||
db->aDb[iDb].pSeqTab = pTable;
|
db->aDb[iDb].pSeqTab = pTable;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1452,13 +1455,34 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){
|
||||||
zStmt
|
zStmt
|
||||||
);
|
);
|
||||||
sqliteFree(zStmt);
|
sqliteFree(zStmt);
|
||||||
|
sqlite3ChangeCookie(db, v, p->iDb);
|
||||||
|
|
||||||
|
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||||
|
/* Check to see if we need to create an sqlite_sequence table for
|
||||||
|
** keeping track of autoincrement keys.
|
||||||
|
*/
|
||||||
|
if( p->autoInc ){
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Reparse everything to update our internal data structures */
|
/* Reparse everything to update our internal data structures */
|
||||||
sqlite3ChangeCookie(db, v, p->iDb);
|
|
||||||
sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
|
sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
|
||||||
sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
|
sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Add the table to the in-memory representation of the database.
|
/* Add the table to the in-memory representation of the database.
|
||||||
*/
|
*/
|
||||||
if( db->init.busy && pParse->nErr==0 ){
|
if( db->init.busy && pParse->nErr==0 ){
|
||||||
|
@ -1807,7 +1831,9 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
|
||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
Trigger *pTrigger;
|
Trigger *pTrigger;
|
||||||
sqlite3BeginWriteOperation(pParse, 0, pTab->iDb);
|
int iDb = pTab->iDb;
|
||||||
|
Db *pDb = &db->aDb[iDb];
|
||||||
|
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||||
|
|
||||||
/* Drop all triggers associated with the table being dropped. Code
|
/* Drop all triggers associated with the table being dropped. Code
|
||||||
** is generated to remove entries from sqlite_master and/or
|
** is generated to remove entries from sqlite_master and/or
|
||||||
|
@ -1815,7 +1841,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
|
||||||
*/
|
*/
|
||||||
pTrigger = pTab->pTrigger;
|
pTrigger = pTab->pTrigger;
|
||||||
while( pTrigger ){
|
while( pTrigger ){
|
||||||
assert( pTrigger->iDb==pTab->iDb || pTrigger->iDb==1 );
|
assert( pTrigger->iDb==iDb || pTrigger->iDb==1 );
|
||||||
sqlite3DropTriggerPtr(pParse, pTrigger, 1);
|
sqlite3DropTriggerPtr(pParse, pTrigger, 1);
|
||||||
pTrigger = pTrigger->pNext;
|
pTrigger = pTrigger->pNext;
|
||||||
}
|
}
|
||||||
|
@ -1829,11 +1855,25 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
|
||||||
*/
|
*/
|
||||||
sqlite3NestedParse(pParse,
|
sqlite3NestedParse(pParse,
|
||||||
"DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
|
"DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
|
||||||
db->aDb[pTab->iDb].zName, SCHEMA_TABLE(pTab->iDb), pTab->zName);
|
pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
|
||||||
if( !isView ){
|
if( !isView ){
|
||||||
destroyTable(pParse, pTab);
|
destroyTable(pParse, pTab);
|
||||||
}
|
}
|
||||||
sqlite3VdbeOp3(v, OP_DropTable, pTab->iDb, 0, pTab->zName, 0);
|
|
||||||
|
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||||
|
/* Remove any entries of the sqlite_sequence table associated with
|
||||||
|
** the table being dropped */
|
||||||
|
if( pTab->autoInc ){
|
||||||
|
sqlite3NestedParse(pParse,
|
||||||
|
"DELETE FROM %s.sqlite_sequence WHERE name=%Q",
|
||||||
|
pDb->zName, pTab->zName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Remove the table entry from SQLite's internal schema
|
||||||
|
*/
|
||||||
|
sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
|
||||||
}
|
}
|
||||||
sqliteViewResetAll(db, iDb);
|
sqliteViewResetAll(db, iDb);
|
||||||
|
|
||||||
|
|
15
src/expr.c
15
src/expr.c
|
@ -12,7 +12,7 @@
|
||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** for generating VDBE code that evaluates expressions in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: expr.c,v 1.169 2004/11/09 12:44:38 danielk1977 Exp $
|
** $Id: expr.c,v 1.170 2004/11/12 03:56:15 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -202,7 +202,8 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, Token *pToken){
|
||||||
** When doing a nested parse, you can include terms in an expression
|
** When doing a nested parse, you can include terms in an expression
|
||||||
** that look like this: #0 #1 #2 ... These terms refer to elements
|
** that look like this: #0 #1 #2 ... These terms refer to elements
|
||||||
** on the stack. "#0" (or just "#") means the top of the stack.
|
** on the stack. "#0" (or just "#") means the top of the stack.
|
||||||
** "#1" means the next down on the stack. And so forth.
|
** "#1" means the next down on the stack. And so forth. #-1 means
|
||||||
|
** memory location 0. #-2 means memory location 1. And so forth.
|
||||||
**
|
**
|
||||||
** This routine is called by the parser to deal with on of those terms.
|
** This routine is called by the parser to deal with on of those terms.
|
||||||
** It immediately generates code to store the value in a memory location.
|
** It immediately generates code to store the value in a memory location.
|
||||||
|
@ -220,9 +221,13 @@ Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
|
||||||
}
|
}
|
||||||
p = sqlite3Expr(TK_REGISTER, 0, 0, pToken);
|
p = sqlite3Expr(TK_REGISTER, 0, 0, pToken);
|
||||||
depth = atoi(&pToken->z[1]);
|
depth = atoi(&pToken->z[1]);
|
||||||
p->iTable = pParse->nMem++;
|
if( depth>=0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, depth, 0);
|
p->iTable = pParse->nMem++;
|
||||||
sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1);
|
sqlite3VdbeAddOp(v, OP_Dup, depth, 0);
|
||||||
|
sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1);
|
||||||
|
}else{
|
||||||
|
p->iTable = -1-depth;
|
||||||
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
40
src/insert.c
40
src/insert.c
|
@ -12,7 +12,7 @@
|
||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle INSERT statements in SQLite.
|
** to handle INSERT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: insert.c,v 1.124 2004/11/09 12:44:38 danielk1977 Exp $
|
** $Id: insert.c,v 1.125 2004/11/12 03:56:15 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
|
@ -189,6 +189,8 @@ void sqlite3Insert(
|
||||||
int iInsertBlock = 0; /* Address of the subroutine used to insert data */
|
int iInsertBlock = 0; /* Address of the subroutine used to insert data */
|
||||||
int iCntMem = 0; /* Memory cell used for the row counter */
|
int iCntMem = 0; /* Memory cell used for the row counter */
|
||||||
int newIdx = -1; /* Cursor for the NEW table */
|
int newIdx = -1; /* Cursor for the NEW table */
|
||||||
|
Db *pDb; /* The database containing table being inserted into */
|
||||||
|
int counterMem = 0; /* Memory cell holding AUTOINCREMENT counter */
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
int isView; /* True if attempting to insert into a view */
|
int isView; /* True if attempting to insert into a view */
|
||||||
|
@ -210,7 +212,8 @@ void sqlite3Insert(
|
||||||
goto insert_cleanup;
|
goto insert_cleanup;
|
||||||
}
|
}
|
||||||
assert( pTab->iDb<db->nDb );
|
assert( pTab->iDb<db->nDb );
|
||||||
zDb = db->aDb[pTab->iDb].zName;
|
pDb = &db->aDb[pTab->iDb];
|
||||||
|
zDb = pDb->zName;
|
||||||
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
|
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
|
||||||
goto insert_cleanup;
|
goto insert_cleanup;
|
||||||
}
|
}
|
||||||
|
@ -270,6 +273,21 @@ void sqlite3Insert(
|
||||||
newIdx = pParse->nTab++;
|
newIdx = pParse->nTab++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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.
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif /* SQLITE_OMIT_AUTOINCREMENT */
|
||||||
|
|
||||||
/* Figure out how many columns of data are supplied. If the data
|
/* Figure out how many columns of data are supplied. If the data
|
||||||
** is coming from a SELECT statement, then this step also generates
|
** is coming from a SELECT statement, then this step also generates
|
||||||
** all the code to implement the SELECT statement and invoke a subroutine
|
** all the code to implement the SELECT statement and invoke a subroutine
|
||||||
|
@ -545,11 +563,16 @@ void sqlite3Insert(
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
||||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_NewRecno, base, 0);
|
sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem);
|
||||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp(v, OP_NewRecno, base, 0);
|
sqlite3VdbeAddOp(v, OP_NewRecno, base, 0);
|
||||||
}
|
}
|
||||||
|
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||||
|
if( pTab->autoInc ){
|
||||||
|
sqlite3VdbeAddOp(v, OP_MemMax, counterMem, 0);
|
||||||
|
}
|
||||||
|
#endif /* SQLITE_OMIT_AUTOINCREMENT */
|
||||||
|
|
||||||
/* Push onto the stack, data for all columns of the new entry, beginning
|
/* Push onto the stack, data for all columns of the new entry, beginning
|
||||||
** with the first column.
|
** with the first column.
|
||||||
|
@ -633,6 +656,17 @@ void sqlite3Insert(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||||
|
/* Update 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Return the number of rows inserted. If this routine is
|
** Return the number of rows inserted. If this routine is
|
||||||
** generating code because of a call to sqlite3NestedParse(), do not
|
** generating code because of a call to sqlite3NestedParse(), do not
|
||||||
|
|
23
src/parse.y
23
src/parse.y
|
@ -14,7 +14,7 @@
|
||||||
** the parser. Lemon will also generate a header file containing
|
** the parser. Lemon will also generate a header file containing
|
||||||
** numeric codes for all of the tokens.
|
** numeric codes for all of the tokens.
|
||||||
**
|
**
|
||||||
** @(#) $Id: parse.y,v 1.152 2004/11/09 16:13:33 danielk1977 Exp $
|
** @(#) $Id: parse.y,v 1.153 2004/11/12 03:56:15 drh Exp $
|
||||||
*/
|
*/
|
||||||
%token_prefix TK_
|
%token_prefix TK_
|
||||||
%token_type {Token}
|
%token_type {Token}
|
||||||
|
@ -150,7 +150,7 @@ id(A) ::= ID(X). {A = X;}
|
||||||
%ifdef SQLITE_OMIT_COMPOUND_SELECT
|
%ifdef SQLITE_OMIT_COMPOUND_SELECT
|
||||||
EXCEPT INTERSECT UNION
|
EXCEPT INTERSECT UNION
|
||||||
%endif
|
%endif
|
||||||
REINDEX RENAME AUTOINCR CDATE CTIME CTIMESTAMP ALTER
|
REINDEX RENAME CDATE CTIME CTIMESTAMP ALTER
|
||||||
.
|
.
|
||||||
|
|
||||||
// Define operator precedence early so that this is the first occurance
|
// Define operator precedence early so that this is the first occurance
|
||||||
|
@ -230,8 +230,8 @@ ccons ::= COLLATE id(C). {sqlite3AddCollateType(pParse, C.z, C.n);}
|
||||||
|
|
||||||
// The optional AUTOINCREMENT keyword
|
// The optional AUTOINCREMENT keyword
|
||||||
%type autoinc {int}
|
%type autoinc {int}
|
||||||
autoinc(X) ::= . {X = 0;}
|
autoinc(X) ::= . {X = 0;}
|
||||||
autoinc(X) ::= AUTOINC. {X = 1;}
|
autoinc(X) ::= AUTOINCR. {X = 1;}
|
||||||
|
|
||||||
// The next group of rules parses the arguments to a REFERENCES clause
|
// The next group of rules parses the arguments to a REFERENCES clause
|
||||||
// that determine if the referential integrity checking is deferred or
|
// that determine if the referential integrity checking is deferred or
|
||||||
|
@ -320,6 +320,21 @@ cmd ::= select(X). {
|
||||||
sqlite3SelectDelete(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*}
|
%type select {Select*}
|
||||||
%destructor select {sqlite3SelectDelete($$);}
|
%destructor select {sqlite3SelectDelete($$);}
|
||||||
%type oneselect {Select*}
|
%type oneselect {Select*}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.337 2004/11/10 15:27:38 danielk1977 Exp $
|
** @(#) $Id: sqliteInt.h,v 1.338 2004/11/12 03:56:15 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
|
@ -1457,5 +1457,6 @@ sqlite3_value *sqlite3GetTransientValue(sqlite3*db);
|
||||||
extern const unsigned char sqlite3UpperToLower[];
|
extern const unsigned char sqlite3UpperToLower[];
|
||||||
void sqlite3RootPageMoved(Db*, int, int);
|
void sqlite3RootPageMoved(Db*, int, int);
|
||||||
void sqlite3Reindex(Parse*, Token*, Token*);
|
void sqlite3Reindex(Parse*, Token*, Token*);
|
||||||
|
void sqlite3NestedParse(Parse*, const char*, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
** individual tokens and sends those tokens one-by-one over to the
|
** individual tokens and sends those tokens one-by-one over to the
|
||||||
** parser for analysis.
|
** parser for analysis.
|
||||||
**
|
**
|
||||||
** $Id: tokenize.c,v 1.95 2004/11/05 05:10:29 drh Exp $
|
** $Id: tokenize.c,v 1.96 2004/11/12 03:56:15 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
@ -178,7 +178,7 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case '#': {
|
case '#': {
|
||||||
for(i=1; isdigit(z[i]); i++){}
|
for(i=1; isdigit(z[i]) || (i==1 && z[1]=='-'); i++){}
|
||||||
*tokenType = TK_REGISTER;
|
*tokenType = TK_REGISTER;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -409,7 +409,7 @@ abort_parse:
|
||||||
pParse->zErrMsg = 0;
|
pParse->zErrMsg = 0;
|
||||||
if( !nErr ) nErr++;
|
if( !nErr ) nErr++;
|
||||||
}
|
}
|
||||||
if( pParse->pVdbe && pParse->nErr>0 ){
|
if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
|
||||||
sqlite3VdbeDelete(pParse->pVdbe);
|
sqlite3VdbeDelete(pParse->pVdbe);
|
||||||
pParse->pVdbe = 0;
|
pParse->pVdbe = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.425 2004/11/10 11:55:13 danielk1977 Exp $
|
** $Id: vdbe.c,v 1.426 2004/11/12 03:56:15 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
@ -2822,7 +2822,7 @@ case OP_NotExists: {
|
||||||
**
|
**
|
||||||
** If P2>0 then P2 is a memory cell that holds the largest previously
|
** If P2>0 then P2 is a memory cell that holds the largest previously
|
||||||
** generated record number. No new record numbers are allowed to be less
|
** generated record number. No new record numbers are allowed to be less
|
||||||
** than this value. When this value reaches 0x7fffffff, a SQLITE_FULL
|
** than this value. When this value reaches its maximum, a SQLITE_FULL
|
||||||
** error is generated. The P2 memory cell is updated with the generated
|
** error is generated. The P2 memory cell is updated with the generated
|
||||||
** record number. This P2 mechanism is used to help implement the
|
** record number. This P2 mechanism is used to help implement the
|
||||||
** AUTOINCREMENT feature.
|
** AUTOINCREMENT feature.
|
||||||
|
|
Loading…
Reference in New Issue