Add support for CREATE INDEX IF NOT EXISTS and DROP INDEX IF EXISTS. (CVS 2855)
FossilOrigin-Name: 551cdd6c309e75687abaeac5381b794cd5e4c10a
This commit is contained in:
parent
f93339decb
commit
4d91a701bd
20
manifest
20
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
|
||||
|
@ -1 +1 @@
|
||||
837dc77ff9f5271b7e1bb8602fc021670c7802d1
|
||||
551cdd6c309e75687abaeac5381b794cd5e4c10a
|
17
src/build.c
17
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 <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;
|
||||
}
|
||||
|
12
src/parse.y
12
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 /////////////////////////////
|
||||
//
|
||||
|
@ -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 ){
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user