From b421b894e0889fd0e573c5c541d7643c30ba5290 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 28 Jan 2012 19:41:53 +0000 Subject: [PATCH] Add support for IF NOT EXISTS on CREATE VIRTUAL TABLE. FossilOrigin-Name: 230983e86a897caa91a487ef2d4c1c7fb7c79f10 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/parse.y | 5 +++-- src/sqliteInt.h | 2 +- src/vtab.c | 7 ++++--- test/vtab1.test | 35 ++++++++++++++++++++++++++++++----- 6 files changed, 48 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 63af2fc92f..a7d7bcb3c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sversion\snumber\sto\s3.7.11\sand\srerun\sautoconf. -D 2012-01-28T15:26:27.652 +C Add\ssupport\sfor\sIF\sNOT\sEXISTS\son\sCREATE\sVIRTUAL\sTABLE. +D 2012-01-28T19:41:53.964 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -170,7 +170,7 @@ F src/os_unix.c 657672fab2580a84116c140b36ee3d6b6fc75b4e F src/os_win.c 5ac061ae1326a71500cee578ed0fd9113b4f6a37 F src/pager.c 2d892f7b901a8867a33bc21742086165a3a99af8 F src/pager.h a435da8421dc7844b7f9c7f37b636c160c50208a -F src/parse.y 203ea3305abf7441ec55dde8714246fc87dff981 +F src/parse.y fcda1cc4bcb6152759285a1da0c76db40def8650 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h b1d8775a9bddf44e65edb0d20bfc57a4982f840f F src/pcache1.c 281822d22265245b19f908cb3f5df725f7e11b06 @@ -184,7 +184,7 @@ F src/select.c 1ad267692ab09afe05092eddcb5aba96b796afe1 F src/shell.c f492df9fc2de27e4700ecbaa948729fc47af88d7 F src/sqlite.h.in 53516617d2945a411d028674d7fa20dd394b9ec0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h ee35c21bb13099df24b3675eabb0ff820213ed9d +F src/sqliteInt.h 005e7da944fdb8c2b7883ebb345caf3835c1e162 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -249,7 +249,7 @@ F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 3c171040c28a95084fb5024ab731140a86fd5439 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 -F src/vtab.c e9318d88feac85be8e27ee783ac8f5397933fc8a +F src/vtab.c ab90fb600a3f5e4b7c48d22a4cdb2d6b23239847 F src/wal.c 5f7bcc0610af759953defd769eacebfd98a22bc8 F src/wal.h eaa00b9a403ddda2b56d01b7afc19ef600f9363f F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f @@ -886,7 +886,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 7701bb609fe8bf6535514e8b849a309e8f00573b F test/view.test b182a67ec43f490b156b5a710827a341be83dd17 -F test/vtab1.test 12fbb309ce830c4064e44f275eb02a65c2780076 +F test/vtab1.test 17d0db1096b603a357f943a9dcbdc3e30c6f04f2 F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1 F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275 @@ -988,7 +988,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P eb3b6a0ceb8bfb9fd59ff5fec420f863a9b5c4e4 -R 934943e42a60a1f66e407e179ff30164 +P 6f9b265dd099928208022f4006c93173a3c0b1c8 +R 56430bb5efcddc94e7a06c2adc4c5844 U drh -Z 84eb0b66b94876f295c8a9280ca63106 +Z fff0b31769982710fff0c154a3894bb9 diff --git a/manifest.uuid b/manifest.uuid index 6e8d301c56..bae97e026e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f9b265dd099928208022f4006c93173a3c0b1c8 \ No newline at end of file +230983e86a897caa91a487ef2d4c1c7fb7c79f10 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index d0f5f4152f..3bdf3f0084 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1390,8 +1390,9 @@ kwcolumn_opt ::= COLUMNKW. %ifndef SQLITE_OMIT_VIRTUALTABLE cmd ::= create_vtab. {sqlite3VtabFinishParse(pParse,0);} cmd ::= create_vtab LP vtabarglist RP(X). {sqlite3VtabFinishParse(pParse,&X);} -create_vtab ::= createkw VIRTUAL TABLE nm(X) dbnm(Y) USING nm(Z). { - sqlite3VtabBeginParse(pParse, &X, &Y, &Z); +create_vtab ::= createkw VIRTUAL TABLE ifnotexists(E) + nm(X) dbnm(Y) USING nm(Z). { + sqlite3VtabBeginParse(pParse, &X, &Y, &Z, E); } vtabarglist ::= vtabarg. vtabarglist ::= vtabarglist COMMA vtabarg. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f084f55c24..109737dee4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3127,7 +3127,7 @@ void sqlite3AutoLoadExtensions(sqlite3*); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif void sqlite3VtabMakeWritable(Parse*,Table*); -void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*); +void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int); void sqlite3VtabFinishParse(Parse*, Token*); void sqlite3VtabArgInit(Parse*); void sqlite3VtabArgExtend(Parse*, Token*); diff --git a/src/vtab.c b/src/vtab.c index 8119cb5511..c7221cd3b7 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -278,13 +278,14 @@ void sqlite3VtabBeginParse( Parse *pParse, /* Parsing context */ Token *pName1, /* Name of new table, or database name */ Token *pName2, /* Name of new table or NULL */ - Token *pModuleName /* Name of the module for the virtual table */ + Token *pModuleName, /* Name of the module for the virtual table */ + int ifNotExists /* No error if the table already exists */ ){ int iDb; /* The database the table is being created in */ Table *pTable; /* The new virtual table */ sqlite3 *db; /* Database connection */ - sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0); + sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists); pTable = pParse->pNewTable; if( pTable==0 ) return; assert( 0==pTable->pIndex ); @@ -319,7 +320,7 @@ void sqlite3VtabBeginParse( ** virtual table currently under construction in pParse->pTable. */ static void addArgumentToVtab(Parse *pParse){ - if( pParse->sArg.z && ALWAYS(pParse->pNewTable) ){ + if( pParse->sArg.z && pParse->pNewTable ){ const char *z = (const char*)pParse->sArg.z; int n = pParse->sArg.n; sqlite3 *db = pParse->db; diff --git a/test/vtab1.test b/test/vtab1.test index 16f1b4389c..f056b2f368 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -51,7 +51,7 @@ ifcapable !vtab||!schema_pragmas { # We cannot create a virtual table if the module has not been registered. # -do_test vtab1-1.1 { +do_test vtab1-1.1.1 { explain { CREATE VIRTUAL TABLE t1 USING echo; } @@ -59,6 +59,11 @@ do_test vtab1-1.1 { CREATE VIRTUAL TABLE t1 USING echo; } } {1 {no such module: echo}} +do_test vtab1-1.1.2 { + catchsql { + CREATE VIRTUAL TABLE IF NOT EXISTS t1 USING echo; + } +} {1 {no such module: echo}} do_test vtab1-1.2 { execsql { SELECT name FROM sqlite_master ORDER BY 1 @@ -75,11 +80,16 @@ register_echo_module [sqlite3_connection_pointer db] # The "echo" module does not invoke sqlite3_declare_vtab() if it is # passed zero arguments. # -do_test vtab1-1.3 { +do_test vtab1-1.3.1 { catchsql { CREATE VIRTUAL TABLE t1 USING echo; } } {1 {vtable constructor did not declare schema: t1}} +do_test vtab1-1.3.2 { + catchsql { + CREATE VIRTUAL TABLE IF NOT EXISTS t1 USING echo; + } +} {1 {vtable constructor did not declare schema: t1}} do_test vtab1-1.4 { execsql { SELECT name FROM sqlite_master ORDER BY 1 @@ -90,11 +100,16 @@ do_test vtab1-1.4 { # the virtual table if it is passed an argument that does not correspond # to an existing real table in the same database. # -do_test vtab1-1.5 { +do_test vtab1-1.5.1 { catchsql { CREATE VIRTUAL TABLE t1 USING echo(no_such_table); } } {1 {vtable constructor failed: t1}} +do_test vtab1-1.5.2 { + catchsql { + CREATE VIRTUAL TABLE IF NOT EXISTS t1 USING echo(no_such_table); + } +} {1 {vtable constructor failed: t1}} do_test vtab1-1.6 { execsql { SELECT name FROM sqlite_master ORDER BY 1 @@ -128,17 +143,27 @@ do_test vtab-1.2152.4 { # select an illegal table-name (i.e a reserved name or the name of a # table that already exists). # -do_test vtab1-1.7 { +do_test vtab1-1.7.1 { catchsql { CREATE VIRTUAL TABLE sqlite_master USING echo; } } {1 {object name reserved for internal use: sqlite_master}} -do_test vtab1-1.8 { +do_test vtab1-1.7.2 { + catchsql { + CREATE VIRTUAL TABLE IF NOT EXISTS sqlite_master USING echo; + } +} {1 {object name reserved for internal use: sqlite_master}} +do_test vtab1-1.8.1 { catchsql { CREATE TABLE treal(a, b, c); CREATE VIRTUAL TABLE treal USING echo(treal); } } {1 {table treal already exists}} +do_test vtab1-1.8.2 { + catchsql { + CREATE VIRTUAL TABLE IF NOT EXISTS treal USING echo(treal); + } +} {0 {}} do_test vtab1-1.9 { execsql { DROP TABLE treal;