mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Progress towards getting prepared statements and CREATE and DROP to play
nicely together. Work is incomplete. Some tests are known to fail. (CVS 1864) FossilOrigin-Name: 49b991492496e104f5eca620a5d465a742b7ff3a
This commit is contained in:
24
manifest
24
manifest
@ -1,5 +1,5 @@
|
|||||||
C First\scut\sat\sa\sanalysis\stool\sfor\sversion\s3.0\sdatabases.\s(CVS\s1862)
|
C Progress\stowards\sgetting\sprepared\sstatements\sand\sCREATE\sand\sDROP\sto\splay\nnicely\stogether.\s\sWork\sis\sincomplete.\s\sSome\stests\sare\sknown\sto\sfail.\s(CVS\s1864)
|
||||||
D 2004-07-23T00:01:39
|
D 2004-07-24T03:30:48
|
||||||
F Makefile.in 4a5e570a9e2d35b09c31b3cf01b78cea764ade4b
|
F Makefile.in 4a5e570a9e2d35b09c31b3cf01b78cea764ade4b
|
||||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@ -29,7 +29,7 @@ F src/attach.c 784456629b3d7e50e4691f496700658fd1f16441
|
|||||||
F src/auth.c 60db23b98bb94c8b0178180faaf49dc116674217
|
F src/auth.c 60db23b98bb94c8b0178180faaf49dc116674217
|
||||||
F src/btree.c edf4ece708350dec7f28ebd4620c6d33afe6993a
|
F src/btree.c edf4ece708350dec7f28ebd4620c6d33afe6993a
|
||||||
F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
|
F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
|
||||||
F src/build.c 3a1356286569266873d5d1c910e7797a3bfd5761
|
F src/build.c d1870caf93cce22e6991116e39cf5c05c73882ee
|
||||||
F src/date.c e1bb384a7856c18dce9cadb0afbe6934ba5ddb00
|
F src/date.c e1bb384a7856c18dce9cadb0afbe6934ba5ddb00
|
||||||
F src/delete.c e81545e546f6bc87d7508a93a09ca70695265af3
|
F src/delete.c e81545e546f6bc87d7508a93a09ca70695265af3
|
||||||
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
|
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
|
||||||
@ -39,7 +39,7 @@ F src/hash.c f0a2f22c2a7052d67053b5f4690ea3010bb3fb9f
|
|||||||
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
|
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
|
||||||
F src/insert.c d99ffe87e1e1397f4233afcd06841d52d6b17b18
|
F src/insert.c d99ffe87e1e1397f4233afcd06841d52d6b17b18
|
||||||
F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
|
F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
|
||||||
F src/main.c 447db2fb6121360814afd725ee93c22d6eef8e7f
|
F src/main.c c4ba7d8f674d7c880e2e0deea16432d63defa5b2
|
||||||
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
|
||||||
F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345
|
F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345
|
||||||
F src/os_common.h fe9604754116bd2f2702d58f82d2d8b89998cb21
|
F src/os_common.h fe9604754116bd2f2702d58f82d2d8b89998cb21
|
||||||
@ -60,7 +60,7 @@ F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
|||||||
F src/select.c aefda626660086addca4ce85c34aeef5d0f44c25
|
F src/select.c aefda626660086addca4ce85c34aeef5d0f44c25
|
||||||
F src/shell.c 93c96c847228c02fb84bb381875d87ee71fbbeb4
|
F src/shell.c 93c96c847228c02fb84bb381875d87ee71fbbeb4
|
||||||
F src/sqlite.h.in 80de11cde2c9f78eff4dab0aad1eb5196d6e2a3f
|
F src/sqlite.h.in 80de11cde2c9f78eff4dab0aad1eb5196d6e2a3f
|
||||||
F src/sqliteInt.h 049cb4f716f7b7ea3657f26c7e26a4f821aca53c
|
F src/sqliteInt.h 8cf9cf4bd02dacedbf3738ecfad49ea32e599e47
|
||||||
F src/table.c 4521c278892f60e4d630788c0ea5cf4db1e75c49
|
F src/table.c 4521c278892f60e4d630788c0ea5cf4db1e75c49
|
||||||
F src/tclsqlite.c 3ce001b3c301876a9c8163472077a4c10e0d49f3
|
F src/tclsqlite.c 3ce001b3c301876a9c8163472077a4c10e0d49f3
|
||||||
F src/test1.c ef00096c283ccfec1b2ae5fdaccb85fb06e24281
|
F src/test1.c ef00096c283ccfec1b2ae5fdaccb85fb06e24281
|
||||||
@ -68,13 +68,13 @@ F src/test2.c f4c2f3928f1998fd8cb75a81e33a60e025ea85d4
|
|||||||
F src/test3.c 94d0a2a90bccd85802488cb42c69ec8afd2e4646
|
F src/test3.c 94d0a2a90bccd85802488cb42c69ec8afd2e4646
|
||||||
F src/test4.c a921a69821fd30209589228e64f94e9f715b6fe2
|
F src/test4.c a921a69821fd30209589228e64f94e9f715b6fe2
|
||||||
F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1
|
F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1
|
||||||
F src/tokenize.c 900374b6b37f04748bcd48c2d29a41c251542935
|
F src/tokenize.c 368c1c6eb11355188fc4423e77c1708856b16c9b
|
||||||
F src/trigger.c 6aaf6d79cc2157c70a06031dd1531707d644cfb4
|
F src/trigger.c 6aaf6d79cc2157c70a06031dd1531707d644cfb4
|
||||||
F src/update.c b66b1896c9da54678ba3eff2bf0b4d291a95986a
|
F src/update.c b66b1896c9da54678ba3eff2bf0b4d291a95986a
|
||||||
F src/utf.c f03535db72bfa09e24202ccdd245f21d2fc65f0a
|
F src/utf.c f03535db72bfa09e24202ccdd245f21d2fc65f0a
|
||||||
F src/util.c 2aacc79b7bf5df5859813dafd3bf3258f67a5234
|
F src/util.c 2aacc79b7bf5df5859813dafd3bf3258f67a5234
|
||||||
F src/vacuum.c b8546f4921719458cc537b9e736df52a8256399c
|
F src/vacuum.c b8546f4921719458cc537b9e736df52a8256399c
|
||||||
F src/vdbe.c 5a7d1ee9d7356df6b53be64c1776824a33f6f2fb
|
F src/vdbe.c 5d35f08682878165bfba796b298fe3615ae9c9fc
|
||||||
F src/vdbe.h 75b241c02431b9c0f16eaa9cdbb34146c6287f52
|
F src/vdbe.h 75b241c02431b9c0f16eaa9cdbb34146c6287f52
|
||||||
F src/vdbeInt.h 7160653a006b6d2c4a00d204112a095bdf842ab6
|
F src/vdbeInt.h 7160653a006b6d2c4a00d204112a095bdf842ab6
|
||||||
F src/vdbeapi.c c5c6d8f162a9581dde497b1a4034f9a0bf54c355
|
F src/vdbeapi.c c5c6d8f162a9581dde497b1a4034f9a0bf54c355
|
||||||
@ -140,7 +140,7 @@ F test/minmax.test 6513f9a1bb85fd35ff72b34b7b6634fad6b1e69c
|
|||||||
F test/misc1.test 72768ec8cabc952a4cfcddca43d566f9e0bce899
|
F test/misc1.test 72768ec8cabc952a4cfcddca43d566f9e0bce899
|
||||||
F test/misc2.test 703734f5817215ca54e364833b3bf5ff36fcc21e
|
F test/misc2.test 703734f5817215ca54e364833b3bf5ff36fcc21e
|
||||||
F test/misc3.test eb488314990bfc0959221a1acc465013238bf168
|
F test/misc3.test eb488314990bfc0959221a1acc465013238bf168
|
||||||
F test/misc4.test 9e4291bb174e4357459e0b080f7ca9c6733150c9
|
F test/misc4.test e941a0918df0bf3ab42563e35970d98288ddddf7
|
||||||
F test/misuse.test 2a64ce711419f2fd12806ed95af930fd4e7bb8f3
|
F test/misuse.test 2a64ce711419f2fd12806ed95af930fd4e7bb8f3
|
||||||
F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
|
F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
|
||||||
F test/null.test c14d0f4739f21e929b8115b72bf0c765b6bb1721
|
F test/null.test c14d0f4739f21e929b8115b72bf0c765b6bb1721
|
||||||
@ -161,7 +161,7 @@ F test/select5.test 3f3f0f31e674fa61f8a3bdb6af1517dfae674081
|
|||||||
F test/select6.test a9e31906e700e7c7592c4d0acfc022808f718baf
|
F test/select6.test a9e31906e700e7c7592c4d0acfc022808f718baf
|
||||||
F test/sort.test 30fb9ea782a78da849a562d53233ec62d421bf61
|
F test/sort.test 30fb9ea782a78da849a562d53233ec62d421bf61
|
||||||
F test/subselect.test cca16490d78613174bf90a8416fc21a383ec7c71
|
F test/subselect.test cca16490d78613174bf90a8416fc21a383ec7c71
|
||||||
F test/table.test b6d07f04c4157d1f2a37fb7febe36b250d468e31
|
F test/table.test fd9a0f4992230e4ca89cd37ae3191a12750df1d0
|
||||||
F test/tableapi.test b21ab097e87a5484bb61029e69e1a4e5c5e65ede
|
F test/tableapi.test b21ab097e87a5484bb61029e69e1a4e5c5e65ede
|
||||||
F test/tclsqlite.test 0ef39b0228a32601432cec20208ec4b35e9b5cdb
|
F test/tclsqlite.test 0ef39b0228a32601432cec20208ec4b35e9b5cdb
|
||||||
F test/temptable.test 63a16e3ad19adf073cfbcdf7624c92ac5236522c
|
F test/temptable.test 63a16e3ad19adf073cfbcdf7624c92ac5236522c
|
||||||
@ -240,7 +240,7 @@ F www/tclsqlite.tcl 06a86cba4d7fc88e2bcd633b57702d3d16abebb5
|
|||||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
||||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||||
P 15774aab7d20eb4dfcb47378c8255e26b8cbbe19
|
P 7c7f698b2eda7b1b34f5ca7fe104145d8bbd8f56
|
||||||
R 1451250ebcf80a0882a7e76f969566bf
|
R b1b16f99b3da9325a0228f34d4f42233
|
||||||
U drh
|
U drh
|
||||||
Z af23712a2660f12a62a563c7e13af761
|
Z b40eb69ee75bee6f41ad47e71f93841a
|
||||||
|
@ -1 +1 @@
|
|||||||
7c7f698b2eda7b1b34f5ca7fe104145d8bbd8f56
|
49b991492496e104f5eca620a5d465a742b7ff3a
|
124
src/build.c
124
src/build.c
@ -23,7 +23,7 @@
|
|||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
** PRAGMA
|
** PRAGMA
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.240 2004/07/22 01:19:35 drh Exp $
|
** $Id: build.c,v 1.241 2004/07/24 03:30:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -231,8 +231,8 @@ void sqlite3UnlinkAndDeleteIndex(sqlite *db, Index *pIndex){
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Erase all schema information from the in-memory hash tables of
|
** Erase all schema information from the in-memory hash tables of
|
||||||
** a sigle database. This routine is called to reclaim memory
|
** a single database. This routine is called to reclaim memory
|
||||||
** before the closes. It is also called during a rollback
|
** before the database closes. It is also called during a rollback
|
||||||
** if there were schema changes during the transaction or if a
|
** if there were schema changes during the transaction or if a
|
||||||
** schema-cookie mismatch occurs.
|
** schema-cookie mismatch occurs.
|
||||||
**
|
**
|
||||||
@ -1169,14 +1169,16 @@ void sqlite3ChangeCookie(sqlite *db, Vdbe *v, int iDb){
|
|||||||
** Measure the number of characters needed to output the given
|
** Measure the number of characters needed to output the given
|
||||||
** identifier. The number returned includes any quotes used
|
** identifier. The number returned includes any quotes used
|
||||||
** but does not include the null terminator.
|
** but does not include the null terminator.
|
||||||
|
**
|
||||||
|
** The estimate is conservative. It might be larger that what is
|
||||||
|
** really needed.
|
||||||
*/
|
*/
|
||||||
static int identLength(const char *z){
|
static int identLength(const char *z){
|
||||||
int n;
|
int n;
|
||||||
int needQuote = 0;
|
|
||||||
for(n=0; *z; n++, z++){
|
for(n=0; *z; n++, z++){
|
||||||
if( *z=='\'' ){ n++; needQuote=1; }
|
if( *z=='"' ){ n++; }
|
||||||
}
|
}
|
||||||
return n + needQuote*2;
|
return n + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1191,12 +1193,12 @@ static void identPut(char *z, int *pIdx, char *zIdent){
|
|||||||
}
|
}
|
||||||
needQuote = zIdent[j]!=0 || isdigit(zIdent[0])
|
needQuote = zIdent[j]!=0 || isdigit(zIdent[0])
|
||||||
|| sqlite3KeywordCode(zIdent, j)!=TK_ID;
|
|| sqlite3KeywordCode(zIdent, j)!=TK_ID;
|
||||||
if( needQuote ) z[i++] = '\'';
|
if( needQuote ) z[i++] = '"';
|
||||||
for(j=0; zIdent[j]; j++){
|
for(j=0; zIdent[j]; j++){
|
||||||
z[i++] = zIdent[j];
|
z[i++] = zIdent[j];
|
||||||
if( zIdent[j]=='\'' ) z[i++] = '\'';
|
if( zIdent[j]=='"' ) z[i++] = '"';
|
||||||
}
|
}
|
||||||
if( needQuote ) z[i++] = '\'';
|
if( needQuote ) z[i++] = '"';
|
||||||
z[i] = 0;
|
z[i] = 0;
|
||||||
*pIdx = i;
|
*pIdx = i;
|
||||||
}
|
}
|
||||||
@ -1209,16 +1211,18 @@ static void identPut(char *z, int *pIdx, char *zIdent){
|
|||||||
static char *createTableStmt(Table *p){
|
static char *createTableStmt(Table *p){
|
||||||
int i, k, n;
|
int i, k, n;
|
||||||
char *zStmt;
|
char *zStmt;
|
||||||
char *zSep, *zSep2, *zEnd;
|
char *zSep, *zSep2, *zEnd, *z;
|
||||||
|
Column *pCol;
|
||||||
n = 0;
|
n = 0;
|
||||||
for(i=0; i<p->nCol; i++){
|
for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
|
||||||
n += identLength(p->aCol[i].zName);
|
n += identLength(pCol->zName);
|
||||||
if( p->aCol[i].zType ){
|
z = pCol->zType;
|
||||||
n += (strlen(p->aCol[i].zType) + 1);
|
if( z ){
|
||||||
|
n += (strlen(z) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n += identLength(p->zName);
|
n += identLength(p->zName);
|
||||||
if( n<40 ){
|
if( n<50 ){
|
||||||
zSep = "";
|
zSep = "";
|
||||||
zSep2 = ",";
|
zSep2 = ",";
|
||||||
zEnd = ")";
|
zEnd = ")";
|
||||||
@ -1234,15 +1238,15 @@ static char *createTableStmt(Table *p){
|
|||||||
k = strlen(zStmt);
|
k = strlen(zStmt);
|
||||||
identPut(zStmt, &k, p->zName);
|
identPut(zStmt, &k, p->zName);
|
||||||
zStmt[k++] = '(';
|
zStmt[k++] = '(';
|
||||||
for(i=0; i<p->nCol; i++){
|
for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
|
||||||
strcpy(&zStmt[k], zSep);
|
strcpy(&zStmt[k], zSep);
|
||||||
k += strlen(&zStmt[k]);
|
k += strlen(&zStmt[k]);
|
||||||
zSep = zSep2;
|
zSep = zSep2;
|
||||||
identPut(zStmt, &k, p->aCol[i].zName);
|
identPut(zStmt, &k, pCol->zName);
|
||||||
if( p->aCol[i].zType ){
|
if( (z = pCol->zType)!=0 ){
|
||||||
zStmt[k++] = ' ';
|
zStmt[k++] = ' ';
|
||||||
strcpy(&zStmt[k], p->aCol[i].zType);
|
strcpy(&zStmt[k], z);
|
||||||
k += strlen(p->aCol[i].zType);
|
k += strlen(z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strcpy(&zStmt[k], zEnd);
|
strcpy(&zStmt[k], zEnd);
|
||||||
@ -1305,12 +1309,11 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){
|
|||||||
|
|
||||||
if( p->pSelect==0 ){
|
if( p->pSelect==0 ){
|
||||||
/* A regular table */
|
/* A regular table */
|
||||||
sqlite3VdbeOp3(v, OP_CreateTable, 0, p->iDb, (char*)&p->tnum, P3_POINTER);
|
sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0);
|
||||||
}else{
|
}else{
|
||||||
/* A view */
|
/* A view */
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
||||||
}
|
}
|
||||||
p->tnum = 0;
|
|
||||||
|
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
||||||
|
|
||||||
@ -1371,13 +1374,15 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){
|
|||||||
sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
|
sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
|
||||||
sqlite3ChangeCookie(db, v, p->iDb);
|
sqlite3ChangeCookie(db, v, p->iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
||||||
|
sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
|
||||||
|
sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
|
||||||
|
|
||||||
sqlite3EndWriteOperation(pParse);
|
sqlite3EndWriteOperation(pParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the table to the in-memory representation of the database.
|
/* Add the table to the in-memory representation of the database.
|
||||||
*/
|
*/
|
||||||
if( pParse->explain==0 && pParse->nErr==0 ){
|
if( db->init.busy && pParse->nErr==0 ){
|
||||||
Table *pOld;
|
Table *pOld;
|
||||||
FKey *pFKey;
|
FKey *pFKey;
|
||||||
pOld = sqlite3HashInsert(&db->aDb[p->iDb].tblHash,
|
pOld = sqlite3HashInsert(&db->aDb[p->iDb].tblHash,
|
||||||
@ -1565,26 +1570,6 @@ static void sqliteViewResetAll(sqlite *db, int idx){
|
|||||||
DbClearProperty(db, idx, DB_UnresetViews);
|
DbClearProperty(db, idx, DB_UnresetViews);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
** Given a token, look up a table with that name. If not found, leave
|
|
||||||
** an error for the parser to find and return NULL.
|
|
||||||
*/
|
|
||||||
Table *sqlite3TableFromToken(Parse *pParse, Token *pTok){
|
|
||||||
char *zName;
|
|
||||||
Table *pTab;
|
|
||||||
zName = sqlite3NameFromToken(pTok);
|
|
||||||
if( zName==0 ) return 0;
|
|
||||||
pTab = sqlite3FindTable(pParse->db, zName, 0);
|
|
||||||
sqliteFree(zName);
|
|
||||||
if( pTab==0 ){
|
|
||||||
sqlite3ErrorMsg(pParse, "no such table: %T", pTok);
|
|
||||||
pParse->checkSchema = 1;
|
|
||||||
}
|
|
||||||
return pTab;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine is called to do the work of a DROP TABLE statement.
|
** This routine is called to do the work of a DROP TABLE statement.
|
||||||
** pName is the name of the table to be dropped.
|
** pName is the name of the table to be dropped.
|
||||||
@ -2099,7 +2084,7 @@ void sqlite3CreateIndex(
|
|||||||
/* Link the new Index structure to its table and to the other
|
/* Link the new Index structure to its table and to the other
|
||||||
** in-memory database structures.
|
** in-memory database structures.
|
||||||
*/
|
*/
|
||||||
if( !pParse->explain ){
|
if( db->init.busy ){
|
||||||
Index *p;
|
Index *p;
|
||||||
p = sqlite3HashInsert(&db->aDb[pIndex->iDb].idxHash,
|
p = sqlite3HashInsert(&db->aDb[pIndex->iDb].idxHash,
|
||||||
pIndex->zName, strlen(pIndex->zName)+1, pIndex);
|
pIndex->zName, strlen(pIndex->zName)+1, pIndex);
|
||||||
@ -2108,14 +2093,9 @@ void sqlite3CreateIndex(
|
|||||||
goto exit_create_index;
|
goto exit_create_index;
|
||||||
}
|
}
|
||||||
db->flags |= SQLITE_InternChanges;
|
db->flags |= SQLITE_InternChanges;
|
||||||
}
|
if( pTblName!=0 ){
|
||||||
|
pIndex->tnum = db->init.newTnum;
|
||||||
/* If the db->init.busy is 1 it means we are reading the SQL off the
|
}
|
||||||
** "sqlite_master" table on the disk. So do not write to the disk
|
|
||||||
** again. Extract the table number from the db->init.newTnum field.
|
|
||||||
*/
|
|
||||||
if( db->init.busy && pTblName!=0 ){
|
|
||||||
pIndex->tnum = db->init.newTnum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the db->init.busy is 0 then create the index on disk. This
|
/* If the db->init.busy is 0 then create the index on disk. This
|
||||||
@ -2148,8 +2128,7 @@ void sqlite3CreateIndex(
|
|||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, "index", P3_STATIC);
|
sqlite3VdbeOp3(v, OP_String8, 0, 0, "index", P3_STATIC);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pIndex->zName, 0);
|
sqlite3VdbeOp3(v, OP_String8, 0, 0, pIndex->zName, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
||||||
sqlite3VdbeOp3(v, OP_CreateIndex, 0, iDb,(char*)&pIndex->tnum,P3_POINTER);
|
sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0);
|
||||||
pIndex->tnum = 0;
|
|
||||||
if( pTblName ){
|
if( pTblName ){
|
||||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
||||||
@ -2185,11 +2164,11 @@ void sqlite3CreateIndex(
|
|||||||
sqlite3VdbeResolveLabel(v, lbl2);
|
sqlite3VdbeResolveLabel(v, lbl2);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 2, 0);
|
sqlite3VdbeAddOp(v, OP_Close, 2, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Close, 1, 0);
|
||||||
}
|
|
||||||
if( pTblName!=0 ){
|
|
||||||
sqlite3ChangeCookie(db, v, iDb);
|
sqlite3ChangeCookie(db, v, iDb);
|
||||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
||||||
sqlite3EndWriteOperation(pParse);
|
sqlite3EndWriteOperation(pParse);
|
||||||
|
sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0,
|
||||||
|
sqlite3MPrintf("name='%q'", pIndex->zName), P3_DYNAMIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2198,19 +2177,21 @@ void sqlite3CreateIndex(
|
|||||||
** OE_Ignore. This is necessary for the correct operation of UPDATE
|
** OE_Ignore. This is necessary for the correct operation of UPDATE
|
||||||
** and INSERT.
|
** and INSERT.
|
||||||
*/
|
*/
|
||||||
if( onError!=OE_Replace || pTab->pIndex==0
|
if( db->init.busy || pTblName==0 ){
|
||||||
|| pTab->pIndex->onError==OE_Replace){
|
if( onError!=OE_Replace || pTab->pIndex==0
|
||||||
pIndex->pNext = pTab->pIndex;
|
|| pTab->pIndex->onError==OE_Replace){
|
||||||
pTab->pIndex = pIndex;
|
pIndex->pNext = pTab->pIndex;
|
||||||
}else{
|
pTab->pIndex = pIndex;
|
||||||
Index *pOther = pTab->pIndex;
|
}else{
|
||||||
while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
|
Index *pOther = pTab->pIndex;
|
||||||
pOther = pOther->pNext;
|
while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
|
||||||
|
pOther = pOther->pNext;
|
||||||
|
}
|
||||||
|
pIndex->pNext = pOther->pNext;
|
||||||
|
pOther->pNext = pIndex;
|
||||||
}
|
}
|
||||||
pIndex->pNext = pOther->pNext;
|
pIndex = 0;
|
||||||
pOther->pNext = pIndex;
|
|
||||||
}
|
}
|
||||||
pIndex = 0;
|
|
||||||
|
|
||||||
/* Clean up before exiting */
|
/* Clean up before exiting */
|
||||||
exit_create_index:
|
exit_create_index:
|
||||||
@ -2244,13 +2225,6 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){
|
|||||||
"or PRIMARY KEY constraint cannot be dropped", 0);
|
"or PRIMARY KEY constraint cannot be dropped", 0);
|
||||||
goto exit_drop_index;
|
goto exit_drop_index;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if( pIndex->iDb>1 ){
|
|
||||||
sqlite3ErrorMsg(pParse, "cannot alter schema of attached "
|
|
||||||
"databases", 0);
|
|
||||||
goto exit_drop_index;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
{
|
{
|
||||||
int code = SQLITE_DROP_INDEX;
|
int code = SQLITE_DROP_INDEX;
|
||||||
@ -2272,7 +2246,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){
|
|||||||
if( v ){
|
if( v ){
|
||||||
static VdbeOpList dropIndex[] = {
|
static VdbeOpList dropIndex[] = {
|
||||||
{ OP_Rewind, 0, ADDR(9), 0},
|
{ OP_Rewind, 0, ADDR(9), 0},
|
||||||
{ OP_String8, 0, 0, 0}, /* 1 */
|
{ OP_String8, 0, 0, 0}, /* 1 */
|
||||||
{ OP_MemStore, 1, 1, 0},
|
{ OP_MemStore, 1, 1, 0},
|
||||||
{ OP_MemLoad, 1, 0, 0}, /* 3 */
|
{ OP_MemLoad, 1, 0, 0}, /* 3 */
|
||||||
{ OP_Column, 0, 1, 0},
|
{ OP_Column, 0, 1, 0},
|
||||||
|
150
src/main.c
150
src/main.c
@ -14,21 +14,12 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** accessed by users of the library.
|
||||||
**
|
**
|
||||||
** $Id: main.c,v 1.246 2004/07/22 01:19:35 drh Exp $
|
** $Id: main.c,v 1.247 2004/07/24 03:30:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
/*
|
|
||||||
** A pointer to this structure is used to communicate information
|
|
||||||
** from sqlite3Init into the sqlite3InitCallback.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
sqlite *db; /* The database being initialized */
|
|
||||||
char **pzErrMsg; /* Error message stored here */
|
|
||||||
} InitData;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The following constant value is used by the SQLITE_BIGENDIAN and
|
** The following constant value is used by the SQLITE_BIGENDIAN and
|
||||||
** SQLITE_LITTLEENDIAN macros.
|
** SQLITE_LITTLEENDIAN macros.
|
||||||
@ -49,89 +40,69 @@ static void corruptSchema(InitData *pData, const char *zExtra){
|
|||||||
/*
|
/*
|
||||||
** This is the callback routine for the code that initializes the
|
** This is the callback routine for the code that initializes the
|
||||||
** database. See sqlite3Init() below for additional information.
|
** database. See sqlite3Init() below for additional information.
|
||||||
|
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
|
||||||
**
|
**
|
||||||
** Each callback contains the following information:
|
** Each callback contains the following information:
|
||||||
**
|
**
|
||||||
** argv[0] = "table" or "index" or "view" or "trigger"
|
** argv[0] = name of thing being created
|
||||||
** argv[1] = name of thing being created
|
** argv[1] = root page number for table or index. NULL for trigger or view.
|
||||||
** argv[2] = root page number for table or index. NULL for trigger or view.
|
** argv[2] = SQL text for the CREATE statement.
|
||||||
** argv[3] = SQL text for the CREATE statement.
|
** argv[3] = "1" for temporary files, "0" for main database, "2" or more
|
||||||
** argv[4] = "1" for temporary files, "0" for main database, "2" or more
|
|
||||||
** for auxiliary database files.
|
** for auxiliary database files.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
static
|
|
||||||
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
|
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
|
||||||
InitData *pData = (InitData*)pInit;
|
InitData *pData = (InitData*)pInit;
|
||||||
int nErr = 0;
|
sqlite *db = pData->db;
|
||||||
|
int iDb;
|
||||||
|
|
||||||
assert( argc==5 );
|
assert( argc==4 );
|
||||||
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
|
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
|
||||||
if( argv[0]==0 ){
|
if( argv[1]==0 || argv[3]==0 ){
|
||||||
corruptSchema(pData, 0);
|
corruptSchema(pData, 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
switch( argv[0][0] ){
|
iDb = atoi(argv[3]);
|
||||||
case 'v':
|
assert( iDb>=0 && iDb<db->nDb );
|
||||||
case 'i':
|
if( argv[2] && argv[2][0] ){
|
||||||
case 't': { /* CREATE TABLE, CREATE INDEX, or CREATE VIEW statements */
|
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
|
||||||
sqlite *db = pData->db;
|
** But because db->init.busy is set to 1, no VDBE code is generated
|
||||||
if( argv[2]==0 || argv[4]==0 ){
|
** or executed. All the parser does is build the internal data
|
||||||
corruptSchema(pData, 0);
|
** structures that describe the table, index, or view.
|
||||||
return 1;
|
*/
|
||||||
}
|
char *zErr;
|
||||||
if( argv[3] && argv[3][0] ){
|
int rc;
|
||||||
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
|
assert( db->init.busy );
|
||||||
** But because db->init.busy is set to 1, no VDBE code is generated
|
db->init.iDb = iDb;
|
||||||
** or executed. All the parser does is build the internal data
|
db->init.newTnum = atoi(argv[1]);
|
||||||
** structures that describe the table, index, or view.
|
rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
|
||||||
*/
|
db->init.iDb = 0;
|
||||||
char *zErr;
|
if( SQLITE_OK!=rc ){
|
||||||
int rc;
|
corruptSchema(pData, zErr);
|
||||||
assert( db->init.busy );
|
sqlite3_free(zErr);
|
||||||
db->init.iDb = atoi(argv[4]);
|
return rc;
|
||||||
assert( db->init.iDb>=0 && db->init.iDb<db->nDb );
|
|
||||||
db->init.newTnum = atoi(argv[2]);
|
|
||||||
rc = sqlite3_exec(db, argv[3], 0, 0, &zErr);
|
|
||||||
db->init.iDb = 0;
|
|
||||||
if( SQLITE_OK!=rc ){
|
|
||||||
corruptSchema(pData, zErr);
|
|
||||||
sqlite3_free(zErr);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
/* If the SQL column is blank it means this is an index that
|
|
||||||
** was created to be the PRIMARY KEY or to fulfill a UNIQUE
|
|
||||||
** constraint for a CREATE TABLE. The index should have already
|
|
||||||
** been created when we processed the CREATE TABLE. All we have
|
|
||||||
** to do here is record the root page number for that index.
|
|
||||||
*/
|
|
||||||
int iDb;
|
|
||||||
Index *pIndex;
|
|
||||||
|
|
||||||
iDb = atoi(argv[4]);
|
|
||||||
assert( iDb>=0 && iDb<db->nDb );
|
|
||||||
pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zName);
|
|
||||||
if( pIndex==0 || pIndex->tnum!=0 ){
|
|
||||||
/* This can occur if there exists an index on a TEMP table which
|
|
||||||
** has the same name as another index on a permanent index. Since
|
|
||||||
** the permanent table is hidden by the TEMP table, we can also
|
|
||||||
** safely ignore the index on the permanent table.
|
|
||||||
*/
|
|
||||||
/* Do Nothing */;
|
|
||||||
}else{
|
|
||||||
pIndex->tnum = atoi(argv[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
}else{
|
||||||
default: {
|
/* If the SQL column is blank it means this is an index that
|
||||||
/* This can not happen! */
|
** was created to be the PRIMARY KEY or to fulfill a UNIQUE
|
||||||
nErr = 1;
|
** constraint for a CREATE TABLE. The index should have already
|
||||||
assert( nErr==0 );
|
** been created when we processed the CREATE TABLE. All we have
|
||||||
|
** to do here is record the root page number for that index.
|
||||||
|
*/
|
||||||
|
Index *pIndex;
|
||||||
|
pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName);
|
||||||
|
if( pIndex==0 || pIndex->tnum!=0 ){
|
||||||
|
/* This can occur if there exists an index on a TEMP table which
|
||||||
|
** has the same name as another index on a permanent index. Since
|
||||||
|
** the permanent table is hidden by the TEMP table, we can also
|
||||||
|
** safely ignore the index on the permanent table.
|
||||||
|
*/
|
||||||
|
/* Do Nothing */;
|
||||||
|
}else{
|
||||||
|
pIndex->tnum = atoi(argv[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nErr;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -147,7 +118,7 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
|
|||||||
BtCursor *curMain;
|
BtCursor *curMain;
|
||||||
int size;
|
int size;
|
||||||
Table *pTab;
|
Table *pTab;
|
||||||
char const *azArg[6];
|
char const *azArg[5];
|
||||||
char zDbNum[30];
|
char zDbNum[30];
|
||||||
int meta[10];
|
int meta[10];
|
||||||
InitData initData;
|
InitData initData;
|
||||||
@ -192,16 +163,15 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
|
|||||||
|
|
||||||
/* Construct the schema tables. */
|
/* Construct the schema tables. */
|
||||||
sqlite3SafetyOff(db);
|
sqlite3SafetyOff(db);
|
||||||
azArg[0] = "table";
|
azArg[0] = zMasterName;
|
||||||
azArg[1] = zMasterName;
|
azArg[1] = "1";
|
||||||
azArg[2] = "1";
|
azArg[2] = zMasterSchema;
|
||||||
azArg[3] = zMasterSchema;
|
|
||||||
sprintf(zDbNum, "%d", iDb);
|
sprintf(zDbNum, "%d", iDb);
|
||||||
azArg[4] = zDbNum;
|
azArg[3] = zDbNum;
|
||||||
azArg[5] = 0;
|
azArg[4] = 0;
|
||||||
initData.db = db;
|
initData.db = db;
|
||||||
initData.pzErrMsg = pzErrMsg;
|
initData.pzErrMsg = pzErrMsg;
|
||||||
rc = sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
|
rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
sqlite3SafetyOn(db);
|
sqlite3SafetyOn(db);
|
||||||
return rc;
|
return rc;
|
||||||
@ -304,14 +274,14 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
|
|||||||
/* For an empty database, there is nothing to read */
|
/* For an empty database, there is nothing to read */
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
}else{
|
}else{
|
||||||
char *zSql = 0;
|
char *zSql;
|
||||||
|
zSql = sqlite3MPrintf(
|
||||||
|
"SELECT name, rootpage, sql, %s FROM '%q'.%s",
|
||||||
|
zDbNum, db->aDb[iDb].zName, zMasterName);
|
||||||
sqlite3SafetyOff(db);
|
sqlite3SafetyOff(db);
|
||||||
sqlite3SetString(&zSql,
|
|
||||||
"SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
|
|
||||||
db->aDb[iDb].zName, "\".", zMasterName, (char*)0);
|
|
||||||
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
|
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
|
||||||
sqliteFree(zSql);
|
|
||||||
sqlite3SafetyOn(db);
|
sqlite3SafetyOn(db);
|
||||||
|
sqliteFree(zSql);
|
||||||
sqlite3BtreeCloseCursor(curMain);
|
sqlite3BtreeCloseCursor(curMain);
|
||||||
}
|
}
|
||||||
if( sqlite3_malloc_failed ){
|
if( sqlite3_malloc_failed ){
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.308 2004/07/22 15:02:25 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.309 2004/07/24 03:30:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@ -1159,6 +1159,16 @@ struct DbFixer {
|
|||||||
const Token *pName; /* Name of the container - used for error messages */
|
const Token *pName; /* Name of the container - used for error messages */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** A pointer to this structure is used to communicate information
|
||||||
|
** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
sqlite *db; /* The database being initialized */
|
||||||
|
char **pzErrMsg; /* Error message stored here */
|
||||||
|
} InitData;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This global flag is set for performance testing of triggers. When it is set
|
* This global flag is set for performance testing of triggers. When it is set
|
||||||
* SQLite will perform the overhead of building new and old trigger references
|
* SQLite will perform the overhead of building new and old trigger references
|
||||||
@ -1210,6 +1220,7 @@ void sqlite3ExprDelete(Expr*);
|
|||||||
ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
|
ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
|
||||||
void sqlite3ExprListDelete(ExprList*);
|
void sqlite3ExprListDelete(ExprList*);
|
||||||
int sqlite3Init(sqlite*, char**);
|
int sqlite3Init(sqlite*, char**);
|
||||||
|
int sqlite3InitCallback(void*, int, char**, char**);
|
||||||
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
|
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
|
||||||
void sqlite3ResetInternalSchema(sqlite*, int);
|
void sqlite3ResetInternalSchema(sqlite*, int);
|
||||||
void sqlite3BeginParse(Parse*,int);
|
void sqlite3BeginParse(Parse*,int);
|
||||||
|
@ -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.78 2004/06/18 06:02:35 danielk1977 Exp $
|
** $Id: tokenize.c,v 1.79 2004/07/24 03:30:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@ -431,6 +431,11 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
|||||||
sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
|
sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if( sqlite3OsFileExists("vdbe_sqltrace") ){
|
||||||
|
printf("SQL To Compiler: [%s]\n", zSql);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
pParse->sLastToken.dyn = 0;
|
pParse->sLastToken.dyn = 0;
|
||||||
pParse->zTail = zSql;
|
pParse->zTail = zSql;
|
||||||
while( sqlite3_malloc_failed==0 && zSql[i]!=0 ){
|
while( sqlite3_malloc_failed==0 && zSql[i]!=0 ){
|
||||||
@ -714,4 +719,3 @@ int sqlite3_complete16(const void *zSql){
|
|||||||
sqlite3ValueFree(pVal);
|
sqlite3ValueFree(pVal);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
54
src/vdbe.c
54
src/vdbe.c
@ -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.403 2004/07/21 02:53:30 drh Exp $
|
** $Id: vdbe.c,v 1.404 2004/07/24 03:30:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@ -3670,24 +3670,19 @@ case OP_Clear: {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: CreateTable * P2 P3
|
/* Opcode: CreateTable P1 * *
|
||||||
**
|
**
|
||||||
** Allocate a new table in the main database file if P2==0 or in the
|
** Allocate a new table in the main database file if P2==0 or in the
|
||||||
** auxiliary database file if P2==1. Push the page number
|
** auxiliary database file if P2==1. Push the page number
|
||||||
** for the root page of the new table onto the stack.
|
** for the root page of the new table onto the stack.
|
||||||
**
|
**
|
||||||
** The root page number is also written to a memory location that P3
|
|
||||||
** points to. This is the mechanism is used to write the root page
|
|
||||||
** number into the parser's internal data structures that describe the
|
|
||||||
** new table.
|
|
||||||
**
|
|
||||||
** The difference between a table and an index is this: A table must
|
** The difference between a table and an index is this: A table must
|
||||||
** have a 4-byte integer key and can have arbitrary data. An index
|
** have a 4-byte integer key and can have arbitrary data. An index
|
||||||
** has an arbitrary key but no data.
|
** has an arbitrary key but no data.
|
||||||
**
|
**
|
||||||
** See also: CreateIndex
|
** See also: CreateIndex
|
||||||
*/
|
*/
|
||||||
/* Opcode: CreateIndex * P2 P3
|
/* Opcode: CreateIndex P1 * *
|
||||||
**
|
**
|
||||||
** Allocate a new index in the main database file if P2==0 or in the
|
** Allocate a new index in the main database file if P2==0 or in the
|
||||||
** auxiliary database file if P2==1. Push the page number of the
|
** auxiliary database file if P2==1. Push the page number of the
|
||||||
@ -3699,28 +3694,59 @@ case OP_CreateIndex:
|
|||||||
case OP_CreateTable: {
|
case OP_CreateTable: {
|
||||||
int pgno;
|
int pgno;
|
||||||
int flags;
|
int flags;
|
||||||
assert( pOp->p3!=0 && pOp->p3type==P3_POINTER );
|
Db *pDb;
|
||||||
assert( pOp->p2>=0 && pOp->p2<db->nDb );
|
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||||
assert( db->aDb[pOp->p2].pBt!=0 );
|
pDb = &db->aDb[pOp->p1];
|
||||||
|
assert( pDb->pBt!=0 );
|
||||||
if( pOp->opcode==OP_CreateTable ){
|
if( pOp->opcode==OP_CreateTable ){
|
||||||
/* flags = BTREE_INTKEY; */
|
/* flags = BTREE_INTKEY; */
|
||||||
flags = BTREE_LEAFDATA|BTREE_INTKEY;
|
flags = BTREE_LEAFDATA|BTREE_INTKEY;
|
||||||
}else{
|
}else{
|
||||||
flags = BTREE_ZERODATA;
|
flags = BTREE_ZERODATA;
|
||||||
}
|
}
|
||||||
rc = sqlite3BtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno, flags);
|
rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
|
||||||
pTos++;
|
pTos++;
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
pTos->i = pgno;
|
pTos->i = pgno;
|
||||||
pTos->flags = MEM_Int;
|
pTos->flags = MEM_Int;
|
||||||
*(u32*)pOp->p3 = pgno;
|
|
||||||
pOp->p3 = 0;
|
|
||||||
}else{
|
}else{
|
||||||
pTos->flags = MEM_Null;
|
pTos->flags = MEM_Null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Opcode: ParseSchema P1 * P3
|
||||||
|
**
|
||||||
|
** Read and parse all entries from the SQLITE_MASTER table of database P1
|
||||||
|
** that match the WHERE clause P3.
|
||||||
|
**
|
||||||
|
** This opcode invokes the parser to create a new virtual machine,
|
||||||
|
** then runs the new virtual machine. It is thus a reentrant opcode.
|
||||||
|
*/
|
||||||
|
case OP_ParseSchema: {
|
||||||
|
char *zSql;
|
||||||
|
int iDb = pOp->p1;
|
||||||
|
const char *zMaster;
|
||||||
|
InitData initData;
|
||||||
|
|
||||||
|
assert( iDb>=0 && iDb<db->nDb );
|
||||||
|
zMaster = iDb==1 ? TEMP_MASTER_NAME : MASTER_NAME;
|
||||||
|
initData.db = db;
|
||||||
|
initData.pzErrMsg = &p->zErrMsg;
|
||||||
|
zSql = sqlite3MPrintf(
|
||||||
|
"SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
|
||||||
|
pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
|
||||||
|
sqlite3SafetyOff(db);
|
||||||
|
assert( db->init.busy==0 );
|
||||||
|
db->init.busy = 1;
|
||||||
|
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
|
||||||
|
db->init.busy = 0;
|
||||||
|
sqlite3SafetyOn(db);
|
||||||
|
sqliteFree(zSql);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Opcode: IntegrityCk * P2 *
|
/* Opcode: IntegrityCk * P2 *
|
||||||
**
|
**
|
||||||
** Do an analysis of the currently open database. Push onto the
|
** Do an analysis of the currently open database. Push onto the
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
# This file implements tests for miscellanous features that were
|
# This file implements tests for miscellanous features that were
|
||||||
# left out of other test files.
|
# left out of other test files.
|
||||||
#
|
#
|
||||||
# $Id: misc4.test,v 1.3 2004/07/19 17:25:25 drh Exp $
|
# $Id: misc4.test,v 1.4 2004/07/24 03:30:49 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -54,4 +54,29 @@ do_test misc4-1.3 {
|
|||||||
sqlite3_finalize $stmt
|
sqlite3_finalize $stmt
|
||||||
} {SQLITE_SCHEMA}
|
} {SQLITE_SCHEMA}
|
||||||
|
|
||||||
|
# Prepare but do not execute various CREATE statements. Then before
|
||||||
|
# those statements are executed, try to use the tables, indices, views,
|
||||||
|
# are triggers that were created.
|
||||||
|
#
|
||||||
|
if 0 {
|
||||||
|
do_test misc4-2.1 {
|
||||||
|
set stmt [sqlite3_prepare $DB {CREATE TABLE t3(x);} -1 TAIL]
|
||||||
|
catchsql {
|
||||||
|
pragma vdbe_trace=on;
|
||||||
|
INSERT INTO t3 VALUES(1);
|
||||||
|
}
|
||||||
|
} {1 {no such table: t3}}
|
||||||
|
do_test misc4-2.2 {
|
||||||
|
sqlite3_step $stmt
|
||||||
|
} SQLITE_DONE
|
||||||
|
do_test misc4-2.3 {
|
||||||
|
sqlite3_finalize $stmt
|
||||||
|
} SQLITE_OK
|
||||||
|
do_test misc4-2.4 {
|
||||||
|
catchsql {
|
||||||
|
INSERT INTO t3 VALUES(1);
|
||||||
|
}
|
||||||
|
} {0 {}}
|
||||||
|
}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing the CREATE TABLE statement.
|
# focus of this file is testing the CREATE TABLE statement.
|
||||||
#
|
#
|
||||||
# $Id: table.test,v 1.28 2004/06/21 07:36:33 danielk1977 Exp $
|
# $Id: table.test,v 1.29 2004/07/24 03:30:49 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -316,39 +316,39 @@ do_test table-8.1.1 {
|
|||||||
SELECT sql FROM sqlite_master WHERE name='t2';
|
SELECT sql FROM sqlite_master WHERE name='t2';
|
||||||
}
|
}
|
||||||
} {{CREATE TABLE t2(
|
} {{CREATE TABLE t2(
|
||||||
'desc' text,
|
"desc" text,
|
||||||
'asc' text,
|
"asc" text,
|
||||||
'explain' int,
|
"explain" int,
|
||||||
'14_vac' boolean,
|
"14_vac" boolean,
|
||||||
fuzzy_dog_12 varchar(10),
|
fuzzy_dog_12 varchar(10),
|
||||||
'begin' blob,
|
"begin" blob,
|
||||||
'end' clob
|
"end" clob
|
||||||
)}}
|
)}}
|
||||||
do_test table-8.2 {
|
do_test table-8.2 {
|
||||||
execsql {
|
execsql {
|
||||||
CREATE TABLE 't3''xyz'(a,b,c);
|
CREATE TABLE "t3""xyz"(a,b,c);
|
||||||
INSERT INTO [t3'xyz] VALUES(1,2,3);
|
INSERT INTO [t3"xyz] VALUES(1,2,3);
|
||||||
SELECT * FROM [t3'xyz];
|
SELECT * FROM [t3"xyz];
|
||||||
}
|
}
|
||||||
} {1 2 3}
|
} {1 2 3}
|
||||||
do_test table-8.3 {
|
do_test table-8.3 {
|
||||||
execsql2 {
|
execsql2 {
|
||||||
CREATE TABLE [t4'abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3'xyz];
|
CREATE TABLE [t4"abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3"xyz];
|
||||||
SELECT * FROM [t4'abc];
|
SELECT * FROM [t4"abc];
|
||||||
}
|
}
|
||||||
} {cnt 1 max(b+c) 5}
|
} {cnt 1 max(b+c) 5}
|
||||||
|
|
||||||
# Update for v3: The declaration type of anything except a column is now a
|
# Update for v3: The declaration type of anything except a column is now a
|
||||||
# NULL pointer, so the created table has no column types. (Changed result
|
# NULL pointer, so the created table has no column types. (Changed result
|
||||||
# from {{CREATE TABLE 't4''abc'(cnt NUMERIC,'max(b+c)' NUMERIC)}}).
|
# from {{CREATE TABLE 't4"abc'(cnt NUMERIC,"max(b+c)" NUMERIC)}}).
|
||||||
do_test table-8.3.1 {
|
do_test table-8.3.1 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT sql FROM sqlite_master WHERE name='t4''abc'
|
SELECT sql FROM sqlite_master WHERE name='t4"abc'
|
||||||
}
|
}
|
||||||
} {{CREATE TABLE 't4''abc'(cnt,'max(b+c)')}}
|
} {{CREATE TABLE "t4""abc"(cnt,"max(b+c)")}}
|
||||||
do_test table-8.4 {
|
do_test table-8.4 {
|
||||||
execsql2 {
|
execsql2 {
|
||||||
CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3'xyz];
|
CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3"xyz];
|
||||||
SELECT * FROM t5;
|
SELECT * FROM t5;
|
||||||
}
|
}
|
||||||
} {y'all 1}
|
} {y'all 1}
|
||||||
@ -356,7 +356,7 @@ do_test table-8.5 {
|
|||||||
db close
|
db close
|
||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
execsql2 {
|
execsql2 {
|
||||||
SELECT * FROM [t4'abc];
|
SELECT * FROM [t4"abc];
|
||||||
}
|
}
|
||||||
} {cnt 1 max(b+c) 5}
|
} {cnt 1 max(b+c) 5}
|
||||||
do_test table-8.6 {
|
do_test table-8.6 {
|
||||||
@ -520,5 +520,3 @@ do_test table-12.2 {
|
|||||||
} {{CREATE TABLE t8(b number(5,10),h,i integer,j BLOB)}}
|
} {{CREATE TABLE t8(b number(5,10),h,i integer,j BLOB)}}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user