]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add support for CREATE INDEX IF NOT EXISTS and DROP INDEX IF EXISTS. (CVS 2855)
authordrh <drh@noemail.net>
Wed, 4 Jan 2006 15:54:36 +0000 (15:54 +0000)
committerdrh <drh@noemail.net>
Wed, 4 Jan 2006 15:54:36 +0000 (15:54 +0000)
FossilOrigin-Name: 551cdd6c309e75687abaeac5381b794cd5e4c10a

manifest
manifest.uuid
src/build.c
src/parse.y
src/prepare.c
src/sqliteInt.h
test/index.test

index 365047851bc5c5f1839ea8a721c2097fa78b2b1f..8f8a53e37ec4a1b573993b0f729f1ac934bb608d 100644 (file)
--- 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
index 29dcb162aa9d39747ca8eef742ec1da233210909..8ed490b0836235a98d98508d3f3cc7222a647415 100644 (file)
@@ -1 +1 @@
-837dc77ff9f5271b7e1bb8602fc021670c7802d1
\ No newline at end of file
+551cdd6c309e75687abaeac5381b794cd5e4c10a
\ No newline at end of file
index 655fee5439fcc88587550c57fdeff2c35c0c4aa1..48cebe427245258d9daebf2b07083e91fe14df25 100644 (file)
@@ -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 <ctype.h>
@@ -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;
   }
index 13005756bbe9a9495d99deacc4e7b0f4ae80ba3b..e7d13e86558ab786610cfd94821308b7748729c7 100644 (file)
@@ -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 /////////////////////////////
 //
index 164c4149e996cf652d008910c00656eeaec87f3c..1510b344e208c55e3a11c70d3347d6b3bc5115bf 100644 (file)
@@ -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 ){
index f735aa408d7acca06977c3b8d3dfb2d69a49a0dc..7c30a5eeccbe72920c6d9b58d52622c30ecbb1f1 100644 (file)
@@ -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);
index 539a04eab57ac8d02626b45e79c5c8031a7d119b..27c419cf613fd453f9771e4dd09d9515008c46aa 100644 (file)
@@ -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