Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Test interaction of incremental io and other database writes. (CVS 3922) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4516416b4d38679ea7d259155f241e54 |
User & Date: | danielk1977 2007-05-04 18:36:45.000 |
Context
2007-05-04
| ||
19:03 | Fix compilation and testing with OMIT_INCRBLOB defined. (CVS 3923) (check-in: a0f8adc692 user: danielk1977 tags: trunk) | |
18:36 | Test interaction of incremental io and other database writes. (CVS 3922) (check-in: 4516416b4d user: danielk1977 tags: trunk) | |
18:30 | Change incremental vacuum to be triggered by a pragma rather than a command. We have a lot to learn about this yet and we do not want to paint ourselves into a corner by commiting to specific syntax too early. (CVS 3921) (check-in: b13e497a32 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | 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. ** ************************************************************************* |
︙ | |||
391 392 393 394 395 396 397 | 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | - + | CellInfo info; /* A parse of the cell we are pointing at */ u8 wrFlag; /* True if writable */ u8 eState; /* One of the CURSOR_XXX constants (see below) */ void *pKey; /* Saved key that was cursor's last known position */ i64 nKey; /* Size of pKey, or last integer key */ int skip; /* (skip<0) -> Prev() is a no-op. (skip>0) -> Next() is */ #ifndef SQLITE_OMIT_INCRBLOB |
︙ | |||
761 762 763 764 765 766 767 768 769 770 771 772 773 774 | 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 | + + + | ** If the second argument argument - doSeek - is false, then instead of ** returning the cursor to it's saved position, any saved position is deleted ** and the cursor state set to CURSOR_INVALID. */ static int restoreOrClearCursorPositionX(BtCursor *pCur){ int rc; assert( pCur->eState==CURSOR_REQUIRESEEK ); if( pCur->isIncrblobHandle ){ return SQLITE_ABORT; } pCur->eState = CURSOR_INVALID; rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip); if( rc==SQLITE_OK ){ sqliteFree(pCur->pKey); pCur->pKey = 0; assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); } |
︙ | |||
3181 3182 3183 3184 3185 3186 3187 | 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 | - + | ** Data is read to or from the buffer pBuf. ** ** This routine does not make a distinction between key and data. ** It just reads or writes bytes from the payload area. Data might ** appear on the main page or be scattered out on multiple overflow ** pages. ** |
︙ | |||
3250 3251 3252 3253 3254 3255 3256 | 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 | - + - + | if( rc==SQLITE_OK && amt>0 ){ const int ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */ Pgno nextPage; nextPage = get4byte(&aPayload[pCur->info.nLocal]); #ifndef SQLITE_OMIT_INCRBLOB |
︙ | |||
6985 6986 6987 6988 6989 6990 6991 | 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 | - + + + + + + - - - - + + + - - - - - - + + | /* ** Argument pCsr must be a cursor opened for writing on an ** 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. */ |
︙ | |||
7023 7024 7025 7026 7027 7028 7029 | 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 | - + - + | ** ** This function sets a flag only. The actual page location cache ** (stored in BtCursor.aOverflow[]) is allocated and used by function ** accessPayload() (the worker function for sqlite3BtreeData() and ** sqlite3BtreePutData()). */ void sqlite3BtreeCacheOverflow(BtCursor *pCur){ |
︙ |
Changes to src/btree.h.
︙ | |||
9 10 11 12 13 14 15 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** |
︙ | |||
138 139 140 141 142 143 144 | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | - + | const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt); int sqlite3BtreeDataSize(BtCursor*, u32 *pSize); int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); struct Pager *sqlite3BtreePager(Btree*); |
︙ |
Changes to src/tclsqlite.c.
︙ | |||
8 9 10 11 12 13 14 | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | - + | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite. Append this file to sqlite3.c and ** compile the whole thing to build a TCL-enabled version of SQLite. ** |
︙ | |||
116 117 118 119 120 121 122 | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | - + - | SqlPreparedStmt *stmtLast; /* Last statement in the list */ int maxStmt; /* The next maximum number of stmtList */ int nStmt; /* Number of statements in stmtList */ IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */ }; struct IncrblobChannel { |
︙ |
Changes to src/test1.c.
︙ | |||
9 10 11 12 13 14 15 | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | - + | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** |
︙ | |||
1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 | 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(autoincrement)); Tcl_SetObjResult(interp, pRet); return TCL_OK; } #endif #ifndef SQLITE_OMIT_INCRBLOB /* ** sqlite3_blob_read CHANNEL OFFSET N */ static int test_blob_read( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ Tcl_Channel channel; ClientData instanceData; sqlite3_blob *pBlob; int notUsed; int nByte; int iOffset; unsigned char *zBuf; int rc; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET N"); return TCL_ERROR; } channel = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), ¬Used); if( !channel || TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) || TCL_OK!=Tcl_GetIntFromObj(interp, objv[3], &nByte) || nByte<0 || iOffset<0 ){ return TCL_ERROR; } instanceData = Tcl_GetChannelInstanceData(channel); pBlob = *((sqlite3_blob **)instanceData); zBuf = (unsigned char *)Tcl_Alloc(nByte); rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset); if( rc==SQLITE_OK ){ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zBuf, nByte)); }else{ Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); } Tcl_Free((char *)zBuf); return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); } /* ** sqlite3_blob_write CHANNEL OFFSET DATA */ static int test_blob_write( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ Tcl_Channel channel; ClientData instanceData; sqlite3_blob *pBlob; int notUsed; int iOffset; int rc; unsigned char *zBuf; int nBuf; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA"); return TCL_ERROR; } channel = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), ¬Used); if( !channel || TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) || iOffset<0 ){ return TCL_ERROR; } instanceData = Tcl_GetChannelInstanceData(channel); pBlob = *((sqlite3_blob **)instanceData); zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf); rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE); } return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); } #endif /* ** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC? */ static int test_load_extension( ClientData clientData, /* Not used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
︙ | |||
4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 | 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 | + + + + | #ifndef SQLITE_OMIT_SHARED_CACHE { "sqlite3_enable_shared_cache", test_enable_shared, 0 }, #endif { "sqlite3_libversion_number", test_libversion_number, 0 }, #ifdef SQLITE_ENABLE_COLUMN_METADATA { "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, #endif #ifndef SQLITE_OMIT_INCRBLOB { "sqlite3_blob_read", test_blob_read, 0 }, { "sqlite3_blob_write", test_blob_write, 0 }, #endif }; static int bitmask_size = sizeof(Bitmask)*8; int i; extern int sqlite3_os_trace; extern int sqlite3_where_trace; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; |
︙ |
Changes to src/vdbeblob.c.
1 2 3 4 5 6 7 8 9 10 11 12 | 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. ** ************************************************************************* ** |
︙ | |||
240 241 242 243 244 245 246 | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | - - - - - + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + - - + + + + + + + + + + + - - - - - + - - - | int sqlite3_blob_close(sqlite3_blob *pBlob){ Incrblob *p = (Incrblob *)pBlob; sqlite3_stmt *pStmt = p->pStmt; sqliteFree(p); return sqlite3_finalize(pStmt); } |
Changes to test/incrblob.test.
1 2 3 4 5 6 7 8 9 10 11 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | - + | # 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. # #*********************************************************************** # |
︙ | |||
198 199 200 201 202 203 204 | 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 | - - - - + + + + + + + + + + + + + | } #------------------------------------------------------------------------ # incrblob-3.*: # # Test the outcome of trying to write to a read-only blob handle. # |
︙ | |||
383 384 385 386 387 388 389 | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | - | do_test incrblob-6.7 { set ::blob [db2 incrblob blobs i 4] gets $::blob } {connection} do_test incrblob-6.8 { tell $::blob } {10} |
︙ | |||
421 422 423 424 425 426 427 428 | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | do_test incrblob-6.14 { execsql { SELECT * FROM blobs WHERE rowid = 4; } } {a different invocation} db2 close #----------------------------------------------------------------------- # The following tests verify the behaviour of the incremental IO # APIs in the following cases: # # 7.1 A row that containing an open blob is modified. # # 7.2 A CREATE TABLE requires that an overflow page that is part # of an open blob is moved. # # 7.3 An INCREMENTAL VACUUM moves an overflow page that is part # of an open blob. # # In the first case above, correct behaviour is for all subsequent # read/write operations on the blob-handle to return SQLITE_ABORT. # More accurately, blob-handles are invalidated whenever the table # they belong to is written to. # # The second two cases have no external effect. They are testing # that the internal cache of overflow page numbers is correctly # invalidated. # do_test incrblob-7.1.0 { execsql { BEGIN; DROP TABLE blobs; CREATE TABLE t1 (a, b, c, d BLOB); INSERT INTO t1(a, b, c, d) VALUES(1, 2, 3, 4); COMMIT; } } {} foreach {tn arg} {1 "" 2 -readonly} { execsql { UPDATE t1 SET d = zeroblob(10000); } do_test incrblob-7.1.$tn.1 { set ::b [eval db incrblob $arg t1 d 1] binary scan [sqlite3_blob_read $::b 5000 5] c* c set c } {0 0 0 0 0} do_test incrblob-7.1.$tn.2 { execsql { UPDATE t1 SET d = 15; } } {} do_test incrblob-7.1.$tn.3 { set rc [catch { sqlite3_blob_read $::b 5000 5 } msg] list $rc $msg } {1 SQLITE_ABORT} do_test incrblob-7.1.$tn.4 { execsql { SELECT d FROM t1; } } {15} do_test incrblob-7.1.$tn.5 { set rc [catch { close $::b } msg] list $rc $msg } {0 {}} do_test incrblob-7.1.$tn.6 { execsql { SELECT d FROM t1; } } {15} } set fd [open [info script]] set ::data [read $fd] close $fd db close file delete -force test.db test.db-journal sqlite3 db test.db do_test incrblob-7.2.1 { execsql { PRAGMA auto_vacuum = "incremental"; CREATE TABLE t1(a INTEGER PRIMARY KEY, b); -- root@page3 INSERT INTO t1 VALUES(123, $::data); } set ::b [db incrblob -readonly t1 b 123] read $::b } $::data do_test incrblob-7.2.2 { execsql { CREATE TABLE t2(a INTEGER PRIMARY KEY, b); -- root@page4 } seek $::b 0 read $::b } $::data do_test incrblob-7.2.3 { close $::b execsql { SELECT rootpage FROM sqlite_master; } } {3 4} set ::otherdata "[string range $::data 0 1000][string range $::data 1001 end]" do_test incrblob-7.3.1 { execsql { INSERT INTO t2 VALUES(456, $::otherdata); } set ::b [db incrblob -readonly t2 b 456] read $::b } $::otherdata do_test incrblob-7.3.2 { expr [file size test.db]/1024 } 30 do_test incrblob-7.3.3 { execsql { DELETE FROM t1 WHERE a = 123; INCREMENTAL VACUUM; } seek $::b 0 read $::b } $::otherdata finish_test |