Shared-cache mode fixes for views and virtual tables.

FossilOrigin-Name: 2b370dea704b59262c604af0efcef5660b194454
This commit is contained in:
dan 2012-10-04 19:33:00 +00:00
parent 613a53a029
commit 41fb5cd103
13 changed files with 151 additions and 34 deletions

View File

@ -1,5 +1,5 @@
C Fix\san\sout-of-order\smemset()\sthat\soccurs\sbefore\sall\svariable\sdeclarations\nare\sfinished.\s\sAlso\sfix\sa\sline\sthat\sexceeds\sthe\s80-character\sline\slength\nlimit.
D 2012-10-03T18:09:32.822
C Shared-cache\smode\sfixes\sfor\sviews\sand\svirtual\stables.
D 2012-10-04T19:33:00.992
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -114,9 +114,9 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
F src/alter.c 0c1716aa8d248bd6bc750e23be4c68ad05f8668c
F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168
F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410
F src/attach.c 577bf5675b0c50495fc28549f2fcbdb1bac71143
F src/attach.c 34c15ecd686e58f08e5bb1389e28a0b65c2c83db
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c afc067b9a9050ff48b9d46285c53d096c556a73d
F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1
@ -124,13 +124,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 14de53ebb334633ee632ab3c5b9262cfe7cbe455
F src/btree.h 078f76b28c338ab6eb6dd7324d63ee54463aeb6c
F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621
F src/build.c c4555e16f8ccdadb2616014c617ed8166c5a93f7
F src/build.c 74baa2d6d63535c9fc82e0d51d3e5d1145614473
F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
F src/delete.c 4f7d773ec44b7db22b30ec9144f58a69154e09b7
F src/expr.c 4de967b85f577ba00a7cdcb53d22070def6198db
F src/delete.c e35684ad93c741266b086610d2efd709b7946853
F src/expr.c 57fb8e7a05d4147e40b9f4c439e37ed2abab9332
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af
F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898
@ -138,7 +138,7 @@ F src/global.c fb44b11e02e06c995e6ed6642509edd23599d584
F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 6e2aa7fbb5d4c5f34d412772751ed0aff0b9e87b
F src/insert.c aefc97951fbac7f022d423170b9f74e82410bc13
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
@ -174,12 +174,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 75c5e37cc882c468383c9d9e07496b9a16cfae3e
F src/select.c 2a82736faeca1fe93315eda20c691d68ec13bb6c
F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7
F src/sqlite.h.in c7be05ad191d2634292fcc77bdb2bcfa4526eb98
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
F src/sqliteInt.h c29395d6e68cfbcb2661787ae4820e5e256c916a
F src/sqliteInt.h 27105bbf399f65842fb8eb9e343123a628cc6e5a
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@ -245,7 +245,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 d8020c0a0e8ccc490ca449d7e665311b6e9f3ba9
F src/vtab.c c7671587d07b76582c495d9305b35c0172cad5d3
F src/wal.c e1fe8f92a0ea0fef8faa87ec43a127a478589d22
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
@ -702,6 +702,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 61cf645c716451642ae9be2342fada8b200649c3
F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de
F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf
F test/shell1.test 272384163432c0efd2c6817396beb0d119565d53
@ -884,7 +885,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
@ -1018,7 +1019,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9
P 956e4d7f8958e7065ff2d61cd71519d6f4113d4a
R 9f4b1a764df6137e6f14304dffc8ad1d
U drh
Z a3c3e4f99944b9339f658e73f3668f5f
P ba2f492f957ab5556cd540e21a76ebb75efea725
R a18cfd3cd9e6232f2cdfda7383e14e1c
T *branch * shared-cache-fix
T *sym-shared-cache-fix *
T -sym-trunk *
U dan
Z f1b4bf4b6486e150199936af81c3ec9e

View File

@ -1 +1 @@
ba2f492f957ab5556cd540e21a76ebb75efea725
2b370dea704b59262c604af0efcef5660b194454

View File

@ -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

View File

@ -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; i<pList->nSrc; 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;

View File

@ -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{

View File

@ -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 ){

View File

@ -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);

View File

@ -1743,7 +1743,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 */
}

View File

@ -3332,8 +3332,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)

View File

@ -1869,6 +1869,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" */
@ -2437,6 +2438,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 */
@ -2847,6 +2849,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*);

View File

@ -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; i<p->nModuleArg; 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 ){

78
test/shared9.test Normal file
View File

@ -0,0 +1,78 @@
# 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
db close
set enable_shared_cache [sqlite3_enable_shared_cache 1]
# Test organization:
#
# 1.* - Views.
# 2.* - Virtual tables.
#
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.2 { db2 eval "SELECT * FROM v1" } {}
do_test 1.3 { db2 eval "INSERT INTO t2 VALUES(3, 4)" } {}
do_test 2.1 {
db1 eval {
CREATE VIRTUAL TABLE fred.t4 USING fts4;
INSERT INTO t4 VALUES('hello world');
}
} {}
do_test 2.2 {
db2 eval {
INSERT INTO t4 VALUES('shared cache');
SELECT * FROM t4 WHERE t4 MATCH 'hello';
}
} {{hello world}}
do_test 2.3 {
db1 eval {
SELECT * FROM t4 WHERE t4 MATCH 'c*';
}
} {{shared cache}}
db1 close
db2 close
sqlite3_enable_shared_cache $::enable_shared_cache
finish_test

View File

@ -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