From: dan Date: Mon, 28 Jun 2010 10:15:19 +0000 (+0000) Subject: Currently, if SQLite cannot find a table or index referred to by a query, it reloads... X-Git-Tag: version-3.7.2~219 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1db95106ee48da9743f2d64bf1fdf7ba6d1442ed;p=thirdparty%2Fsqlite.git Currently, if SQLite cannot find a table or index referred to by a query, it reloads the database schema from disk to see if the table or index has been added since the schema was cached in memory. Extend this behaviour to columns (which may have been added using ALTER TABLE) and fix some obscure cases related to tables and indexes (INDEXED BY, DROP TABLE etc.). FossilOrigin-Name: 4932f22848b3d15a2b6dc5fa2cd69ce19182e2a4 --- diff --git a/manifest b/manifest index 0ad9732351..44277cd841 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Make\swalIndexTryHdr()\sa\sprivate\sfunction.\s\sFix\san\sissue\swith\sSQLITE_MUTEX_NOOP. -D 2010-06-26T22:16:03 +C Currently,\sif\sSQLite\scannot\sfind\sa\stable\sor\sindex\sreferred\sto\sby\sa\squery,\sit\sreloads\sthe\sdatabase\sschema\sfrom\sdisk\sto\ssee\sif\sthe\stable\sor\sindex\shas\sbeen\sadded\ssince\sthe\sschema\swas\scached\sin\smemory.\sExtend\sthis\sbehaviour\sto\scolumns\s(which\smay\shave\sbeen\sadded\susing\sALTER\sTABLE)\sand\sfix\ssome\sobscure\scases\srelated\sto\stables\sand\sindexes\s(INDEXED\sBY,\sDROP\sTABLE\setc.). +D 2010-06-28T10:15:20 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -119,7 +116,7 @@ F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff F src/btree.c 9806fb4030d0af907cf5cd7d4b9c8fd939eccfef F src/btree.h dd83041eda10c17daf023257c1fc883b5f71f85a F src/btreeInt.h b0c87f6725b06a0aa194a6d25d54b16ce9d6e291 -F src/build.c 9d48f4023d5e3d0a6807f1f531d8d7187d252c57 +F src/build.c 31830208adbd6f97bef2517531ed70954a306fde F src/callback.c 01843bdf4b0420fd28046525d150fcd9802931a9 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 51553a859994d01d8bf3500747f66a890c459774 @@ -133,7 +130,7 @@ F src/global.c 3fedfe02f1b2b1f6118455c881d132b804a1f0a7 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 3a9567687f6b84ab9a41448e3d2ce20424f4743c +F src/insert.c d9476f23f85a20eea3cc25a4b9f9cbae77a33bf2 F src/journal.c b0ea6b70b532961118ab70301c00a33089f9315c F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e @@ -169,9 +166,9 @@ F src/pragma.c 423865323a4074f1e0d4ab02af0be014653e8863 F src/prepare.c fd1398cb1da54385ba5bd68d93928f10d10a1d9c F src/printf.c 5f5b65a83e63f2096a541a340722a509fa0240a7 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 -F src/resolve.c ac5f1a713cd1ae77f08b83cc69581e11bf5ae6f9 +F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c c03d8a0565febcde8c6a12c5d77d065fddae889b +F src/select.c 4903ff1bbd08b55cbce00ea43c645530de41b362 F src/shell.c fd4ccdb37c3b68de0623eb938a649e0990710714 F src/sqlite.h.in 301476d8556cbb1c5d4bc906370b2dafe4d98a44 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89 @@ -215,8 +212,8 @@ F src/test_thread.c aa9919c885a1fe53eafc73492f0898ee6c0a0726 F src/test_vfs.c 90d51963dfe2aa28a9408b461cb06f48921be8e8 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb -F src/trigger.c 8927588cb9e6d47f933b53bfe74200fbb504100d -F src/update.c 9859f2056c7739a1db0d9774ccb6c2f0cee6d1de +F src/trigger.c 67e95c76d625b92d43409ace771c8e0d02a09ac2 +F src/update.c 19c899c23cd29fd102c9068e0b0ff5b087204beb F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c 32aebf04c10e51ad3977a928b7416bed671b620b F src/vacuum.c 241a8386727c1497eba4955933356dfba6ff8c9f @@ -569,6 +566,7 @@ F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd F test/savepoint6.test 76d3948568b2cdc0c13a671cadcae75009b183d6 F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 +F test/schema3.test 5d0e3b93bd56dd70be3ca340871cdbe74f812de3 F test/securedel.test 328d2921c0ca49bdd3352e516b0377fc07143254 F test/select1.test f67ca2dfc05df41c7b86eb32ca409b427a5f43b0 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 @@ -830,14 +828,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e82d008eaffb5522080cad6c69c1b194b78eadbd -R 4571797951f4ab0ab98573ca3fe9c307 -U drh -Z bf87b4bd0a568f47cbc6bbfb396cf7d8 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFMJnwmoxKgR168RlERAnB3AJ9WmFDjS4Mogutm6tqMf4TXdZMPZQCfcfy3 -WxCV4jYOGkRTKW5Witg+E/w= -=dfOb ------END PGP SIGNATURE----- +P ec65bbd06bdd3bf16a742c5bb1fab0dce756c01a +R b9e500f7ddaf53f7185bc0d73d249ff0 +U dan +Z cda19ee0469f27bd539b5c60bd39f17a diff --git a/manifest.uuid b/manifest.uuid index 82e2669eb7..508623b288 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec65bbd06bdd3bf16a742c5bb1fab0dce756c01a \ No newline at end of file +4932f22848b3d15a2b6dc5fa2cd69ce19182e2a4 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 4c00e398e2..ce3e614843 100644 --- a/src/build.c +++ b/src/build.c @@ -2614,6 +2614,7 @@ Index *sqlite3CreateIndex( if( j>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "table %s has no column named %s", pTab->zName, zColName); + pParse->checkSchema = 1; goto exit_create_index; } pIndex->aiColumn[i] = j; diff --git a/src/insert.c b/src/insert.c index 05964f849f..f6ad5ab9eb 100644 --- a/src/insert.c +++ b/src/insert.c @@ -727,7 +727,7 @@ void sqlite3Insert( }else{ sqlite3ErrorMsg(pParse, "table %S has no column named %s", pTabList, 0, pColumn->a[i].zName); - pParse->nErr++; + pParse->checkSchema = 1; goto insert_cleanup; } } diff --git a/src/resolve.c b/src/resolve.c index 4e94827e9c..74d6aaef93 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -357,6 +357,7 @@ static int lookupName( }else{ sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); } + pParse->checkSchema = 1; pTopNC->nErr++; } diff --git a/src/select.c b/src/select.c index 9a016039a8..b03e50638d 100644 --- a/src/select.c +++ b/src/select.c @@ -3020,6 +3020,7 @@ int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ ); if( !pIdx ){ sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0); + pParse->checkSchema = 1; return SQLITE_ERROR; } pFrom->pIndex = pIdx; diff --git a/src/trigger.c b/src/trigger.c index 66464bdae4..27fc708d7c 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -496,6 +496,7 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ if( !noErr ){ sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); } + pParse->checkSchema = 1; goto drop_trigger_cleanup; } sqlite3DropTriggerPtr(pParse, pTrigger); diff --git a/src/update.c b/src/update.c index 3c82c27045..fe8344ca27 100644 --- a/src/update.c +++ b/src/update.c @@ -212,6 +212,7 @@ void sqlite3Update( pRowidExpr = pChanges->a[i].pExpr; }else{ sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName); + pParse->checkSchema = 1; goto update_cleanup; } } diff --git a/test/schema3.test b/test/schema3.test new file mode 100644 index 0000000000..7b8962ba57 --- /dev/null +++ b/test/schema3.test @@ -0,0 +1,91 @@ +# 2010 Jun 28 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +source $testdir/lock_common.tcl + +# This block tests that if one client modifies the database schema, a +# second client updates its internal cache of the database schema before +# executing any queries. Specifically, it does not return a "no such column" +# or "no such table" error if the table or column in question does exist +# but was added after the second client loaded its cache of the database +# schema. +# +# Types of schema modifications: +# +# 1. Adding a database table. +# 2. Adding a database view. +# 3. Adding a database index. +# 4. Adding a database trigger. +# 5. Adding a column to an existing table (ALTER TABLE). +# +do_multiclient_test tn { + + # Have connections [db1] and [db2] load the current database schema. + # + sql1 { SELECT * FROM sqlite_master } + sql2 { SELECT * FROM sqlite_master } + + foreach {tn2 c1 c2} { + 1 { CREATE TABLE t1(a, b) } { SELECT * FROM t1 } + 2 { CREATE TABLE t2(a, b) } { UPDATE t2 SET a = b } + 3 { CREATE TABLE t3(a, b) } { DELETE FROM t3 } + 4 { CREATE TABLE t4(a, b) } { INSERT INTO t4 VALUES(1, 2) } + 5 { CREATE TABLE t5(a, b) } { DROP TABLE t5 } + 6 { CREATE TABLE t6(a, b) } { CREATE INDEX i1 ON t6(a) } + + 7 { ALTER TABLE t1 ADD COLUMN c } { SELECT a, b, c FROM t1 } + 8 { ALTER TABLE t2 ADD COLUMN c } { UPDATE t2 SET a = c } + 9 { ALTER TABLE t2 ADD COLUMN d } { UPDATE t2 SET d = c } + 10 { ALTER TABLE t3 ADD COLUMN c } { DELETE FROM t3 WHERE c>10 } + 11 { ALTER TABLE t4 ADD COLUMN c } { INSERT INTO t4(a,b,c) VALUES(1,2,3) } + 12 { ALTER TABLE t6 ADD COLUMN c } { CREATE INDEX i2 ON t6(c) } + 13 { ALTER TABLE t6 ADD COLUMN d } { + CREATE TRIGGER tr1 AFTER UPDATE OF d ON t6 BEGIN + SELECT 1, 2, 3; + END; + } + + 14 { CREATE INDEX i3 ON t1(a) } { DROP INDEX i3 } + 15 { CREATE INDEX i4 ON t2(a) } { + SELECT * FROM t2 INDEXED BY i4 ORDER BY a + } + + 16 { CREATE TRIGGER tr2 AFTER INSERT ON t3 BEGIN SELECT 1 ; END } { + DROP TRIGGER tr2 + } + + 17 { CREATE VIEW v1 AS SELECT * FROM t1 } { SELECT a,b,c FROM v1 } + 18 { ALTER TABLE t1 ADD COLUMN d } { SELECT a,b,c,d FROM v1 } + + 19 { CREATE TABLE t7(a, b) } { + DROP TABLE IF EXISTS t7; CREATE TABLE t7(c, d); + } + 20 { CREATE INDEX i5 ON t7(c, d) } { + DROP INDEX IF EXISTS i5; CREATE INDEX i5 ON t7(c) + } + 21 { CREATE TRIGGER tr3 BEFORE DELETE ON t7 BEGIN SELECT 1, 2, 3 ; END } { + DROP TRIGGER IF EXISTS tr3; + CREATE TRIGGER tr3 AFTER INSERT ON t7 BEGIN SELECT 1, 2, 3 ; END + } + } { + do_test schema3-1.$tn.$tn2 { + sql1 $c1 + sql2 $c2 + } {} + } +} + +finish_test