Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Minor bugfixes for incrblob mode. (CVS 3903) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
db54a9466e3bea9c03740ce0b755cfa0 |
User & Date: | danielk1977 2007-05-03 11:43:33.000 |
Context
2007-05-03
| ||
11:43 | Minor bugfixes for incrblob mode. (CVS 3904) (check-in: b84d597c90 user: danielk1977 tags: trunk) | |
11:43 | Minor bugfixes for incrblob mode. (CVS 3903) (check-in: db54a9466e user: danielk1977 tags: trunk) | |
2007-05-02
| ||
17:54 | Allow CREATE TABLE to occur while other queries are running. DROP TABLE is still prohibited, however, since we do not want to delete a table out from under an running query. (CVS 3902) (check-in: 5b4bf1fce4 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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 19 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.369 2007/05/03 11:43:33 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
3101 3102 3103 3104 3105 3106 3107 | Pgno iGuess = ovfl+1; u8 eType; while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){ iGuess++; } | | | 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 | Pgno iGuess = ovfl+1; u8 eType; while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){ iGuess++; } if( iGuess<=sqlite3PagerPagecount(pBt->pPager) ){ rc = ptrmapGet(pBt, iGuess, &eType, &pgno); if( rc!=SQLITE_OK ){ return rc; } if( eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){ next = iGuess; } |
︙ | ︙ | |||
5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 | #ifdef SQLITE_OMIT_AUTOVACUUM rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); if( rc ) return rc; #else if( pBt->autoVacuum ){ Pgno pgnoMove; /* Move a page here to make room for the root-page */ MemPage *pPageMove; /* The page to move to. */ /* Read the value of meta[3] from the database to determine where the ** 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). */ rc = sqlite3BtreeGetMeta(p, 4, &pgnoRoot); if( rc!=SQLITE_OK ) return rc; | > > > > > > > > > > > > > | 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 | #ifdef SQLITE_OMIT_AUTOVACUUM rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); if( rc ) return rc; #else if( pBt->autoVacuum ){ Pgno pgnoMove; /* Move a page here to make room for the root-page */ MemPage *pPageMove; /* The page to move to. */ #ifndef SQLITE_OMIT_INCRBLOB /* Creating a new table may probably require moving an existing database ** to make room for the new tables root page. In case this page turns ** out to be an overflow page, delete all overflow page-map caches ** held by open cursors. */ BtCursor *pCur; for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ sqliteFree(pCur->aOverflow); pCur->aOverflow = 0; } #endif /* Read the value of meta[3] from the database to determine where the ** 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). */ rc = sqlite3BtreeGetMeta(p, 4, &pgnoRoot); if( rc!=SQLITE_OK ) return rc; |
︙ | ︙ | |||
6939 6940 6941 6942 6943 6944 6945 | ** INTKEY table currently pointing at a valid table entry. ** This function modifies the data stored as part of that entry. ** Only the data content may only be modified, it is not possible ** to change the length of the data stored. */ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, const void *z){ BtShared *pBt = pCsr->pBtree->pBt; | < < < < < < < < < < < | 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 | ** INTKEY table currently pointing at a valid table entry. ** This function modifies the data stored as part of that entry. ** Only the data content may only be modified, it is not possible ** to change the length of the data stored. */ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, const void *z){ BtShared *pBt = pCsr->pBtree->pBt; /* Check some preconditions: ** (a) a write-transaction is open, ** (b) the cursor is open for writing, ** (c) there is no read-lock on the table being modified and ** (d) the cursor points at a valid row of an intKey table. */ |
︙ | ︙ |
Changes to src/vdbeblob.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* ** 2007 May 1 ** ** 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 19 20 | /* ** 2007 May 1 ** ** 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. ** ************************************************************************* ** ** $Id: vdbeblob.c,v 1.3 2007/05/03 11:43:33 danielk1977 Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #ifndef SQLITE_OMIT_INCRBLOB |
︙ | ︙ | |||
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 | do { Parse sParse; Table *pTab; memset(&sParse, 0, sizeof(Parse)); sParse.db = db; pTab = sqlite3LocateTable(&sParse, zTable, zDb); if( !pTab ){ sqlite3Error(db, sParse.rc, "%s", sParse.zErrMsg); sqliteFree(sParse.zErrMsg); rc = sParse.rc; goto blob_open_out; } /* Now search pTab for the exact column. */ for(iCol=0; iCol < pTab->nCol; iCol++) { if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ break; } } if( iCol==pTab->nCol ){ sqlite3Error(db, SQLITE_ERROR, "no such column: %s", zColumn); sqliteFree(sParse.zErrMsg); rc = SQLITE_ERROR; goto blob_open_out; } v = sqlite3VdbeCreate(db); if( v ){ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob); | > > > > > > > | 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 | do { Parse sParse; Table *pTab; memset(&sParse, 0, sizeof(Parse)); sParse.db = db; rc = sqlite3SafetyOn(db); if( rc!=SQLITE_OK ){ return rc; } pTab = sqlite3LocateTable(&sParse, zTable, zDb); if( !pTab ){ sqlite3Error(db, sParse.rc, "%s", sParse.zErrMsg); sqliteFree(sParse.zErrMsg); rc = sParse.rc; sqlite3SafetyOff(db); goto blob_open_out; } /* Now search pTab for the exact column. */ for(iCol=0; iCol < pTab->nCol; iCol++) { if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ break; } } if( iCol==pTab->nCol ){ sqlite3Error(db, SQLITE_ERROR, "no such column: %s", zColumn); sqliteFree(sParse.zErrMsg); rc = SQLITE_ERROR; sqlite3SafetyOff(db); goto blob_open_out; } v = sqlite3VdbeCreate(db); if( v ){ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob); |
︙ | ︙ | |||
140 141 142 143 144 145 146 147 148 149 150 151 152 153 | ** always return an SQL NULL. This is useful because it means ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ sqlite3VdbeChangeP2(v, 5, pTab->nCol+1); sqlite3VdbeMakeReady(v, 1, 0, 1, 0); } sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow); rc = sqlite3_step((sqlite3_stmt *)v); if( rc!=SQLITE_ROW ){ nAttempt++; rc = sqlite3_finalize((sqlite3_stmt *)v); v = 0; | > > > > > | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | ** always return an SQL NULL. This is useful because it means ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ sqlite3VdbeChangeP2(v, 5, pTab->nCol+1); sqlite3VdbeMakeReady(v, 1, 0, 1, 0); } rc = sqlite3SafetyOff(db); if( rc!=SQLITE_OK ){ return rc; } sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow); rc = sqlite3_step((sqlite3_stmt *)v); if( rc!=SQLITE_ROW ){ nAttempt++; rc = sqlite3_finalize((sqlite3_stmt *)v); v = 0; |
︙ | ︙ |
Changes to test/incrblob.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2007 May 1 # # 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 19 20 | # 2007 May 1 # # 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. # #*********************************************************************** # # $Id: incrblob.test,v 1.3 2007/05/03 11:43:35 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl do_test incrblob-1.1 { execsql { CREATE TABLE blobs(k PRIMARY KEY, v BLOB); |
︙ | ︙ | |||
45 46 47 48 49 50 51 | do_test incrblob-1.2.6 { execsql { SELECT v FROM blobs WHERE rowid = 1; } } {1234567890} #-------------------------------------------------------------------- | | > | | < | < | > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > | > > | > > > | > > | 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 | do_test incrblob-1.2.6 { execsql { SELECT v FROM blobs WHERE rowid = 1; } } {1234567890} #-------------------------------------------------------------------- # Test cases incrblob-1.3.X check that it is possible to read and write # regions of a blob that lie on overflow pages. # do_test incrblob-1.3.1 { set ::str "[string repeat . 10000]" execsql { INSERT INTO blobs(rowid, k, v) VALUES(3, 'three', $::str); } } {} do_test incrblob-1.3.2 { set ::blob [db incrblob blobs v 3] seek $::blob 8500 read $::blob 10 } {..........} do_test incrblob-1.3.3 { seek $::blob 8500 puts -nonewline $::blob 1234567890 } {} do_test incrblob-1.3.4 { seek $::blob 8496 read $::blob 10 } {....123456} do_test incrblob-1.3.10 { close $::blob } {} #------------------------------------------------------------------------ # incrblob-2.*: Test seeking in an incremental blob can use ptrmap pages. # proc nRead {db} { set bt [btree_from_db $db] array set stats [btree_pager_stats $bt] return $stats(read) } foreach AutoVacuumMode [list 0 1] { db close file delete -force test.db test.db-journal sqlite3 db test.db execsql "PRAGMA auto_vacuum = $AutoVacuumMode" do_test incrblob-2.$AutoVacuumMode.1 { set ::str [string repeat abcdefghij 2900] execsql { BEGIN; CREATE TABLE blobs(k PRIMARY KEY, v BLOB); DELETE FROM blobs; INSERT INTO blobs VALUES('one', $::str || randstr(500,500)); COMMIT; } expr [file size test.db]/1024 } [expr 31 + $AutoVacuumMode] do_test incrblob-2.$AutoVacuumMode.2 { execsql { PRAGMA auto_vacuum; } } $AutoVacuumMode do_test incrblob-2.$AutoVacuumMode.3 { # Open and close the db to make sure the page cache is empty. db close sqlite3 db test.db # Read the last 20 bytes of the blob via a blob handle. set ::blob [db incrblob blobs v 1] seek $::blob -20 end set ::fragment [read $::blob] close $::blob # If the database is not in auto-vacuum mode, the whole of # the overflow-chain must be scanned. In auto-vacuum mode, # sqlite uses the ptrmap pages to avoid reading the other pages. # nRead db } [expr $AutoVacuumMode ? 4 : 30] do_test incrblob-2.3 { string range [db one {SELECT v FROM blobs}] end-19 end } $::fragment } finish_test |