Shared-cache mode fixes for views and virtual tables.
FossilOrigin-Name: 2b370dea704b59262c604af0efcef5660b194454
This commit is contained in:
parent
613a53a029
commit
41fb5cd103
36
manifest
36
manifest
@ -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
|
||||
|
@ -1 +1 @@
|
||||
ba2f492f957ab5556cd540e21a76ebb75efea725
|
||||
2b370dea704b59262c604af0efcef5660b194454
|
@ -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
|
||||
|
@ -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;
|
||||
|
31
src/build.c
31
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{
|
||||
|
@ -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 ){
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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*);
|
||||
|
@ -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
78
test/shared9.test
Normal 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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user