mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Cause opening a transaction on a sharable b-tree module automatically obtain a read-lock on page 1. This means there is no way for sqlite3BtreeGetMeta() to fail. (CVS 6836)
FossilOrigin-Name: e3c055f167f895ae45858de9d9d8a264df2f36b6
This commit is contained in:
30
manifest
30
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Fix\sfor\scompilation\swith\sOMIT_AUTOVACUUM\sdefined.\sTicket\s#3940.\s(CVS\s6835)
|
C Cause\sopening\sa\stransaction\son\sa\ssharable\sb-tree\smodule\sautomatically\sobtain\sa\sread-lock\son\spage\s1.\sThis\smeans\sthere\sis\sno\sway\sfor\ssqlite3BtreeGetMeta()\sto\sfail.\s(CVS\s6836)
|
||||||
D 2009-07-02T05:23:26
|
D 2009-07-02T07:47:33
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 8b8fb7823264331210cddf103831816c286ba446
|
F Makefile.in 8b8fb7823264331210cddf103831816c286ba446
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -103,12 +103,12 @@ F src/alter.c 95f41d957f56407aac6224041ca5b954042318d1
|
|||||||
F src/analyze.c e239496cfb5394ac8867f1c112905ddab8d01cd9
|
F src/analyze.c e239496cfb5394ac8867f1c112905ddab8d01cd9
|
||||||
F src/attach.c 13995348fc5a26cdd136a50806faf292aabc173f
|
F src/attach.c 13995348fc5a26cdd136a50806faf292aabc173f
|
||||||
F src/auth.c 98db07c2088455797678eb1031f42d4d94d18a71
|
F src/auth.c 98db07c2088455797678eb1031f42d4d94d18a71
|
||||||
F src/backup.c ff50af53184a5fd7bdee4d620b5dabef74717c79
|
F src/backup.c 97a3859d8585eb4fcb1e81a795cf4b3fdd82f30f
|
||||||
F src/bitvec.c 0ef0651714728055d43de7a4cdd95e703fac0119
|
F src/bitvec.c 0ef0651714728055d43de7a4cdd95e703fac0119
|
||||||
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
|
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
|
||||||
F src/btree.c aff035e89ae885ab64acaf339d10411a2c79829b
|
F src/btree.c b739b9659c07d2b9d20f0e8f51ae0cc7f995e039
|
||||||
F src/btree.h f70b694e8c163227369a66863b01fbff9009f323
|
F src/btree.h 8cae6364735a5cb2d577ddb23fa6d0e655a4b931
|
||||||
F src/btreeInt.h 55346bc14b939ad41b297942e8b1b581e960fb99
|
F src/btreeInt.h b31e5ac04181c7e2892c33ab06228c551df6233c
|
||||||
F src/build.c 867028ee9f63f7bc8eb8d4a720bb98cf9b9a12b4
|
F src/build.c 867028ee9f63f7bc8eb8d4a720bb98cf9b9a12b4
|
||||||
F src/callback.c cb68b21b0d4ae7d11ae0e487933bce3323784dcf
|
F src/callback.c cb68b21b0d4ae7d11ae0e487933bce3323784dcf
|
||||||
F src/complete.c 5ad5c6cd4548211867c204c41a126d73a9fbcea0
|
F src/complete.c 5ad5c6cd4548211867c204c41a126d73a9fbcea0
|
||||||
@@ -152,8 +152,8 @@ F src/parse.y c48ce2025d848bbd1995f811e74dced8ab30abe6
|
|||||||
F src/pcache.c 395f752a13574120bd7513a400ba02a265aaa76d
|
F src/pcache.c 395f752a13574120bd7513a400ba02a265aaa76d
|
||||||
F src/pcache.h 9b927ccc5a538e31b4c3bc7eec4f976db42a1324
|
F src/pcache.h 9b927ccc5a538e31b4c3bc7eec4f976db42a1324
|
||||||
F src/pcache1.c 97e7e8e6e34026fb43b47d08532b0c02e959c26c
|
F src/pcache1.c 97e7e8e6e34026fb43b47d08532b0c02e959c26c
|
||||||
F src/pragma.c 1774ff8e2f167368225108489b1c9d123aa13257
|
F src/pragma.c 9eb44ac1d3dc1ac3ea4f444abe1a10ae8acaa16c
|
||||||
F src/prepare.c 3db796d75a786e55cfcb43d46d7145f87b672b76
|
F src/prepare.c e8d8996900d4b7b183622dd2fe2286e1ff0ad37f
|
||||||
F src/printf.c 508a1c59433353552b6553cba175eaa7331f8fc1
|
F src/printf.c 508a1c59433353552b6553cba175eaa7331f8fc1
|
||||||
F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
|
F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
|
||||||
F src/resolve.c 4a61d03e49b15440878096e6030863fc628828f0
|
F src/resolve.c 4a61d03e49b15440878096e6030863fc628828f0
|
||||||
@@ -169,7 +169,7 @@ F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
|
|||||||
F src/tclsqlite.c d3195e0738c101a155404ecdb1cd9532a2fd34f2
|
F src/tclsqlite.c d3195e0738c101a155404ecdb1cd9532a2fd34f2
|
||||||
F src/test1.c c8f9358879876660b721369f576bf6e4ac5b9210
|
F src/test1.c c8f9358879876660b721369f576bf6e4ac5b9210
|
||||||
F src/test2.c d73e4a490349245fb196b990b80684513e0ceaee
|
F src/test2.c d73e4a490349245fb196b990b80684513e0ceaee
|
||||||
F src/test3.c 1e1778ca7e0234c9eb329ac6a5729067b822f3d5
|
F src/test3.c 56750fb15ec9430b3ddb343df727bc164462a706
|
||||||
F src/test4.c f79ab52d27ff49b784b631a42e2ccd52cfd5c84c
|
F src/test4.c f79ab52d27ff49b784b631a42e2ccd52cfd5c84c
|
||||||
F src/test5.c 162a1cea2105a2c460a3f39fa6919617b562a288
|
F src/test5.c 162a1cea2105a2c460a3f39fa6919617b562a288
|
||||||
F src/test6.c 1a0a7a1f179469044b065b4a88aab9faee114101
|
F src/test6.c 1a0a7a1f179469044b065b4a88aab9faee114101
|
||||||
@@ -202,13 +202,13 @@ F src/trigger.c c07c5157c58fcdb704f65d5f5e4775276e45bb8b
|
|||||||
F src/update.c a1bbe774bce495d62dce3df3f42a5f04c1de173a
|
F src/update.c a1bbe774bce495d62dce3df3f42a5f04c1de173a
|
||||||
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
|
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
|
||||||
F src/util.c 861d5b5c58be4921f0a254489ea94cb15f550ef8
|
F src/util.c 861d5b5c58be4921f0a254489ea94cb15f550ef8
|
||||||
F src/vacuum.c 0e14f371ea3326c6b8cfba257286d798cd20db59
|
F src/vacuum.c 3fe0eebea6d2311c1c2ab2962887d11f7a4dcfb0
|
||||||
F src/vdbe.c f2462fdb71b8dfd788e2be1228b1b6c1b702ea80
|
F src/vdbe.c 7e5781773b62c4ef1569e58340f2ca9a034a08b5
|
||||||
F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
|
F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
|
||||||
F src/vdbeInt.h 831c254a6eef237ef4664c8381a0137586567007
|
F src/vdbeInt.h 831c254a6eef237ef4664c8381a0137586567007
|
||||||
F src/vdbeapi.c 0ab8ada7260b32031ca97f338caecf0812460624
|
F src/vdbeapi.c 0ab8ada7260b32031ca97f338caecf0812460624
|
||||||
F src/vdbeaux.c 3773217a73f93fb292d264b3b1da98c179a0f2f0
|
F src/vdbeaux.c 3773217a73f93fb292d264b3b1da98c179a0f2f0
|
||||||
F src/vdbeblob.c f3d3151d8ddfe9fed288f9e2c98c96e12e914fbb
|
F src/vdbeblob.c a3f3e0e877fc64ea50165eec2855f5ada4477611
|
||||||
F src/vdbemem.c 1618f685d19b4bcc96e40b3c478487bafd2ae246
|
F src/vdbemem.c 1618f685d19b4bcc96e40b3c478487bafd2ae246
|
||||||
F src/vtab.c 00902f289521041712fb0293d0bf8688c7af8e48
|
F src/vtab.c 00902f289521041712fb0293d0bf8688c7af8e48
|
||||||
F src/walker.c 1edca756275f158b80f20eb6f104c8d3fcc96a04
|
F src/walker.c 1edca756275f158b80f20eb6f104c8d3fcc96a04
|
||||||
@@ -738,7 +738,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
||||||
P a00aeec21cca7ccf19d4cdef618149aa2773c005
|
P 8f0591ae98c2125a4922933496f4412aee8ab86e
|
||||||
R 5fe9e3bafbc544bd46fe048a3e0db33e
|
R 2a84fbc1846890230c75f17318268fe4
|
||||||
U danielk1977
|
U danielk1977
|
||||||
Z b3ae67dabd40a49c30f3f7417027c9a9
|
Z 37d78b0a7f7b710a92735d2117f44c5f
|
||||||
|
@@ -1 +1 @@
|
|||||||
8f0591ae98c2125a4922933496f4412aee8ab86e
|
e3c055f167f895ae45858de9d9d8a264df2f36b6
|
@@ -12,7 +12,7 @@
|
|||||||
** This file contains the implementation of the sqlite3_backup_XXX()
|
** This file contains the implementation of the sqlite3_backup_XXX()
|
||||||
** API functions and the related features.
|
** API functions and the related features.
|
||||||
**
|
**
|
||||||
** $Id: backup.c,v 1.17 2009/06/03 11:25:07 danielk1977 Exp $
|
** $Id: backup.c,v 1.18 2009/07/02 07:47:33 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "btreeInt.h"
|
#include "btreeInt.h"
|
||||||
@@ -318,7 +318,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
|||||||
&& SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2))
|
&& SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2))
|
||||||
){
|
){
|
||||||
p->bDestLocked = 1;
|
p->bDestLocked = 1;
|
||||||
rc = sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
|
sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there is no open read-transaction on the source database, open
|
/* If there is no open read-transaction on the source database, open
|
||||||
|
119
src/btree.c
119
src/btree.c
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.647 2009/07/02 05:23:26 danielk1977 Exp $
|
** $Id: btree.c,v 1.648 2009/07/02 07:47:33 danielk1977 Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** See the header comment on "btreeInt.h" for additional information.
|
** See the header comment on "btreeInt.h" for additional information.
|
||||||
@@ -366,7 +366,10 @@ static void clearAllSharedCacheTableLocks(Btree *p){
|
|||||||
assert( pLock->pBtree->inTrans>=pLock->eLock );
|
assert( pLock->pBtree->inTrans>=pLock->eLock );
|
||||||
if( pLock->pBtree==p ){
|
if( pLock->pBtree==p ){
|
||||||
*ppIter = pLock->pNext;
|
*ppIter = pLock->pNext;
|
||||||
sqlite3_free(pLock);
|
assert( pLock->iTable!=1 || pLock==&p->lock );
|
||||||
|
if( pLock->iTable!=1 ){
|
||||||
|
sqlite3_free(pLock);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
ppIter = &pLock->pNext;
|
ppIter = &pLock->pNext;
|
||||||
}
|
}
|
||||||
@@ -1605,6 +1608,10 @@ int sqlite3BtreeOpen(
|
|||||||
}
|
}
|
||||||
p->inTrans = TRANS_NONE;
|
p->inTrans = TRANS_NONE;
|
||||||
p->db = db;
|
p->db = db;
|
||||||
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
|
p->lock.pBtree = p;
|
||||||
|
p->lock.iTable = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
|
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
|
||||||
/*
|
/*
|
||||||
@@ -2376,6 +2383,13 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Any read-only or read-write transaction implies a read-lock on
|
||||||
|
** page 1. So if some other shared-cache client already has a write-lock
|
||||||
|
** on page 1, the transaction cannot be opened. */
|
||||||
|
if( SQLITE_OK!=(rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK)) ){
|
||||||
|
goto trans_begun;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* Call lockBtree() until either pBt->pPage1 is populated or
|
/* Call lockBtree() until either pBt->pPage1 is populated or
|
||||||
** lockBtree() returns something other than SQLITE_OK. lockBtree()
|
** lockBtree() returns something other than SQLITE_OK. lockBtree()
|
||||||
@@ -2406,6 +2420,14 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
if( p->inTrans==TRANS_NONE ){
|
if( p->inTrans==TRANS_NONE ){
|
||||||
pBt->nTransaction++;
|
pBt->nTransaction++;
|
||||||
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
|
if( p->sharable ){
|
||||||
|
assert( p->lock.pBtree==p && p->lock.iTable==1 );
|
||||||
|
p->lock.eLock = READ_LOCK;
|
||||||
|
p->lock.pNext = pBt->pLock;
|
||||||
|
pBt->pLock = &p->lock;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
|
p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
|
||||||
if( p->inTrans>pBt->inTransaction ){
|
if( p->inTrans>pBt->inTransaction ){
|
||||||
@@ -3188,17 +3210,11 @@ static int btreeCursor(
|
|||||||
assert( sqlite3BtreeHoldsMutex(p) );
|
assert( sqlite3BtreeHoldsMutex(p) );
|
||||||
assert( wrFlag==0 || wrFlag==1 );
|
assert( wrFlag==0 || wrFlag==1 );
|
||||||
|
|
||||||
/* The following assert statements verify that if this is a sharable b-tree
|
/* The following assert statements verify that if this is a sharable
|
||||||
** database, the connection is holding the required table locks, and that
|
** b-tree database, the connection is holding the required table locks,
|
||||||
** no other connection has any open cursor that conflicts with this lock.
|
** and that no other connection has any open cursor that conflicts with
|
||||||
**
|
** this lock. */
|
||||||
** The exception to this is read-only cursors open on the schema table.
|
assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) );
|
||||||
** Such a cursor is opened without a lock while reading the database
|
|
||||||
** schema. This is safe because BtShared.mutex is held for the entire
|
|
||||||
** lifetime of this cursor. */
|
|
||||||
assert( (iTable==1 && wrFlag==0)
|
|
||||||
|| hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1)
|
|
||||||
);
|
|
||||||
assert( wrFlag==0 || !hasReadConflicts(p, iTable) );
|
assert( wrFlag==0 || !hasReadConflicts(p, iTable) );
|
||||||
|
|
||||||
if( NEVER(wrFlag && pBt->readOnly) ){
|
if( NEVER(wrFlag && pBt->readOnly) ){
|
||||||
@@ -6663,10 +6679,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){
|
|||||||
** root page of the new table should go. meta[3] is the largest root-page
|
** root page of the new table should go. meta[3] is the largest root-page
|
||||||
** created so far, so the new root-page is (meta[3]+1).
|
** created so far, so the new root-page is (meta[3]+1).
|
||||||
*/
|
*/
|
||||||
rc = sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot);
|
sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot);
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
pgnoRoot++;
|
pgnoRoot++;
|
||||||
|
|
||||||
/* The new root-page may not be allocated on a pointer-map page, or the
|
/* The new root-page may not be allocated on a pointer-map page, or the
|
||||||
@@ -6901,11 +6914,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
|
|||||||
#else
|
#else
|
||||||
if( pBt->autoVacuum ){
|
if( pBt->autoVacuum ){
|
||||||
Pgno maxRootPgno;
|
Pgno maxRootPgno;
|
||||||
rc = sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
|
sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
releasePage(pPage);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( iTable==maxRootPgno ){
|
if( iTable==maxRootPgno ){
|
||||||
/* If the table being dropped is the table with the largest root-page
|
/* If the table being dropped is the table with the largest root-page
|
||||||
@@ -6981,6 +6990,9 @@ int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
** This function may only be called if the b-tree connection already
|
||||||
|
** has a read or write transaction open on the database.
|
||||||
|
**
|
||||||
** Read the meta-information out of a database file. Meta[0]
|
** Read the meta-information out of a database file. Meta[0]
|
||||||
** is the number of free pages currently in the database. Meta[1]
|
** is the number of free pages currently in the database. Meta[1]
|
||||||
** through meta[15] are available for use by higher layers. Meta[0]
|
** through meta[15] are available for use by higher layers. Meta[0]
|
||||||
@@ -6990,71 +7002,24 @@ int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
|
|||||||
** layer (and the SetCookie and ReadCookie opcodes) the number of
|
** layer (and the SetCookie and ReadCookie opcodes) the number of
|
||||||
** free pages is not visible. So Cookie[0] is the same as Meta[1].
|
** free pages is not visible. So Cookie[0] is the same as Meta[1].
|
||||||
*/
|
*/
|
||||||
int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
|
void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
|
||||||
DbPage *pDbPage = 0;
|
|
||||||
int rc;
|
|
||||||
unsigned char *pP1;
|
|
||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
|
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
assert( p->inTrans>TRANS_NONE );
|
||||||
/* Reading a meta-data value requires a read-lock on page 1 (and hence
|
assert( SQLITE_OK==querySharedCacheTableLock(p, 1, READ_LOCK) );
|
||||||
** the sqlite_master table. We grab this lock regardless of whether or
|
assert( pBt->pPage1 );
|
||||||
** not the SQLITE_ReadUncommitted flag is set (the table rooted at page
|
|
||||||
** 1 is treated as a special case by querySharedCacheTableLock()
|
|
||||||
** and setSharedCacheTableLock()).
|
|
||||||
*/
|
|
||||||
rc = querySharedCacheTableLock(p, 1, READ_LOCK);
|
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
sqlite3BtreeLeave(p);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert( idx>=0 && idx<=15 );
|
assert( idx>=0 && idx<=15 );
|
||||||
if( pBt->pPage1 ){
|
|
||||||
/* The b-tree is already holding a reference to page 1 of the database
|
|
||||||
** file. In this case the required meta-data value can be read directly
|
|
||||||
** from the page data of this reference. This is slightly faster than
|
|
||||||
** requesting a new reference from the pager layer.
|
|
||||||
*/
|
|
||||||
pP1 = (unsigned char *)pBt->pPage1->aData;
|
|
||||||
}else{
|
|
||||||
/* The b-tree does not have a reference to page 1 of the database file.
|
|
||||||
** Obtain one from the pager layer.
|
|
||||||
*/
|
|
||||||
rc = sqlite3PagerGet(pBt->pPager, 1, &pDbPage);
|
|
||||||
if( rc ){
|
|
||||||
sqlite3BtreeLeave(p);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
pP1 = (unsigned char *)sqlite3PagerGetData(pDbPage);
|
|
||||||
}
|
|
||||||
*pMeta = get4byte(&pP1[36 + idx*4]);
|
|
||||||
|
|
||||||
/* If the b-tree is not holding a reference to page 1, then one was
|
*pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
|
||||||
** requested from the pager layer in the above block. Release it now.
|
|
||||||
*/
|
|
||||||
if( !pBt->pPage1 ){
|
|
||||||
sqlite3PagerUnref(pDbPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If autovacuumed is disabled in this build but we are trying to
|
/* If auto-vacuum is disabled in this build and this is an auto-vacuum
|
||||||
** access an autovacuumed database, then make the database readonly.
|
** database, mark the database as read-only. */
|
||||||
*/
|
|
||||||
#ifdef SQLITE_OMIT_AUTOVACUUM
|
#ifdef SQLITE_OMIT_AUTOVACUUM
|
||||||
if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ) pBt->readOnly = 1;
|
if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ) pBt->readOnly = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If there is currently an open transaction, grab a read-lock
|
|
||||||
** on page 1 of the database file. This is done to make sure that
|
|
||||||
** no other connection can modify the meta value just read from
|
|
||||||
** the database until the transaction is concluded.
|
|
||||||
*/
|
|
||||||
if( p->inTrans>0 ){
|
|
||||||
rc = setSharedCacheTableLock(p, 1, READ_LOCK);
|
|
||||||
}
|
|
||||||
sqlite3BtreeLeave(p);
|
sqlite3BtreeLeave(p);
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -7740,10 +7705,12 @@ int sqlite3BtreeSchemaLocked(Btree *p){
|
|||||||
*/
|
*/
|
||||||
int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
|
int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
assert( p->inTrans!=TRANS_NONE );
|
||||||
if( p->sharable ){
|
if( p->sharable ){
|
||||||
u8 lockType = READ_LOCK + isWriteLock;
|
u8 lockType = READ_LOCK + isWriteLock;
|
||||||
assert( READ_LOCK+1==WRITE_LOCK );
|
assert( READ_LOCK+1==WRITE_LOCK );
|
||||||
assert( isWriteLock==0 || isWriteLock==1 );
|
assert( isWriteLock==0 || isWriteLock==1 );
|
||||||
|
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
rc = querySharedCacheTableLock(p, iTab, lockType);
|
rc = querySharedCacheTableLock(p, iTab, lockType);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
** subsystem. See comments in the source code for a detailed description
|
** subsystem. See comments in the source code for a detailed description
|
||||||
** of what each interface routine does.
|
** of what each interface routine does.
|
||||||
**
|
**
|
||||||
** @(#) $Id: btree.h,v 1.116 2009/06/03 11:25:07 danielk1977 Exp $
|
** @(#) $Id: btree.h,v 1.117 2009/07/02 07:47:33 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _BTREE_H_
|
#ifndef _BTREE_H_
|
||||||
#define _BTREE_H_
|
#define _BTREE_H_
|
||||||
@@ -97,8 +97,8 @@ int sqlite3BtreeIsInTrans(Btree*);
|
|||||||
int sqlite3BtreeIsInReadTrans(Btree*);
|
int sqlite3BtreeIsInReadTrans(Btree*);
|
||||||
int sqlite3BtreeIsInBackup(Btree*);
|
int sqlite3BtreeIsInBackup(Btree*);
|
||||||
void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
|
void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
|
||||||
int sqlite3BtreeSchemaLocked(Btree *);
|
int sqlite3BtreeSchemaLocked(Btree *pBtree);
|
||||||
int sqlite3BtreeLockTable(Btree *, int, u8);
|
int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
|
||||||
int sqlite3BtreeSavepoint(Btree *, int, int);
|
int sqlite3BtreeSavepoint(Btree *, int, int);
|
||||||
|
|
||||||
const char *sqlite3BtreeGetFilename(Btree *);
|
const char *sqlite3BtreeGetFilename(Btree *);
|
||||||
@@ -118,7 +118,7 @@ int sqlite3BtreeDropTable(Btree*, int, int*);
|
|||||||
int sqlite3BtreeClearTable(Btree*, int, int*);
|
int sqlite3BtreeClearTable(Btree*, int, int*);
|
||||||
void sqlite3BtreeTripAllCursors(Btree*, int);
|
void sqlite3BtreeTripAllCursors(Btree*, int);
|
||||||
|
|
||||||
int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue);
|
void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
|
||||||
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
|
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btreeInt.h,v 1.49 2009/06/24 05:40:34 danielk1977 Exp $
|
** $Id: btreeInt.h,v 1.50 2009/07/02 07:47:33 danielk1977 Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** For a detailed discussion of BTrees, refer to
|
** For a detailed discussion of BTrees, refer to
|
||||||
@@ -302,6 +302,24 @@ struct MemPage {
|
|||||||
*/
|
*/
|
||||||
#define EXTRA_SIZE sizeof(MemPage)
|
#define EXTRA_SIZE sizeof(MemPage)
|
||||||
|
|
||||||
|
/*
|
||||||
|
** A linked list of the following structures is stored at BtShared.pLock.
|
||||||
|
** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor
|
||||||
|
** is opened on the table with root page BtShared.iTable. Locks are removed
|
||||||
|
** from this list when a transaction is committed or rolled back, or when
|
||||||
|
** a btree handle is closed.
|
||||||
|
*/
|
||||||
|
struct BtLock {
|
||||||
|
Btree *pBtree; /* Btree handle holding this lock */
|
||||||
|
Pgno iTable; /* Root page of table */
|
||||||
|
u8 eLock; /* READ_LOCK or WRITE_LOCK */
|
||||||
|
BtLock *pNext; /* Next in BtShared.pLock list */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Candidate values for BtLock.eLock */
|
||||||
|
#define READ_LOCK 1
|
||||||
|
#define WRITE_LOCK 2
|
||||||
|
|
||||||
/* A Btree handle
|
/* A Btree handle
|
||||||
**
|
**
|
||||||
** A database connection contains a pointer to an instance of
|
** A database connection contains a pointer to an instance of
|
||||||
@@ -333,6 +351,9 @@ struct Btree {
|
|||||||
int nBackup; /* Number of backup operations reading this btree */
|
int nBackup; /* Number of backup operations reading this btree */
|
||||||
Btree *pNext; /* List of other sharable Btrees from the same db */
|
Btree *pNext; /* List of other sharable Btrees from the same db */
|
||||||
Btree *pPrev; /* Back pointer of the same list */
|
Btree *pPrev; /* Back pointer of the same list */
|
||||||
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
|
BtLock lock; /* Object used to lock page 1 */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -516,24 +537,6 @@ struct BtCursor {
|
|||||||
*/
|
*/
|
||||||
# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
|
# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
|
||||||
|
|
||||||
/*
|
|
||||||
** A linked list of the following structures is stored at BtShared.pLock.
|
|
||||||
** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor
|
|
||||||
** is opened on the table with root page BtShared.iTable. Locks are removed
|
|
||||||
** from this list when a transaction is committed or rolled back, or when
|
|
||||||
** a btree handle is closed.
|
|
||||||
*/
|
|
||||||
struct BtLock {
|
|
||||||
Btree *pBtree; /* Btree handle holding this lock */
|
|
||||||
Pgno iTable; /* Root page of table */
|
|
||||||
u8 eLock; /* READ_LOCK or WRITE_LOCK */
|
|
||||||
BtLock *pNext; /* Next in BtShared.pLock list */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Candidate values for BtLock.eLock */
|
|
||||||
#define READ_LOCK 1
|
|
||||||
#define WRITE_LOCK 2
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** These macros define the location of the pointer-map entry for a
|
** These macros define the location of the pointer-map entry for a
|
||||||
** database page. The first argument to each is the number of usable
|
** database page. The first argument to each is the number of usable
|
||||||
|
20
src/pragma.c
20
src/pragma.c
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the PRAGMA command.
|
** This file contains code used to implement the PRAGMA command.
|
||||||
**
|
**
|
||||||
** $Id: pragma.c,v 1.213 2009/06/19 14:06:03 drh Exp $
|
** $Id: pragma.c,v 1.214 2009/07/02 07:47:33 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -318,12 +318,13 @@ void sqlite3Pragma(
|
|||||||
*/
|
*/
|
||||||
if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
|
if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
|
||||||
static const VdbeOpList getCacheSize[] = {
|
static const VdbeOpList getCacheSize[] = {
|
||||||
{ OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 0 */
|
{ OP_Transaction, 0, 0, 0}, /* 0 */
|
||||||
{ OP_IfPos, 1, 6, 0},
|
{ OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
|
||||||
|
{ OP_IfPos, 1, 7, 0},
|
||||||
{ OP_Integer, 0, 2, 0},
|
{ OP_Integer, 0, 2, 0},
|
||||||
{ OP_Subtract, 1, 2, 1},
|
{ OP_Subtract, 1, 2, 1},
|
||||||
{ OP_IfPos, 1, 6, 0},
|
{ OP_IfPos, 1, 7, 0},
|
||||||
{ OP_Integer, 0, 1, 0}, /* 5 */
|
{ OP_Integer, 0, 1, 0}, /* 6 */
|
||||||
{ OP_ResultRow, 1, 1, 0},
|
{ OP_ResultRow, 1, 1, 0},
|
||||||
};
|
};
|
||||||
int addr;
|
int addr;
|
||||||
@@ -335,7 +336,8 @@ void sqlite3Pragma(
|
|||||||
pParse->nMem += 2;
|
pParse->nMem += 2;
|
||||||
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
||||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||||
sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE);
|
sqlite3VdbeChangeP1(v, addr+1, iDb);
|
||||||
|
sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
|
||||||
}else{
|
}else{
|
||||||
int size = atoi(zRight);
|
int size = atoi(zRight);
|
||||||
if( size<0 ) size = -size;
|
if( size<0 ) size = -size;
|
||||||
@@ -1302,12 +1304,14 @@ void sqlite3Pragma(
|
|||||||
}else{
|
}else{
|
||||||
/* Read the specified cookie value */
|
/* Read the specified cookie value */
|
||||||
static const VdbeOpList readCookie[] = {
|
static const VdbeOpList readCookie[] = {
|
||||||
{ OP_ReadCookie, 0, 1, 0}, /* 0 */
|
{ OP_Transaction, 0, 0, 0}, /* 0 */
|
||||||
|
{ OP_ReadCookie, 0, 1, 0}, /* 1 */
|
||||||
{ OP_ResultRow, 1, 1, 0}
|
{ OP_ResultRow, 1, 1, 0}
|
||||||
};
|
};
|
||||||
int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
|
int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
|
||||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||||
sqlite3VdbeChangeP3(v, addr, iCookie);
|
sqlite3VdbeChangeP1(v, addr+1, iDb);
|
||||||
|
sqlite3VdbeChangeP3(v, addr+1, iCookie);
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
** interface, and routines that contribute to loading the database schema
|
** interface, and routines that contribute to loading the database schema
|
||||||
** from disk.
|
** from disk.
|
||||||
**
|
**
|
||||||
** $Id: prepare.c,v 1.125 2009/06/25 11:50:21 drh Exp $
|
** $Id: prepare.c,v 1.126 2009/07/02 07:47:33 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -128,7 +128,6 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
|
|||||||
static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
BtCursor *curMain;
|
|
||||||
int size;
|
int size;
|
||||||
Table *pTab;
|
Table *pTab;
|
||||||
Db *pDb;
|
Db *pDb;
|
||||||
@@ -137,6 +136,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
InitData initData;
|
InitData initData;
|
||||||
char const *zMasterSchema;
|
char const *zMasterSchema;
|
||||||
char const *zMasterName = SCHEMA_TABLE(iDb);
|
char const *zMasterName = SCHEMA_TABLE(iDb);
|
||||||
|
int openedTransaction;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The master database table has a structure like this
|
** The master database table has a structure like this
|
||||||
@@ -210,14 +210,21 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
curMain = sqlite3MallocZero(sqlite3BtreeCursorSize());
|
|
||||||
if( !curMain ){
|
/* If there is not already a read-only (or read-write) transaction opened
|
||||||
rc = SQLITE_NOMEM;
|
** on the b-tree database, open one now. If a transaction is opened, it
|
||||||
goto error_out;
|
** will be closed before this function returns. */
|
||||||
}
|
|
||||||
sqlite3BtreeEnter(pDb->pBt);
|
sqlite3BtreeEnter(pDb->pBt);
|
||||||
rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, curMain);
|
if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
|
||||||
if( rc==SQLITE_EMPTY ) rc = SQLITE_OK;
|
rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
|
||||||
|
goto initone_error_out;
|
||||||
|
}
|
||||||
|
openedTransaction = 1;
|
||||||
|
}else{
|
||||||
|
openedTransaction = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the database meta information.
|
/* Get the database meta information.
|
||||||
**
|
**
|
||||||
@@ -236,12 +243,8 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
|
** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
|
||||||
** the possible values of meta[4].
|
** the possible values of meta[4].
|
||||||
*/
|
*/
|
||||||
for(i=0; rc==SQLITE_OK && i<ArraySize(meta); i++){
|
for(i=0; i<ArraySize(meta); i++){
|
||||||
rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
|
sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
|
||||||
}
|
|
||||||
if( rc ){
|
|
||||||
sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
|
|
||||||
goto initone_error_out;
|
|
||||||
}
|
}
|
||||||
pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
|
pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
|
||||||
|
|
||||||
@@ -356,8 +359,9 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
** before that point, jump to error_out.
|
** before that point, jump to error_out.
|
||||||
*/
|
*/
|
||||||
initone_error_out:
|
initone_error_out:
|
||||||
sqlite3BtreeCloseCursor(curMain);
|
if( openedTransaction ){
|
||||||
sqlite3_free(curMain);
|
sqlite3BtreeCommit(pDb->pBt);
|
||||||
|
}
|
||||||
sqlite3BtreeLeave(pDb->pBt);
|
sqlite3BtreeLeave(pDb->pBt);
|
||||||
|
|
||||||
error_out:
|
error_out:
|
||||||
@@ -437,13 +441,46 @@ int sqlite3ReadSchema(Parse *pParse){
|
|||||||
** Check schema cookies in all databases. If any cookie is out
|
** Check schema cookies in all databases. If any cookie is out
|
||||||
** of date, return 0. If all schema cookies are current, return 1.
|
** of date, return 0. If all schema cookies are current, return 1.
|
||||||
*/
|
*/
|
||||||
static int schemaIsValid(sqlite3 *db){
|
static void schemaIsValid(Parse *pParse){
|
||||||
|
sqlite3 *db = pParse->db;
|
||||||
int iDb;
|
int iDb;
|
||||||
int rc;
|
int rc;
|
||||||
BtCursor *curTemp;
|
|
||||||
int cookie;
|
int cookie;
|
||||||
int allOk = 1;
|
|
||||||
|
|
||||||
|
assert( pParse->checkSchema );
|
||||||
|
assert( sqlite3_mutex_held(db->mutex) );
|
||||||
|
for(iDb=0; iDb<db->nDb; iDb++){
|
||||||
|
int openedTransaction = 0; /* True if a transaction is opened */
|
||||||
|
Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */
|
||||||
|
if( pBt==0 ) continue;
|
||||||
|
|
||||||
|
/* If there is not already a read-only (or read-write) transaction opened
|
||||||
|
** on the b-tree database, open one now. If a transaction is opened, it
|
||||||
|
** will be closed immediately after reading the meta-value. */
|
||||||
|
if( !sqlite3BtreeIsInReadTrans(pBt) ){
|
||||||
|
rc = sqlite3BtreeBeginTrans(pBt, 0);
|
||||||
|
if( NEVER(rc==SQLITE_NOMEM) || rc==SQLITE_IOERR_NOMEM ){
|
||||||
|
db->mallocFailed = 1;
|
||||||
|
}
|
||||||
|
if( rc!=SQLITE_OK ) return;
|
||||||
|
openedTransaction = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the schema cookie from the database. If it does not match the
|
||||||
|
** value stored as part of the in the in-memory schema representation,
|
||||||
|
** set Parse.rc to SQLITE_SCHEMA. */
|
||||||
|
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
|
||||||
|
if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
|
||||||
|
pParse->rc = SQLITE_SCHEMA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the transaction, if one was opened. */
|
||||||
|
if( openedTransaction ){
|
||||||
|
sqlite3BtreeCommit(pBt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
curTemp = (BtCursor *)sqlite3Malloc(sqlite3BtreeCursorSize());
|
curTemp = (BtCursor *)sqlite3Malloc(sqlite3BtreeCursorSize());
|
||||||
if( curTemp ){
|
if( curTemp ){
|
||||||
assert( sqlite3_mutex_held(db->mutex) );
|
assert( sqlite3_mutex_held(db->mutex) );
|
||||||
@@ -470,8 +507,8 @@ static int schemaIsValid(sqlite3 *db){
|
|||||||
allOk = 0;
|
allOk = 0;
|
||||||
db->mallocFailed = 1;
|
db->mallocFailed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return allOk;
|
return allOk;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -604,8 +641,8 @@ static int sqlite3Prepare(
|
|||||||
pParse->rc = SQLITE_NOMEM;
|
pParse->rc = SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
|
if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
|
||||||
if( pParse->checkSchema && !schemaIsValid(db) ){
|
if( pParse->checkSchema ){
|
||||||
pParse->rc = SQLITE_SCHEMA;
|
schemaIsValid(pParse);
|
||||||
}
|
}
|
||||||
if( pParse->rc==SQLITE_SCHEMA ){
|
if( pParse->rc==SQLITE_SCHEMA ){
|
||||||
sqlite3ResetInternalSchema(db, 0);
|
sqlite3ResetInternalSchema(db, 0);
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test3.c,v 1.105 2009/06/29 06:00:37 danielk1977 Exp $
|
** $Id: test3.c,v 1.106 2009/07/02 07:47:33 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "btreeInt.h"
|
#include "btreeInt.h"
|
||||||
@@ -425,12 +425,8 @@ static int btree_get_meta(
|
|||||||
char zBuf[30];
|
char zBuf[30];
|
||||||
u32 v;
|
u32 v;
|
||||||
sqlite3BtreeEnter(pBt);
|
sqlite3BtreeEnter(pBt);
|
||||||
rc = sqlite3BtreeGetMeta(pBt, i, &v);
|
sqlite3BtreeGetMeta(pBt, i, &v);
|
||||||
sqlite3BtreeLeave(pBt);
|
sqlite3BtreeLeave(pBt);
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",v);
|
sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",v);
|
||||||
Tcl_AppendElement(interp, zBuf);
|
Tcl_AppendElement(interp, zBuf);
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
** Most of the code in this file may be omitted by defining the
|
** Most of the code in this file may be omitted by defining the
|
||||||
** SQLITE_OMIT_VACUUM macro.
|
** SQLITE_OMIT_VACUUM macro.
|
||||||
**
|
**
|
||||||
** $Id: vacuum.c,v 1.90 2009/06/03 11:25:07 danielk1977 Exp $
|
** $Id: vacuum.c,v 1.91 2009/07/02 07:47:33 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "vdbeInt.h"
|
#include "vdbeInt.h"
|
||||||
@@ -254,8 +254,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
|||||||
for(i=0; i<ArraySize(aCopy); i+=2){
|
for(i=0; i<ArraySize(aCopy); i+=2){
|
||||||
/* GetMeta() and UpdateMeta() cannot fail in this context because
|
/* GetMeta() and UpdateMeta() cannot fail in this context because
|
||||||
** we already have page 1 loaded into cache and marked dirty. */
|
** we already have page 1 loaded into cache and marked dirty. */
|
||||||
rc = sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
|
sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
|
||||||
if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum;
|
|
||||||
rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
|
rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
|
||||||
if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum;
|
if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum;
|
||||||
}
|
}
|
||||||
|
@@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.867 2009/06/29 06:00:37 danielk1977 Exp $
|
** $Id: vdbe.c,v 1.868 2009/07/02 07:47:33 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "vdbeInt.h"
|
#include "vdbeInt.h"
|
||||||
@@ -2759,7 +2759,7 @@ case OP_ReadCookie: { /* out2-prerelease */
|
|||||||
assert( db->aDb[iDb].pBt!=0 );
|
assert( db->aDb[iDb].pBt!=0 );
|
||||||
assert( (p->btreeMask & (1<<iDb))!=0 );
|
assert( (p->btreeMask & (1<<iDb))!=0 );
|
||||||
|
|
||||||
rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
|
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
|
||||||
pOut->u.i = iMeta;
|
pOut->u.i = iMeta;
|
||||||
MemSetTypeFlag(pOut, MEM_Int);
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
break;
|
break;
|
||||||
@@ -2824,12 +2824,11 @@ case OP_VerifyCookie: {
|
|||||||
assert( (p->btreeMask & (1<<pOp->p1))!=0 );
|
assert( (p->btreeMask & (1<<pOp->p1))!=0 );
|
||||||
pBt = db->aDb[pOp->p1].pBt;
|
pBt = db->aDb[pOp->p1].pBt;
|
||||||
if( pBt ){
|
if( pBt ){
|
||||||
rc = sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
|
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
|
||||||
}else{
|
}else{
|
||||||
rc = SQLITE_OK;
|
|
||||||
iMeta = 0;
|
iMeta = 0;
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
|
if( iMeta!=pOp->p2 ){
|
||||||
sqlite3DbFree(db, p->zErrMsg);
|
sqlite3DbFree(db, p->zErrMsg);
|
||||||
p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
|
p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
|
||||||
/* If the schema-cookie from the database file matches the cookie
|
/* If the schema-cookie from the database file matches the cookie
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
**
|
**
|
||||||
** This file contains code used to implement incremental BLOB I/O.
|
** This file contains code used to implement incremental BLOB I/O.
|
||||||
**
|
**
|
||||||
** $Id: vdbeblob.c,v 1.34 2009/06/29 06:00:37 danielk1977 Exp $
|
** $Id: vdbeblob.c,v 1.35 2009/07/02 07:47:33 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
Reference in New Issue
Block a user