From: drh Date: Fri, 26 Oct 2012 13:34:05 +0000 (+0000) Subject: Backport the [/timeline?r=shared-cache-fix | shared-cache-fix] branch. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d9488466991b6a8d9bf999695d9f0ef226be96df;p=thirdparty%2Fsqlite.git Backport the [/timeline?r=shared-cache-fix | shared-cache-fix] branch. FossilOrigin-Name: 325364a984e9a5c0825810bf50f57e026ff3b8dd --- diff --git a/manifest b/manifest index e3e9227f54..772b7d45e3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sQNX-specific\sperformance\stweaks\sto\sthe\sunix\sVFS.\s(Cherry-pick\smerge\sof\n[b02849e7bde458].)\nPut\sauxiliary\slibraries\safter\slibsqlite3.a\sin\sthe\stestfixture\starget\sof\nthe\s"main.mk"\smakefile.\s\s(Cherry-pick\smerge\sof\s[8fc8548f52ab8fcfb5].) -D 2012-10-26T13:25:32.533 +C Backport\sthe\s[/timeline?r=shared-cache-fix\s|\sshared-cache-fix]\sbranch. +D 2012-10-26T13:34:05.437 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -116,9 +116,9 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad -F src/alter.c 149cc80d9257971b0bff34e58fb2263e01998289 +F src/alter.c c3d9d0d6735064c4ba83a67dbf0d42f9bf5a1d6f F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410 -F src/attach.c 577bf5675b0c50495fc28549f2fcbdb1bac71143 +F src/attach.c 34c15ecd686e58f08e5bb1389e28a0b65c2c83db F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 5b31b24d6814b11de763debf342c8cd0a15a4910 F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1 @@ -126,13 +126,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 97edf88abd2b66f31886ba977d2b3b2a21d81d4c F src/btree.h 4aee02e879211bfcfd3f551769578d2e940ab6c2 F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621 -F src/build.c a3b700afd475e6387da59be6f2e86161e80d6d87 +F src/build.c 0aef4fa83fbf334d0929f5e5ad1bb4beecfd00fb F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 500d019da966631ad957c37705642be87524463b F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 -F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de -F src/expr.c 217840a107dcc1e5dbb57cea311daad04bedbb9a +F src/delete.c c374ab8dd20ef475d9a4d26ef3799e71db7379a9 +F src/expr.c 763fce595793e1f47fe9c80fceed2354eb089d13 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 9c77d842dc9961d92a06a65abb80c64ef1750296 F src/func.c 18dfedfb857e100b05755a1b12e88b389f957879 @@ -140,7 +140,7 @@ F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c b090d0a9fb9ff2dbdeaf66aedccf98cd13b1af60 +F src/insert.c ece0dfd2e1cee4cc35e343c79a52eab9f52cef48 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 @@ -176,12 +176,12 @@ F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c f843c872a97baa1594c2cc3d4c003409a7bd03af +F src/select.c b2c911d0bfad8a22732f9de08cbcc2148f7d8d6d F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261 F src/sqlite.h.in c447d35212736c4c77d86bc2d00f6cf4d4c12131 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 -F src/sqliteInt.h 053e03a532beb909ead2df0721db67cdb4c48ae8 +F src/sqliteInt.h 462f9552011af3648628cfcdef1be7df823cdb52 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -247,7 +247,7 @@ F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74 F src/vdbesort.c 0dc1b274dcb4d4c8e71b0b2b15261f286caba39b F src/vdbetrace.c 8bd5da325fc90f28464335e4cc4ad1407fe30835 -F src/vtab.c d2c54fd22aa83eb34fc6f7cd9b097f2fc2b1e9de +F src/vtab.c bf61d2b47fbe544cf128f176d950a95ab9fa7990 F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b @@ -699,6 +699,7 @@ F test/shared4.test 72d90821e8d2fc918a08f16d32880868d8ee8e9d F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9 F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d +F test/shared9.test 3a5b09583e3ba3139a4bd66958061306b4331c7e F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf F test/shell1.test 9895ee3013742a02e5afd8d77793729967ffd195 @@ -881,7 +882,7 @@ F test/trace2.test c1dc104a8d11a347c870cfea6235e3fc6f6cb06d F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22 F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732 -F test/trigger1.test de42feb7cd442787d38185ae74f5a1d7afa400cb +F test/trigger1.test 70acedb76532117bbcc873f8601cdc6905f1f455 F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816 F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359 @@ -1014,7 +1015,7 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix bc91332e37e980c20575e087b368922f93673f1b -P 521024d4a799f36618e8adb1d032d76806db28bc -R 8488838a2bba50b76a7185282c39e09d +P cbfd1b120ada30ee98403af8d95cfbd590353365 +R cec8d9ad420249b78e42ff233036b95b U drh -Z 0b8c2e8e933f44d93bc453110c788c68 +Z f05ff88a3dfee3e1a7e5cb1a864f2163 diff --git a/manifest.uuid b/manifest.uuid index 80578f6042..b5826c41ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cbfd1b120ada30ee98403af8d95cfbd590353365 \ No newline at end of file +325364a984e9a5c0825810bf50f57e026ff3b8dd \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 7f56ce7e0b..a1cef7b82e 100644 --- a/src/alter.c +++ b/src/alter.c @@ -414,7 +414,7 @@ void sqlite3AlterRenameTable( assert( pSrc->nSrc==1 ); assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase); + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_rename_table; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); zDb = db->aDb[iDb].zName; @@ -757,7 +757,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ assert( pParse->pNewTable==0 ); assert( sqlite3BtreeHoldsAllMutexes(db) ); if( db->mallocFailed ) goto exit_begin_add_column; - pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase); + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_begin_add_column; #ifndef SQLITE_OMIT_VIRTUALTABLE diff --git a/src/attach.c b/src/attach.c index e295c30111..3e045aa366 100644 --- a/src/attach.c +++ b/src/attach.c @@ -434,6 +434,7 @@ int sqlite3FixInit( assert( db->nDb>iDb ); pFix->pParse = pParse; pFix->zDb = db->aDb[iDb].zName; + pFix->pSchema = db->aDb[iDb].pSchema; pFix->zType = zType; pFix->pName = pName; return 1; @@ -464,14 +465,15 @@ int sqlite3FixSrcList( if( NEVER(pList==0) ) return 0; zDb = pFix->zDb; for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pItem->zDatabase==0 ){ - pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb); - }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){ + if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ sqlite3ErrorMsg(pFix->pParse, "%s %T cannot reference objects in database %s", pFix->zType, pFix->pName, pItem->zDatabase); return 1; } + sqlite3_free(pItem->zDatabase); + pItem->zDatabase = 0; + pItem->pSchema = pFix->pSchema; #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; diff --git a/src/build.c b/src/build.c index 25e474031f..d07542fe67 100644 --- a/src/build.c +++ b/src/build.c @@ -319,6 +319,31 @@ Table *sqlite3LocateTable( return p; } +/* +** Locate the table identified by *p. +** +** This is a wrapper around sqlite3LocateTable(). The difference between +** sqlite3LocateTable() and this function is that this function restricts +** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be +** non-NULL if it is part of a view or trigger program definition. See +** sqlite3FixSrcList() for details. +*/ +Table *sqlite3LocateTableItem( + Parse *pParse, + int isView, + struct SrcList_item *p +){ + const char *zDb; + assert( p->pSchema==0 || p->zDatabase==0 ); + if( p->pSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); + zDb = pParse->db->aDb[iDb].zName; + }else{ + zDb = p->zDatabase; + } + return sqlite3LocateTable(pParse, isView, p->zName, zDb); +} + /* ** Locate the in-memory structure that describes ** a particular index given the name of that index @@ -2114,8 +2139,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); if( noErr ) db->suppressErr++; - pTab = sqlite3LocateTable(pParse, isView, - pName->a[0].zName, pName->a[0].zDatabase); + pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); if( noErr ) db->suppressErr--; if( pTab==0 ){ @@ -2555,8 +2579,7 @@ Index *sqlite3CreateIndex( ** sqlite3FixSrcList can never fail. */ assert(0); } - pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName, - pTblName->a[0].zDatabase); + pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]); if( !pTab || db->mallocFailed ) goto exit_create_index; assert( db->aDb[iDb].pSchema==pTab->pSchema ); }else{ diff --git a/src/delete.c b/src/delete.c index 44e5995a69..3772198b54 100644 --- a/src/delete.c +++ b/src/delete.c @@ -32,7 +32,7 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ struct SrcList_item *pItem = pSrc->a; Table *pTab; assert( pItem && pSrc->nSrc==1 ); - pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase); + pTab = sqlite3LocateTableItem(pParse, 0, pItem); sqlite3DeleteTable(pParse->db, pItem->pTab); pItem->pTab = pTab; if( pTab ){ diff --git a/src/expr.c b/src/expr.c index 89172f94bf..47f79bd2af 100644 --- a/src/expr.c +++ b/src/expr.c @@ -930,6 +930,7 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ struct SrcList_item *pNewItem = &pNew->a[i]; struct SrcList_item *pOldItem = &p->a[i]; Table *pTab; + pNewItem->pSchema = pOldItem->pSchema; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); diff --git a/src/insert.c b/src/insert.c index a24e8f9481..d0ea159616 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1222,7 +1222,9 @@ void sqlite3GenerateConstraintChecks( onError = overrideError!=OE_Default ? overrideError : OE_Abort; for(i=0; inExpr; i++){ int allOk = sqlite3VdbeMakeLabel(v); - sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL); + Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0); + if( pDup==0 ) break; + sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL); if( onError==OE_Ignore ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); }else{ @@ -1236,6 +1238,7 @@ void sqlite3GenerateConstraintChecks( sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC); } sqlite3VdbeResolveLabel(v, allOk); + sqlite3ExprDelete(db, pDup); } } #endif /* !defined(SQLITE_OMIT_CHECK) */ @@ -1691,7 +1694,7 @@ static int xferOptimization( ** we have to check the semantics. */ pItem = pSelect->pSrc->a; - pSrc = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase); + pSrc = sqlite3LocateTableItem(pParse, 0, pItem); if( pSrc==0 ){ return 0; /* FROM clause does not contain a real table */ } diff --git a/src/select.c b/src/select.c index 6ec9da39a1..1badde362b 100644 --- a/src/select.c +++ b/src/select.c @@ -3268,8 +3268,7 @@ static int selectExpander(Walker *pWalker, Select *p){ }else{ /* An ordinary table or view name in the FROM clause */ assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = - sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase); + pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); if( pTab==0 ) return WRC_Abort; pTab->nRef++; #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 09163bf69c..599c4cb7bb 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1855,6 +1855,7 @@ struct SrcList { i16 nSrc; /* Number of tables or subqueries in the FROM clause */ i16 nAlloc; /* Number of entries allocated in a[] below */ struct SrcList_item { + Schema *pSchema; /* Schema to which this item is fixed */ char *zDatabase; /* Name of database holding this table */ char *zName; /* Name of the table */ char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ @@ -2420,6 +2421,7 @@ struct TriggerStep { typedef struct DbFixer DbFixer; struct DbFixer { Parse *pParse; /* The parsing context. Error messages written here */ + Schema *pSchema; /* Fix items to this schema */ const char *zDb; /* Make sure all objects are contained in this database */ const char *zType; /* Type of the container - used for error messages */ const Token *pName; /* Name of the container - used for error messages */ @@ -2830,6 +2832,7 @@ void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); Table *sqlite3FindTable(sqlite3*,const char*, const char*); Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*); +Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); diff --git a/src/vtab.c b/src/vtab.c index 50d576fc38..6219f8b0ba 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -263,6 +263,7 @@ void sqlite3VtabClear(sqlite3 *db, Table *p){ if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); if( p->azModuleArg ){ int i; + assert( p->nModuleArg<2 || p->azModuleArg[1]==0 ); for(i=0; inModuleArg; i++){ sqlite3DbFree(db, p->azModuleArg[i]); } @@ -324,7 +325,7 @@ void sqlite3VtabBeginParse( pTable->tabFlags |= TF_Virtual; pTable->nModuleArg = 0; addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); - addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName)); + addModuleArgument(db, pTable, 0); addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z); @@ -481,6 +482,7 @@ static int vtabCallConstructor( int nArg = pTab->nModuleArg; char *zErr = 0; char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); + int iDb; if( !zModuleName ){ return SQLITE_NOMEM; @@ -494,6 +496,10 @@ static int vtabCallConstructor( pVTable->db = db; pVTable->pMod = pMod; + assert( pTab->azModuleArg[1]==0 ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + pTab->azModuleArg[1] = db->aDb[iDb].zName; + /* Invoke the virtual table constructor */ assert( &db->pVtabCtx ); assert( xConstruct ); @@ -504,6 +510,7 @@ static int vtabCallConstructor( rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); db->pVtabCtx = pPriorCtx; if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + pTab->azModuleArg[1] = 0; if( SQLITE_OK!=rc ){ if( zErr==0 ){ diff --git a/test/shared9.test b/test/shared9.test new file mode 100644 index 0000000000..bb0dfee186 --- /dev/null +++ b/test/shared9.test @@ -0,0 +1,140 @@ +# 2012 October 5 +# +# 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. +# +#*********************************************************************** +# +# The tests in this file are intended to show if two connections attach +# to the same shared cache using different database names, views and +# virtual tables may still be accessed. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix shared9 + +ifcapable !view||!trigger { + finish_test + return +} + +db close +set enable_shared_cache [sqlite3_enable_shared_cache 1] + +sqlite3 db1 test.db +sqlite3 db2 test.db +forcedelete test.db2 + +do_test 1.1 { + db1 eval { + ATTACH 'test.db2' AS 'fred'; + CREATE TABLE fred.t1(a, b, c); + CREATE VIEW fred.v1 AS SELECT * FROM t1; + + CREATE TABLE fred.t2(a, b); + CREATE TABLE fred.t3(a, b); + CREATE TRIGGER fred.trig AFTER INSERT ON t2 BEGIN + DELETE FROM t3; + INSERT INTO t3 SELECT * FROM t2; + END; + INSERT INTO t2 VALUES(1, 2); + SELECT * FROM t3; + } +} {1 2} + +do_test 1.2 { db2 eval "ATTACH 'test.db2' AS 'jones'" } {} +do_test 1.3 { db2 eval "SELECT * FROM v1" } {} +do_test 1.4 { db2 eval "INSERT INTO t2 VALUES(3, 4)" } {} + +ifcapable fts3 { + do_test 1.5 { + db1 eval { + CREATE VIRTUAL TABLE fred.t4 USING fts4; + INSERT INTO t4 VALUES('hello world'); + } + } {} + + do_test 1.6 { + db2 eval { + INSERT INTO t4 VALUES('shared cache'); + SELECT * FROM t4 WHERE t4 MATCH 'hello'; + } + } {{hello world}} + + do_test 1.7 { + db1 eval { + SELECT * FROM t4 WHERE t4 MATCH 'c*'; + } + } {{shared cache}} +} + +db1 close +db2 close + +#------------------------------------------------------------------------- +# The following tests attempt to find a similar problem with collation +# sequence names - pointers to database handle specific allocations leaking +# into schema objects and being used after the original handle has been +# closed. +# +forcedelete test.db test.db2 +sqlite3 db1 test.db +sqlite3 db2 test.db +foreach x {collate1 collate2 collate3} { + proc $x {a b} { string compare $a $b } + db1 collate $x $x + db2 collate $x $x +} +do_test 2.1 { + db1 eval { + CREATE TABLE t1(a, b, c COLLATE collate1); + CREATE INDEX i1 ON t1(a COLLATE collate2, c, b); + } +} {} +do_test 2.2 { + db1 close + db2 eval "INSERT INTO t1 VALUES('abc', 'def', 'ghi')" +} {} +db2 close + +#------------------------------------------------------------------------- +# At one point, the following would cause a collation sequence belonging +# to connection [db1] to be invoked by a call to [db2 eval]. Which is a +# problem if [db1] has already been closed. +# +forcedelete test.db test.db2 +sqlite3 db1 test.db +sqlite3 db2 test.db + +proc mycollate_db1 {a b} {set ::invoked_mycollate_db1 1 ; string compare $a $b} +proc mycollate_db2 {a b} {string compare $a $b} + +db1 collate mycollate mycollate_db1 +db2 collate mycollate mycollate_db2 + +do_test 2.3 { + set ::invoked_mycollate_db1 0 + db1 eval { + CREATE TABLE t1(a COLLATE mycollate, CHECK (a IN ('one', 'two', 'three'))); + INSERT INTO t1 VALUES('one'); + } + db1 close + set ::invoked_mycollate_db1 +} {1} +do_test 2.4 { + set ::invoked_mycollate_db1 0 + db2 eval { + INSERT INTO t1 VALUES('two'); + } + db2 close + set ::invoked_mycollate_db1 +} {0} + +sqlite3_enable_shared_cache $::enable_shared_cache +finish_test + diff --git a/test/trigger1.test b/test/trigger1.test index 9d917bdb38..38806db3b5 100644 --- a/test/trigger1.test +++ b/test/trigger1.test @@ -210,7 +210,7 @@ do_test trigger1-1.12 { delete from t1 WHERE a=old.a+2; end; } -} {1 {cannot create INSTEAD OF trigger on table: main.t1}} +} {1 {cannot create INSTEAD OF trigger on table: t1}} ifcapable view { # Ensure that we cannot create BEFORE triggers on views @@ -221,7 +221,7 @@ do_test trigger1-1.13 { delete from t1 WHERE a=old.a+2; end; } -} {1 {cannot create BEFORE trigger on view: main.v1}} +} {1 {cannot create BEFORE trigger on view: v1}} # Ensure that we cannot create AFTER triggers on views do_test trigger1-1.14 { catchsql { @@ -231,7 +231,7 @@ do_test trigger1-1.14 { delete from t1 WHERE a=old.a+2; end; } -} {1 {cannot create AFTER trigger on view: main.v1}} +} {1 {cannot create AFTER trigger on view: v1}} } ;# ifcapable view # Check for memory leaks in the trigger parser