From: drh Date: Wed, 4 Jan 2006 15:54:36 +0000 (+0000) Subject: Add support for CREATE INDEX IF NOT EXISTS and DROP INDEX IF EXISTS. (CVS 2855) X-Git-Tag: version-3.6.10~3312 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4d91a701bd0daef78d60bf780e5e25b6f4e44605;p=thirdparty%2Fsqlite.git Add support for CREATE INDEX IF NOT EXISTS and DROP INDEX IF EXISTS. (CVS 2855) FossilOrigin-Name: 551cdd6c309e75687abaeac5381b794cd5e4c10a --- diff --git a/manifest b/manifest index 365047851b..8f8a53e37e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\scase\s0\sto\s(char*)\son\svarargs\sfunctions.\s\sOtherwise\sthere\sare\sproblems\non\s64-bit\smachines.\s(CVS\s2854) -D 2006-01-03T15:16:26 +C Add\ssupport\sfor\sCREATE\sINDEX\sIF\sNOT\sEXISTS\sand\sDROP\sINDEX\sIF\sEXISTS.\s(CVS\s2855) +D 2006-01-04T15:54:36 F Makefile.in e3c6b3a38d734d41574c04f2fc90d18de2b87102 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -36,7 +36,7 @@ F src/attach.c 07822dbd2dcf6de548aba6cb24142aec800fa3b6 F src/auth.c 31e2304bef67f44d635655f44234387ea7d21454 F src/btree.c ec89192ceeae9343c5d8f2564b8c9b8c958e6bfc F src/btree.h d6481f9253f0b5fa40b35da4b93a54d0f9c5f9f2 -F src/build.c bb4c9df2583246728167659d401fd75aa3d9997f +F src/build.c 6bf007d0da0527820329d5695c90e1042bef1e58 F src/callback.c 62066afd516f220575e81b1a1239ab92a2eae252 F src/complete.c df1681cef40dec33a286006981845f87b194e7a4 F src/date.c bb079317bff6a2b78aba5c0d2ddae5f6f03acfb7 @@ -61,15 +61,15 @@ F src/os_win.c 7e2d09f81cb83709b9774ac6be80fa3cb08ac86d F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c 681b4e39d581ead8fd54283176138bec924a4bae F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f -F src/parse.y fea607bdc0f4440e001ca277a49f507b5a3fb1e5 +F src/parse.y 58258759fabdd48f1d2561e276097290b1ea2680 F src/pragma.c 8883b4d34796efa315bdd0ec1b03f580ef1575b9 -F src/prepare.c 1f2bf83038792294ef4a307d95993f90e6c70561 +F src/prepare.c 7639314c504f602d87730238c44ccddc4407ac60 F src/printf.c f47a2f4b5387cd2ebb12e9117a1a5d6bd9a2b812 F src/random.c ff5e9a8cad790e2a51cd4d2e7737dc8540e09d1d F src/select.c 5b0ccd6688e61c0720efa45075a3f9da60180554 F src/shell.c 66b073375efbdee19045e7e0cd38b85f9aff71da F src/sqlite.h.in ba3a29daa6a16e054191ccb384a981964e882a1d -F src/sqliteInt.h bb648c5274d67060cb13f0cd0da141aff1205358 +F src/sqliteInt.h a9b187e8621cd3c20c7ef6c0716d77cbed716d4d F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316 F src/tclsqlite.c 124f822d6c55c5d95420672bf39fe3ba60ae1f76 F src/test1.c 988dbac66c3ca92d69fbe0283d77e86cd6f73ce8 @@ -160,7 +160,7 @@ F test/fkey1.test 153004438d51e6769fb1ce165f6313972d6263ce F test/func.test a7119afcc16abdf24b24486684fb888279008f75 F test/hook.test 3bae7892e04ba40f20e205027c3ba343e46d22ff F test/in.test cead6165aebbe0d451bb2263a307173acfeb6240 -F test/index.test 3871c47ec475f779f0b99dc36a3d177951995712 +F test/index.test c90ab389586dbddfeb6817cd137737b2de1b6522 F test/index2.test 9ad98243fd7fe833795a9cc662f371f0eed4ff4f F test/index3.test f66718cd92ce1216819d47e6a156755e4b2c4ca1 F test/insert.test b0a89e1568fe9890758f8f2b43b68e840e8f1a1a @@ -335,7 +335,7 @@ F www/tclsqlite.tcl ddcf912ea48695603c8ed7efb29f0812ef8d1b49 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 7c3492c8404c39c808af4429b4fcdb7413539ab3 -R ce1d0ff632d7208d0510c9231ee127d4 +P 837dc77ff9f5271b7e1bb8602fc021670c7802d1 +R ec161a22b551e019c6b2c8761d7b0084 U drh -Z 420d480c90c636c6935ddb788f609c13 +Z 4a9af6bfc70464e631ff856496627e88 diff --git a/manifest.uuid b/manifest.uuid index 29dcb162aa..8ed490b083 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -837dc77ff9f5271b7e1bb8602fc021670c7802d1 \ No newline at end of file +551cdd6c309e75687abaeac5381b794cd5e4c10a \ No newline at end of file diff --git a/src/build.c b/src/build.c index 655fee5439..48cebe4272 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.364 2005/12/29 23:33:54 drh Exp $ +** $Id: build.c,v 1.365 2006/01/04 15:54:36 drh Exp $ */ #include "sqliteInt.h" #include @@ -1056,7 +1056,7 @@ void sqlite3AddPrimaryKey( "INTEGER PRIMARY KEY"); #endif }else{ - sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder); + sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0); pList = 0; } @@ -2105,7 +2105,8 @@ void sqlite3CreateIndex( int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */ Token *pEnd, /* The ")" that closes the CREATE INDEX statement */ - int sortOrder /* Sort order of primary key when pList==NULL */ + int sortOrder, /* Sort order of primary key when pList==NULL */ + int ifNotExist /* Omit error if index already exists */ ){ Table *pTab = 0; /* Table to be indexed */ Index *pIndex = 0; /* The index to be created */ @@ -2199,7 +2200,9 @@ void sqlite3CreateIndex( if( !db->init.busy ){ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index; if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){ - sqlite3ErrorMsg(pParse, "index %s already exists", zName); + if( !ifNotExist ){ + sqlite3ErrorMsg(pParse, "index %s already exists", zName); + } goto exit_create_index; } if( sqlite3FindTable(db, zName, 0)!=0 ){ @@ -2525,7 +2528,7 @@ void sqlite3DefaultRowEst(Index *pIdx){ ** This routine will drop an existing named index. This routine ** implements the DROP INDEX statement. */ -void sqlite3DropIndex(Parse *pParse, SrcList *pName){ +void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ Index *pIndex; Vdbe *v; sqlite3 *db = pParse->db; @@ -2539,7 +2542,9 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){ } pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); if( pIndex==0 ){ - sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); + if( !ifExists ){ + sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); + } pParse->checkSchema = 1; goto exit_drop_index; } diff --git a/src/parse.y b/src/parse.y index 13005756bb..e7d13e8655 100644 --- a/src/parse.y +++ b/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.190 2005/12/29 23:33:54 drh Exp $ +** @(#) $Id: parse.y,v 1.191 2006/01/04 15:54:36 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" @@ -262,7 +262,7 @@ ccons ::= NULL onconf. ccons ::= NOT NULL onconf(R). {sqlite3AddNotNull(pParse, R);} ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I). {sqlite3AddPrimaryKey(pParse,0,R,I,Z);} -ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0);} +ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0);} ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X);} ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R). {sqlite3CreateForeignKey(pParse,0,&T,TA,R);} @@ -312,7 +312,7 @@ tcons ::= CONSTRAINT nm. tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R). {sqlite3AddPrimaryKey(pParse,X,R,I,0);} tcons ::= UNIQUE LP idxlist(X) RP onconf(R). - {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0);} + {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0);} tcons ::= CHECK LP expr(E) RP onconf. {sqlite3AddCheckConstraint(pParse,E);} tcons ::= FOREIGN KEY LP idxlist(FA) RP REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). { @@ -836,12 +836,12 @@ expritem(A) ::= . {A = 0;} ///////////////////////////// The CREATE INDEX command /////////////////////// // -cmd ::= CREATE(S) uniqueflag(U) INDEX nm(X) dbnm(D) +cmd ::= CREATE(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D) ON nm(Y) LP idxlist(Z) RP(E) onconf(R). { if( U!=OE_None ) U = R; if( U==OE_Default) U = OE_Abort; sqlite3CreateIndex(pParse, &X, &D, sqlite3SrcListAppend(0,&Y,0), Z, U, - &S, &E, SQLITE_SO_ASC); + &S, &E, SQLITE_SO_ASC, NE); } %type uniqueflag {int} @@ -879,7 +879,7 @@ idxitem(A) ::= nm(X). {A = X;} ///////////////////////////// The DROP INDEX command ///////////////////////// // -cmd ::= DROP INDEX fullname(X). {sqlite3DropIndex(pParse, X);} +cmd ::= DROP INDEX ifexists(E) fullname(X). {sqlite3DropIndex(pParse, X, E);} ///////////////////////////// The VACUUM command ///////////////////////////// // diff --git a/src/prepare.c b/src/prepare.c index 164c4149e9..1510b344e2 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.11 2005/12/29 19:23:07 drh Exp $ +** $Id: prepare.c,v 1.12 2006/01/04 15:54:36 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -433,7 +433,7 @@ int sqlite3_prepare( sParse.rc = SQLITE_NOMEM; } if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; - if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){ + if( sParse.checkSchema && !schemaIsValid(db) ){ sParse.rc = SQLITE_SCHEMA; } if( sParse.rc==SQLITE_SCHEMA ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f735aa408d..7c30a5eecc 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.446 2005/12/30 16:28:02 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.447 2006/01/04 15:54:36 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1516,8 +1516,8 @@ void sqlite3SrcListAssignCursors(Parse*, SrcList*); void sqlite3IdListDelete(IdList*); void sqlite3SrcListDelete(SrcList*); void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, - Token*, int); -void sqlite3DropIndex(Parse*, SrcList*); + Token*, int, int); +void sqlite3DropIndex(Parse*, SrcList*, int); void sqlite3AddKeyType(Vdbe*, ExprList*); void sqlite3AddIdxKeyType(Vdbe*, Index*); int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*, char *aff); diff --git a/test/index.test b/test/index.test index 539a04eab5..27c419cf61 100644 --- a/test/index.test +++ b/test/index.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE INDEX statement. # -# $Id: index.test,v 1.39 2005/11/14 22:29:06 drh Exp $ +# $Id: index.test,v 1.40 2006/01/04 15:54:37 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -185,6 +185,9 @@ do_test index-6.1 { do_test index-6.1b { execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name} } {index1 test1 test2} +do_test index-6.1c { + catchsql {CREATE INDEX IF NOT EXISTS index1 ON test1(f1)} +} {0 {}} do_test index-6.2 { set v [catch {execsql {CREATE INDEX test1 ON test2(g1)}} msg] lappend v $msg @@ -589,6 +592,17 @@ do_test index-17.2 { DROP INDEX sqlite_autoindex_t7_1; } } {1 {index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped}} +do_test index-17.3 { + catchsql { + DROP INDEX IF EXISTS sqlite_autoindex_t7_1; + } +} {1 {index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped}} +do_test index-17.4 { + catchsql { + DROP INDEX IF EXISTS no_such_index; + } +} {0 {}} + # The following tests ensure that it is not possible to explicitly name # a schema object with a name beginning with "sqlite_". Granted that is a