Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge trunk changes into experimental branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | experimental |
Files: | files | file ages | folders |
SHA1: |
15368a9f8523d5fb611cd576080daed2 |
User & Date: | dan 2010-08-03 18:29:05.000 |
Context
2010-08-04
| ||
19:14 | Fix some problems with error recovery introduced while reworking pager state. (check-in: 77eaab6f77 user: dan tags: experimental) | |
2010-08-03
| ||
18:29 | Merge trunk changes into experimental branch. (check-in: 15368a9f85 user: dan tags: experimental) | |
18:18 | Set the Pager.eState variable to PAGER_ERROR whenever the pager enters the error state. (check-in: 4d384761d2 user: dan tags: experimental) | |
18:06 | Fix disabled implementation-mark comments in func.c. (check-in: 57c0960038 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
︙ | ︙ | |||
7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 | /* ** Return non-zero if a transaction is active. */ int sqlite3BtreeIsInTrans(Btree *p){ assert( p==0 || sqlite3_mutex_held(p->db->mutex) ); return (p && (p->inTrans==TRANS_WRITE)); } /* ** Return non-zero if a read (or write) transaction is active. */ int sqlite3BtreeIsInReadTrans(Btree *p){ assert( p ); assert( sqlite3_mutex_held(p->db->mutex) ); | > > > > > > > > > > > > > > > > > > > > > > > | 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 | /* ** Return non-zero if a transaction is active. */ int sqlite3BtreeIsInTrans(Btree *p){ assert( p==0 || sqlite3_mutex_held(p->db->mutex) ); return (p && (p->inTrans==TRANS_WRITE)); } #ifndef SQLITE_OMIT_WAL /* ** Run a checkpoint on the Btree passed as the first argument. ** ** Return SQLITE_LOCKED if this or any other connection has an open ** transaction on the shared-cache the argument Btree is connected to. */ int sqlite3BtreeCheckpoint(Btree *p){ int rc = SQLITE_OK; if( p ){ BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); if( pBt->inTransaction!=TRANS_NONE ){ rc = SQLITE_LOCKED; }else{ rc = sqlite3PagerCheckpoint(pBt->pPager); } sqlite3BtreeLeave(p); } return rc; } #endif /* ** Return non-zero if a read (or write) transaction is active. */ int sqlite3BtreeIsInReadTrans(Btree *p){ assert( p ); assert( sqlite3_mutex_held(p->db->mutex) ); |
︙ | ︙ |
Changes to src/btree.h.
︙ | ︙ | |||
196 197 198 199 200 201 202 203 204 205 206 207 208 209 | int sqlite3BtreeCount(BtCursor *, i64 *); #endif #ifdef SQLITE_TEST int sqlite3BtreeCursorInfo(BtCursor*, int*, int); void sqlite3BtreeCursorList(Btree*); #endif /* ** If we are not using shared cache, then there is no need to ** use mutexes to access the BtShared structures. So make the ** Enter and Leave procedures no-ops. */ #ifndef SQLITE_OMIT_SHARED_CACHE | > > > > | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | int sqlite3BtreeCount(BtCursor *, i64 *); #endif #ifdef SQLITE_TEST int sqlite3BtreeCursorInfo(BtCursor*, int*, int); void sqlite3BtreeCursorList(Btree*); #endif #ifndef SQLITE_OMIT_WAL int sqlite3BtreeCheckpoint(Btree*); #endif /* ** If we are not using shared cache, then there is no need to ** use mutexes to access the BtShared structures. So make the ** Enter and Leave procedures no-ops. */ #ifndef SQLITE_OMIT_SHARED_CACHE |
︙ | ︙ |
Changes to src/func.c.
︙ | ︙ | |||
784 785 786 787 788 789 790 | sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zOptName; assert( argc==1 ); UNUSED_PARAMETER(argc); | | | > > | | > | 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 | sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zOptName; assert( argc==1 ); UNUSED_PARAMETER(argc); /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL ** function is a wrapper around the sqlite3_compileoption_used() C/C++ ** function. */ if( (zOptName = (const char*)sqlite3_value_text(argv[0]))!=0 ){ sqlite3_result_int(context, sqlite3_compileoption_used(zOptName)); } } #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ /* ** Implementation of the sqlite_compileoption_get() function. ** The result is a string that identifies the compiler options ** used to build SQLite. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS static void compileoptiongetFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ int n; assert( argc==1 ); UNUSED_PARAMETER(argc); /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function ** is a wrapper around the sqlite3_compileoption_get() C/C++ function. */ n = sqlite3_value_int(argv[0]); sqlite3_result_text(context, sqlite3_compileoption_get(n), -1, SQLITE_STATIC); } #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ /* Array for converting from half-bytes (nybbles) into ASCII hex ** digits. */ |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 | int allOk = sqlite3VdbeMakeLabel(v); pParse->ckBase = regData; sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, SQLITE_JUMPIFNULL); onError = overrideError!=OE_Default ? overrideError : OE_Abort; if( onError==OE_Ignore ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); }else{ sqlite3HaltConstraint(pParse, onError, 0, 0); } sqlite3VdbeResolveLabel(v, allOk); } #endif /* !defined(SQLITE_OMIT_CHECK) */ /* If we have an INTEGER PRIMARY KEY, make sure the primary key | > | 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 | int allOk = sqlite3VdbeMakeLabel(v); pParse->ckBase = regData; sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, SQLITE_JUMPIFNULL); onError = overrideError!=OE_Default ? overrideError : OE_Abort; if( onError==OE_Ignore ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); }else{ if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */ sqlite3HaltConstraint(pParse, onError, 0, 0); } sqlite3VdbeResolveLabel(v, allOk); } #endif /* !defined(SQLITE_OMIT_CHECK) */ /* If we have an INTEGER PRIMARY KEY, make sure the primary key |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
1304 1305 1306 1307 1308 1309 1310 | int rc = SQLITE_OK; /* Return code */ int i; /* Used to iterate through attached dbs */ assert( sqlite3_mutex_held(db->mutex) ); for(i=0; i<db->nDb && rc==SQLITE_OK; i++){ if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){ | | < < < < < < < < < | 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 | int rc = SQLITE_OK; /* Return code */ int i; /* Used to iterate through attached dbs */ assert( sqlite3_mutex_held(db->mutex) ); for(i=0; i<db->nDb && rc==SQLITE_OK; i++){ if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){ rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt); } } return rc; } #endif /* SQLITE_OMIT_WAL */ |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
5557 5558 5559 5560 5561 5562 5563 | ** journal requires a sync here. However, in locking_mode=exclusive ** on a system under memory pressure it is just possible that this is ** not the case. In this case it is likely enough that the redundant ** xSync() call will be changed to a no-op by the OS anyhow. */ rc = syncJournal(pPager, 0); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; | | | 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 | ** journal requires a sync here. However, in locking_mode=exclusive ** on a system under memory pressure it is just possible that this is ** not the case. In this case it is likely enough that the redundant ** xSync() call will be changed to a no-op by the OS anyhow. */ rc = syncJournal(pPager, 0); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache)); if( rc!=SQLITE_OK ){ assert( rc!=SQLITE_IOERR_BLOCKED ); goto commit_phase_one_exit; } sqlite3PcacheCleanAll(pPager->pPCache); |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
2567 2568 2569 2570 2571 2572 2573 | ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or ** SQLITE_STMTSTATUS_SORT for the most recent eval. */ case DB_STATUS: { int v; const char *zOp; if( objc!=3 ){ | | | 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 | ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or ** SQLITE_STMTSTATUS_SORT for the most recent eval. */ case DB_STATUS: { int v; const char *zOp; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "(step|sort|autoindex)"); return TCL_ERROR; } zOp = Tcl_GetString(objv[2]); if( strcmp(zOp, "step")==0 ){ v = pDb->nStep; }else if( strcmp(zOp, "sort")==0 ){ v = pDb->nSort; |
︙ | ︙ |
Changes to src/update.c.
1 2 3 4 5 6 7 8 9 10 | /* ** 2001 September 15 ** ** 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. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
2396 2397 2398 2399 2400 2401 2402 | #ifdef SQLITE_TEST extern int sqlite3_search_count; #endif assert( p->isTable ); rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); if( rc ) return rc; p->lastRowid = p->movetoTarget; | > | < < < < | 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 | #ifdef SQLITE_TEST extern int sqlite3_search_count; #endif assert( p->isTable ); rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); if( rc ) return rc; p->lastRowid = p->movetoTarget; if( res!=0 ) return SQLITE_CORRUPT_BKPT; p->rowidIsValid = 1; #ifdef SQLITE_TEST sqlite3_search_count++; #endif p->deferredMoveto = 0; p->cacheStatus = CACHE_STALE; }else if( ALWAYS(p->pCursor) ){ int hasMoved; |
︙ | ︙ |
Changes to src/vdbemem.c.
︙ | ︙ | |||
1012 1013 1014 1015 1016 1017 1018 | if( !pExpr ){ *ppVal = 0; return SQLITE_OK; } op = pExpr->op; | | | 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 | if( !pExpr ){ *ppVal = 0; return SQLITE_OK; } op = pExpr->op; /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT2. ** The ifdef here is to enable us to achieve 100% branch test coverage even ** when SQLITE_ENABLE_STAT2 is omitted. */ #ifdef SQLITE_ENABLE_STAT2 if( op==TK_REGISTER ) op = pExpr->op2; #else if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; |
︙ | ︙ |
Changes to test/conflict.test.
︙ | ︙ | |||
784 785 786 787 788 789 790 791 792 | do_test conflict-12.4 { execsql { UPDATE OR REPLACE t5 SET a=a+1 WHERE a=1; SELECT * FROM t5; } } {2 one} finish_test | > > > > > > > > > > > > > > > > > > > > > > | 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 | do_test conflict-12.4 { execsql { UPDATE OR REPLACE t5 SET a=a+1 WHERE a=1; SELECT * FROM t5; } } {2 one} # Ticket [c38baa3d969eab7946dc50ba9d9b4f0057a19437] # REPLACE works like ABORT on a CHECK constraint. # do_test conflict-13.1 { execsql { CREATE TABLE t13(a CHECK(a!=2)); BEGIN; REPLACE INTO t13 VALUES(1); } catchsql { REPLACE INTO t13 VALUES(2); } } {1 {constraint failed}} do_test conflict-13.2 { execsql { REPLACE INTO t13 VALUES(3); COMMIT; SELECT * FROM t13; } } {1 3} finish_test |
Changes to test/wal2.test.
︙ | ︙ | |||
976 977 978 979 980 981 982 | } {wal 1 2 3 4 5 6 7 8 9} do_test wal2-11.1.1 { sqlite3 db2 test.db execsql { SELECT name FROM sqlite_master } db2 } {t1} | > | | | | | | | | | | | | | | | | | | | | | | | > | 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 | } {wal 1 2 3 4 5 6 7 8 9} do_test wal2-11.1.1 { sqlite3 db2 test.db execsql { SELECT name FROM sqlite_master } db2 } {t1} if {$::tcl_version>=8.5} { # Set all zeroed slots in the first hash table to invalid values. # set blob [string range [tvfs shm $::filename] 0 16383] set I [string range [tvfs shm $::filename] 16384 end] binary scan $I t* L set I [list] foreach p $L { lappend I [expr $p ? $p : 400] } append blob [binary format t* $I] tvfs shm $::filename $blob do_test wal2-11.2 { catchsql { INSERT INTO t1 VALUES(10, 11, 12) } } {1 {database disk image is malformed}} # Fill up the hash table on the first page of shared memory with 0x55 bytes. # set blob [string range [tvfs shm $::filename] 0 16383] append blob [string repeat [binary format c 55] 16384] tvfs shm $::filename $blob do_test wal2-11.3 { catchsql { SELECT * FROM t1 } db2 } {1 {database disk image is malformed}} } db close db2 close tvfs delete #------------------------------------------------------------------------- # If a connection is required to create a WAL or SHM file, it creates |
︙ | ︙ | |||
1144 1145 1146 1147 1148 1149 1150 | } $b($can_read,$can_write) } catch { db close } } } finish_test | < | 1146 1147 1148 1149 1150 1151 1152 | } $b($can_read,$can_write) } catch { db close } } } finish_test |
Added test/walshared.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | # 2010 August 2 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the operation of the library in # "PRAGMA journal_mode=WAL" mode with shared-cache turned on. # set testdir [file dirname $argv0] source $testdir/tester.tcl db close set ::enable_shared_cache [sqlite3_enable_shared_cache 1] sqlite3 db test.db sqlite3 db2 test.db do_test walshared-1.0 { execsql { PRAGMA cache_size = 10; PRAGMA journal_mode = WAL; CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); INSERT INTO t1 VALUES(randomblob(100), randomblob(200)); } } {wal} do_test walshared-1.1 { execsql { BEGIN; INSERT INTO t1 VALUES(randomblob(100), randomblob(200)); INSERT INTO t1 SELECT randomblob(100), randomblob(200) FROM t1; INSERT INTO t1 SELECT randomblob(100), randomblob(200) FROM t1; INSERT INTO t1 SELECT randomblob(100), randomblob(200) FROM t1; } } {} do_test walshared-1.2 { catchsql { PRAGMA wal_checkpoint } } {1 {database table is locked}} do_test walshared-1.3 { catchsql { PRAGMA wal_checkpoint } db2 } {1 {database table is locked}} do_test walshared-1.4 { execsql { COMMIT } execsql { PRAGMA integrity_check } db2 } {ok} sqlite3_enable_shared_cache $::enable_shared_cache finish_test |