Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge the fix to ticket [f7b4edece25c99485] into the sessions branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | sessions |
Files: | files | file ages | folders |
SHA1: |
1b736ac2934f2361dee5062e9033cbf2 |
User & Date: | drh 2011-03-19 02:37:38.712 |
Context
2011-03-19
| ||
08:38 | Fix a problem with INTEGER PRIMARY KEY columns and the pre-update hook. (check-in: 24d4d5dd00 user: dan tags: sessions) | |
02:37 | Merge the fix to ticket [f7b4edece25c99485] into the sessions branch. (check-in: 1b736ac293 user: drh tags: sessions) | |
02:04 | Add a test case to verify that ticket [f7b4edece25c994857] is fixed. (check-in: eedbcf0a0b user: drh tags: trunk) | |
2011-03-18
| ||
18:03 | Hold the database mutex for the duration of an sqlite3changeset_apply() call. Also for the duration of all sqlite3session_xxx() calls. (check-in: c615c38c32 user: dan tags: sessions) | |
Changes
install-sh became executable.
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
152 153 154 155 156 157 158 | int iDb; sqlite3VdbeJumpHere(v, pParse->cookieGoto-1); for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ if( (mask & pParse->cookieMask)==0 ) continue; sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0); if( db->init.busy==0 ){ | > | > | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | int iDb; sqlite3VdbeJumpHere(v, pParse->cookieGoto-1); for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ if( (mask & pParse->cookieMask)==0 ) continue; sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0); if( db->init.busy==0 ){ sqlite3VdbeAddOp3(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb], db->aDb[iDb].pSchema->iGeneration); } } #ifndef SQLITE_OMIT_VIRTUALTABLE { int i; for(i=0; i<pParse->nVtabLock; i++){ char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); |
︙ | ︙ |
Changes to src/callback.c.
︙ | ︙ | |||
423 424 425 426 427 428 429 | for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ Table *pTab = sqliteHashData(pElem); sqlite3DeleteTable(0, pTab); } sqlite3HashClear(&temp1); sqlite3HashClear(&pSchema->fkeyHash); pSchema->pSeqTab = 0; | > > | > | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 | for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ Table *pTab = sqliteHashData(pElem); sqlite3DeleteTable(0, pTab); } sqlite3HashClear(&temp1); sqlite3HashClear(&pSchema->fkeyHash); pSchema->pSeqTab = 0; if( pSchema->flags & DB_SchemaLoaded ){ pSchema->iGeneration++; pSchema->flags &= ~DB_SchemaLoaded; } } /* ** Find and return the schema associated with a BTree. Create ** a new one if necessary. */ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
668 669 670 671 672 673 674 675 676 677 678 679 680 681 | }; /* ** An instance of the following structure stores a database schema. */ struct Schema { int schema_cookie; /* Database schema version number for this file */ Hash tblHash; /* All tables indexed by name */ Hash idxHash; /* All (named) indices indexed by name */ Hash trigHash; /* All triggers indexed by name */ Hash fkeyHash; /* All foreign keys by referenced table name */ Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ u8 file_format; /* Schema format version for this file */ u8 enc; /* Text encoding used by this database */ | > | 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 | }; /* ** An instance of the following structure stores a database schema. */ struct Schema { int schema_cookie; /* Database schema version number for this file */ int iGeneration; /* Generation counter. Incremented with each change */ Hash tblHash; /* All tables indexed by name */ Hash idxHash; /* All (named) indices indexed by name */ Hash trigHash; /* All triggers indexed by name */ Hash fkeyHash; /* All foreign keys by referenced table name */ Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ u8 file_format; /* Schema format version for this file */ u8 enc; /* Text encoding used by this database */ |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
2886 2887 2888 2889 2890 2891 2892 | ** schema is changed. Ticket #1644 */ sqlite3ExpirePreparedStatements(db); p->expired = 0; } break; } | | | > > > > > | | 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 | ** schema is changed. Ticket #1644 */ sqlite3ExpirePreparedStatements(db); p->expired = 0; } break; } /* Opcode: VerifyCookie P1 P2 P3 * * ** ** Check the value of global database parameter number 0 (the ** schema version) and make sure it is equal to P2 and that the ** generation counter on the local schema parse equals P3. ** ** P1 is the database number which is 0 for the main database file ** and 1 for the file holding temporary tables and some higher number ** for auxiliary databases. ** ** The cookie changes its value whenever the database schema changes. ** This operation is used to detect when that the cookie has changed ** and that the current process needs to reread the schema. ** ** Either a transaction needs to have been started or an OP_Open needs ** to be executed (to establish a read lock) before this opcode is ** invoked. */ case OP_VerifyCookie: { int iMeta; int iGen; Btree *pBt; assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( (p->btreeMask & (1<<pOp->p1))!=0 ); pBt = db->aDb[pOp->p1].pBt; if( pBt ){ sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); iGen = db->aDb[pOp->p1].pSchema->iGeneration; }else{ iMeta = 0; } if( iMeta!=pOp->p2 || iGen!=pOp->p3 ){ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie ** stored with the in-memory representation of the schema, do ** not reload the schema from the database file. ** ** If virtual-tables are in use, this is not just an optimization. |
︙ | ︙ |
Changes to src/vdbeblob.c.
︙ | ︙ | |||
262 263 264 265 266 267 268 269 270 271 272 273 274 275 | /* Configure the OP_Transaction */ sqlite3VdbeChangeP1(v, 0, iDb); sqlite3VdbeChangeP2(v, 0, flags); /* Configure the OP_VerifyCookie */ sqlite3VdbeChangeP1(v, 1, iDb); sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie); /* Make sure a mutex is held on the table to be accessed */ sqlite3VdbeUsesBtree(v, iDb); /* Configure the OP_TableLock instruction */ #ifdef SQLITE_OMIT_SHARED_CACHE sqlite3VdbeChangeToNoop(v, 2, 1); | > | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | /* Configure the OP_Transaction */ sqlite3VdbeChangeP1(v, 0, iDb); sqlite3VdbeChangeP2(v, 0, flags); /* Configure the OP_VerifyCookie */ sqlite3VdbeChangeP1(v, 1, iDb); sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie); sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration); /* Make sure a mutex is held on the table to be accessed */ sqlite3VdbeUsesBtree(v, iDb); /* Configure the OP_TableLock instruction */ #ifdef SQLITE_OMIT_SHARED_CACHE sqlite3VdbeChangeToNoop(v, 2, 1); |
︙ | ︙ |
Changes to test/capi3.test.
︙ | ︙ | |||
647 648 649 650 651 652 653 | } {0} do_test capi3-6.1 { db cache flush sqlite3_close $DB } {SQLITE_BUSY} do_test capi3-6.2 { sqlite3_step $STMT | | | | | 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 | } {0} do_test capi3-6.1 { db cache flush sqlite3_close $DB } {SQLITE_BUSY} do_test capi3-6.2 { sqlite3_step $STMT } {SQLITE_ERROR} #check_data $STMT capi3-6.3 {INTEGER} {1} {1.0} {1} do_test capi3-6.3 { sqlite3_finalize $STMT } {SQLITE_SCHEMA} do_test capi3-6.4-misuse { db cache flush sqlite3_close $DB } {SQLITE_OK} db close # This procedure sets the value of the file-format in file 'test.db' |
︙ | ︙ |
test/progress.test became a regular file.
︙ | ︙ |
Added test/tkt-f7b4edec.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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | # 2011 March 18 # # 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. # # This file implements tests to verify that ticket # [f7b4edece25c994857dc139207f55a53c8319fae] has been fixed. # set testdir [file dirname $argv0] source $testdir/tester.tcl # Open two database connections to the same database file in # shared cache mode. Create update hooks that will fire on # each connection. # db close set ::enable_shared_cache [sqlite3_enable_shared_cache 1] sqlite3 db1 test.db sqlite3 db2 test.db unset -nocomplain HOOKS set HOOKS {} proc update_hook {args} { lappend ::HOOKS $args } db1 update_hook update_hook db2 update_hook update_hook # Create a prepared statement # do_test tkt-f7b4edec-1 { execsql { CREATE TABLE t1(x, y); } db1 execsql { INSERT INTO t1 VALUES(1, 2) } db1 set ::HOOKS } {{INSERT main t1 1}} # In the second database connection cause the schema to be reparsed # without changing the schema cookie. # set HOOKS {} do_test tkt-f7b4edec-2 { execsql { BEGIN; DROP TABLE t1; CREATE TABLE t1(x, y); ROLLBACK; } db2 set ::HOOKS } {} # Rerun the prepared statement that was created prior to the # schema reparse. Verify that the update-hook gives the correct # output. # set HOOKS {} do_test tkt-f7b4edec-3 { execsql { INSERT INTO t1 VALUES(1, 2) } db1 set ::HOOKS } {{INSERT main t1 2}} # Be sure to restore the original shared-cache mode setting before # returning. # db1 close db2 close sqlite3_enable_shared_cache $::enable_shared_cache finish_test |
tool/mkopts.tcl became a regular file.
︙ | ︙ |