Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Redefine the way PRAGMA data_version works: It continues to change when any other connection commits, including shared-cache connections, but does not change if the local connection commits. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7a97826f33460f3b4f3890c9cf97116c |
User & Date: | drh 2014-12-22 18:41:21.243 |
Context
2014-12-22
| ||
22:02 | Fix a typo in an evidence mark on a test script. No changes to code. (check-in: a08b0c7512 user: drh tags: trunk) | |
18:48 | Merge the PRAGMA data_version redefinition and other fixes from trunk. (check-in: 315243e49d user: drh tags: sessions) | |
18:41 | Redefine the way PRAGMA data_version works: It continues to change when any other connection commits, including shared-cache connections, but does not change if the local connection commits. (check-in: 7a97826f33 user: drh tags: trunk) | |
2014-12-21
| ||
11:56 | Fixes to the README.md file. No changes to code. (check-in: ef4b734d1f user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
︙ | ︙ | |||
3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 | assert( pBt->inTransaction==TRANS_WRITE ); assert( pBt->nTransaction>0 ); rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); if( rc!=SQLITE_OK && bCleanup==0 ){ sqlite3BtreeLeave(p); return rc; } pBt->inTransaction = TRANS_READ; btreeClearHasContent(pBt); } btreeEndTransaction(p); sqlite3BtreeLeave(p); return SQLITE_OK; | > | 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 | assert( pBt->inTransaction==TRANS_WRITE ); assert( pBt->nTransaction>0 ); rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); if( rc!=SQLITE_OK && bCleanup==0 ){ sqlite3BtreeLeave(p); return rc; } p->iDataVersion--; /* Compensate for pPager->iDataVersion++; */ pBt->inTransaction = TRANS_READ; btreeClearHasContent(pBt); } btreeEndTransaction(p); sqlite3BtreeLeave(p); return SQLITE_OK; |
︙ | ︙ | |||
8191 8192 8193 8194 8195 8196 8197 | sqlite3BtreeEnter(p); assert( p->inTrans>TRANS_NONE ); assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) ); assert( pBt->pPage1 ); assert( idx>=0 && idx<=15 ); if( idx==BTREE_DATA_VERSION ){ | | | 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 | sqlite3BtreeEnter(p); assert( p->inTrans>TRANS_NONE ); assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) ); assert( pBt->pPage1 ); assert( idx>=0 && idx<=15 ); if( idx==BTREE_DATA_VERSION ){ *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion; }else{ *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]); } /* If auto-vacuum is disabled in this build and this is an auto-vacuum ** database, mark the database as read-only. */ #ifdef SQLITE_OMIT_AUTOVACUUM |
︙ | ︙ |
Changes to src/btreeInt.h.
︙ | ︙ | |||
347 348 349 350 351 352 353 354 355 356 357 358 359 360 | sqlite3 *db; /* The database connection holding this btree */ BtShared *pBt; /* Sharable content of this btree */ u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */ u8 sharable; /* True if we can share pBt with another db */ u8 locked; /* True if db currently has pBt locked */ int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ int nBackup; /* Number of backup operations reading this btree */ Btree *pNext; /* List of other sharable Btrees from the same db */ Btree *pPrev; /* Back pointer of the same list */ #ifndef SQLITE_OMIT_SHARED_CACHE BtLock lock; /* Object used to lock page 1 */ #endif }; | > | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | sqlite3 *db; /* The database connection holding this btree */ BtShared *pBt; /* Sharable content of this btree */ u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */ u8 sharable; /* True if we can share pBt with another db */ u8 locked; /* True if db currently has pBt locked */ int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ int nBackup; /* Number of backup operations reading this btree */ u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */ Btree *pNext; /* List of other sharable Btrees from the same db */ Btree *pPrev; /* Back pointer of the same list */ #ifndef SQLITE_OMIT_SHARED_CACHE BtLock lock; /* Object used to lock page 1 */ #endif }; |
︙ | ︙ |
Changes to test/pragma3.test.
︙ | ︙ | |||
28 29 30 31 32 33 34 | PRAGMA main.data_version=1234; PRAGMA main.data_version; } {1 1} # EVIDENCE-OF: R-27726-60934 The "PRAGMA data_version" command provides # an indication that the database file has been modified. # | < < < < | | < < < < < < > > > > > | > > > > > | > | | | < < < < > > > > | | > > > > | > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > | > | | | < > > > | | | < | < | < > > > > > | > | > > > > > > > > > > > > > > > > | | | | 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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | PRAGMA main.data_version=1234; PRAGMA main.data_version; } {1 1} # EVIDENCE-OF: R-27726-60934 The "PRAGMA data_version" command provides # an indication that the database file has been modified. # # EVIDENCE-OF: R-25838-33704 The "PRAGMA data_version" value is # unchanced for commits made on the same database connection. # do_execsql_test pragma3-110 { PRAGMA data_version; BEGIN IMMEDIATE; PRAGMA data_version; CREATE TABLE t1(a); INSERT INTO t1 VALUES(100),(200),(300); PRAGMA data_version; COMMIT; SELECT * FROM t1; PRAGMA data_version; } {1 1 1 100 200 300 1} sqlite3 db2 test.db do_test pragma3-120 { db2 eval { SELECT * FROM t1; PRAGMA data_version; } } {100 200 300 1} do_execsql_test pragma3-130 { PRAGMA data_version; BEGIN IMMEDIATE; PRAGMA data_version; INSERT INTO t1 VALUES(400),(500); PRAGMA data_version; COMMIT; SELECT * FROM t1; PRAGMA data_version; } {1 1 1 100 200 300 400 500 1} # EVIDENCE-OF: R-63005-41812 The integer values returned by two # invocations of "PRAGMA data_version" from the same connection will be # different if changes were committed to the database by any other # connection in the interim. # # Value went from 1 in pragma3-120 to 2 here. # do_test pragma3-140 { db2 eval { SELECT * FROM t1; PRAGMA data_version; BEGIN IMMEDIATE; PRAGMA data_version; UPDATE t1 SET a=a+1; COMMIT; SELECT * FROM t1; PRAGMA data_version; } } {100 200 300 400 500 2 2 101 201 301 401 501 2} do_execsql_test pragma3-150 { SELECT * FROM t1; PRAGMA data_version; } {101 201 301 401 501 2} # do_test pragma3-160 { db eval { BEGIN; PRAGMA data_version; UPDATE t1 SET a=555 WHERE a=501; PRAGMA data_version; SELECT * FROM t1 ORDER BY a; PRAGMA data_version; } } {2 2 101 201 301 401 555 2} do_test pragma3-170 { db2 eval { PRAGMA data_version; } } {2} do_test pragma3-180 { db eval { COMMIT; PRAGMA data_version; } } {2} do_test pragma3-190 { db2 eval { PRAGMA data_version; } } {3} # EVIDENCE-OF: R-19326-44825 The "PRAGMA data_version" value is a local # property of each database connection and so values returned by two # concurrent invocations of "PRAGMA data_version" on separate database # connections are often different even though the underlying database is # identical. # do_test pragma3-195 { expr {[db eval {PRAGMA data_version}]!=[db2 eval {PRAGMA data_version}]} } {1} # EVIDENCE-OF: R-54562-06892 The behavior of "PRAGMA data_version" is # the same for all database connections, including database connections # in separate processes and shared cache database connections. # # The next block checks the behavior for separate processes. # do_test pragma3-200 { db eval {PRAGMA data_version; SELECT * FROM t1;} } {2 101 201 301 401 555} do_test pragma3-201 { set fd [open pragma3.txt wb] puts $fd { sqlite3 db test.db; db eval {DELETE FROM t1 WHERE a>300}; db close; exit; } close $fd exec [info nameofexec] pragma3.txt forcedelete pragma3.txt db eval { PRAGMA data_version; SELECT * FROM t1; } } {3 101 201} db2 close db close # EVIDENCE-OF: R-54562-06892 The behavior of "PRAGMA data_version" is # the same for all database connections, including database connections # in separate processes and shared cache database connections. # # The next block checks that behavior is the same for shared-cache. # ifcapable shared_cache { set ::enable_shared_cache [sqlite3_enable_shared_cache 1] sqlite3 db test.db sqlite3 db2 test.db do_test pragma3-300 { db eval { PRAGMA data_version; BEGIN; CREATE TABLE t3(a,b,c); CREATE TABLE t4(x,y,z); INSERT INTO t4 VALUES(123,456,789); PRAGMA data_version; COMMIT; PRAGMA data_version; } } {1 1 1} do_test pragma3-310 { db2 eval { PRAGMA data_version; BEGIN; INSERT INTO t3(a,b,c) VALUES('abc','def','ghi'); SELECT * FROM t3; PRAGMA data_version; } } {2 abc def ghi 2} # The transaction in db2 has not yet committed, so the data_version in # db is unchanged. do_test pragma3-320 { db eval { PRAGMA data_version; SELECT * FROM t4; } } {1 123 456 789} do_test pragma3-330 { db2 eval { COMMIT; PRAGMA data_version; SELECT * FROM t4; } } {2 123 456 789} do_test pragma3-340 { db eval { PRAGMA data_version; SELECT * FROM t3; SELECT * FROM t4; } } {2 abc def ghi 123 456 789} db2 close db close sqlite3_enable_shared_cache $::enable_shared_cache } # Make sure this also works in WAL mode # ifcapable wal { sqlite3 db test.db db eval {PRAGMA journal_mode=WAL} sqlite3 db2 test.db do_test pragma3-400 { db eval { PRAGMA data_version; PRAGMA journal_mode; SELECT * FROM t1; } } {2 wal 101 201} do_test pragma3-410 { db2 eval { PRAGMA data_version; PRAGMA journal_mode; SELECT * FROM t1; } } {2 wal 101 201} do_test pragma3-420 { db eval {UPDATE t1 SET a=111*(a/100); PRAGMA data_version; SELECT * FROM t1} } {2 111 222} do_test pragma3-430 { db2 eval {PRAGMA data_version; SELECT * FROM t1;} } {3 111 222} db2 close } finish_test |