Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch snapshot-cmp Excluding Merge-Ins
This is equivalent to a diff from 9efe2265b1 to 8fc834741b
2016-04-12
| ||
16:04 | Add the sqlite3_snapshot_cmp() interface (available only with SQLITE_ENABLE_SNAPSHOT). (check-in: 7e72896551 user: drh tags: trunk) | |
15:14 | Update the documentation for sqlite3_snapshot_cmp() to make the circumstances under which the comparison is valid clearer. Add tests for the same. (Closed-Leaf check-in: 8fc834741b user: dan tags: snapshot-cmp) | |
2016-04-11
| ||
22:23 | Fix typo in the MSVC makefile. (check-in: 3189a7f185 user: mistachkin tags: trunk) | |
19:59 | Add the sqlite3_snapshot_cmp() API. (check-in: c698a21af7 user: dan tags: snapshot-cmp) | |
19:01 | Performance optimization to sqlite3Dequote() and its callers. (check-in: 9efe2265b1 user: drh tags: trunk) | |
18:25 | Performance optimization for the sqlite3ExprListDelete() routine. (check-in: 2764aeaa11 user: drh tags: trunk) | |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 | ** The application must eventually free every [sqlite3_snapshot] object ** using this routine to avoid a memory leak. ** ** The [sqlite3_snapshot_free()] interface is only available when the ** SQLITE_ENABLE_SNAPSHOT compile-time option is used. */ SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 | ** The application must eventually free every [sqlite3_snapshot] object ** using this routine to avoid a memory leak. ** ** The [sqlite3_snapshot_free()] interface is only available when the ** SQLITE_ENABLE_SNAPSHOT compile-time option is used. */ SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); /* ** CAPI3REF: Compare the ages of two snapshot handles. ** EXPERIMENTAL ** ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages ** of two valid snapshot handles. ** ** If the two snapshot handles are not associated with the same database ** file, the result of the comparison is undefined. ** ** Additionally, the result of the comparison is only valid if both of the ** snapshot handles were obtained by calling sqlite3_snapshot_get() since the ** last time the wal file was deleted. The wal file is deleted when the ** database is changed back to rollback mode or when the number of database ** clients drops to zero. If either snapshot handle was obtained before the ** wal file was last deleted, the value returned by this function ** is undefined. ** ** Otherwise, this API returns a negative value if P1 refers to an older ** snapshot than P2, zero if the two handles refer to the same database ** snapshot, and a positive value if P1 is a newer snapshot than P2. */ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( sqlite3_snapshot *p1, sqlite3_snapshot *p2 ); /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 | } pSnapshot = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); sqlite3_snapshot_free(pSnapshot); return TCL_OK; } #endif /* SQLITE_ENABLE_SNAPSHOT */ /* ** Usage: sqlite3_next_stmt DB STMT ** ** Return the next statment in sequence after STMT. */ static int test_next_stmt( void * clientData, | > > > > > > > > > > > > > > > > > > > > > > > > > | 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 | } pSnapshot = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); sqlite3_snapshot_free(pSnapshot); return TCL_OK; } #endif /* SQLITE_ENABLE_SNAPSHOT */ #ifdef SQLITE_ENABLE_SNAPSHOT /* ** Usage: sqlite3_snapshot_cmp SNAPSHOT1 SNAPSHOT2 */ static int test_snapshot_cmp( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int res; sqlite3_snapshot *p1; sqlite3_snapshot *p2; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT1 SNAPSHOT2"); return TCL_ERROR; } p1 = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); p2 = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[2])); res = sqlite3_snapshot_cmp(p1, p2); Tcl_SetObjResult(interp, Tcl_NewIntObj(res)); return TCL_OK; } #endif /* SQLITE_ENABLE_SNAPSHOT */ /* ** Usage: sqlite3_next_stmt DB STMT ** ** Return the next statment in sequence after STMT. */ static int test_next_stmt( void * clientData, |
︙ | ︙ | |||
7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 | { "sqlite3_config_sqllog", test_config_sqllog, 0 }, #endif { "vfs_current_time_int64", vfsCurrentTimeInt64, 0 }, #ifdef SQLITE_ENABLE_SNAPSHOT { "sqlite3_snapshot_get", test_snapshot_get, 0 }, { "sqlite3_snapshot_open", test_snapshot_open, 0 }, { "sqlite3_snapshot_free", test_snapshot_free, 0 }, #endif }; static int bitmask_size = sizeof(Bitmask)*8; static int longdouble_size = sizeof(LONGDOUBLE_TYPE); int i; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; | > | 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 | { "sqlite3_config_sqllog", test_config_sqllog, 0 }, #endif { "vfs_current_time_int64", vfsCurrentTimeInt64, 0 }, #ifdef SQLITE_ENABLE_SNAPSHOT { "sqlite3_snapshot_get", test_snapshot_get, 0 }, { "sqlite3_snapshot_open", test_snapshot_open, 0 }, { "sqlite3_snapshot_free", test_snapshot_free, 0 }, { "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 }, #endif }; static int bitmask_size = sizeof(Bitmask)*8; static int longdouble_size = sizeof(LONGDOUBLE_TYPE); int i; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 | } /* Try to open on pSnapshot when the next read-transaction starts */ void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){ pWal->pSnapshot = (WalIndexHdr*)pSnapshot; } #endif /* SQLITE_ENABLE_SNAPSHOT */ #ifdef SQLITE_ENABLE_ZIPVFS /* ** If the argument is not NULL, it points to a Wal object that holds a ** read-lock. This function returns the database page-size if it is known, ** or zero if it is not (or if pWal is NULL). | > > > > > > > > > > > > > > > > > | 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 | } /* Try to open on pSnapshot when the next read-transaction starts */ void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){ pWal->pSnapshot = (WalIndexHdr*)pSnapshot; } /* ** Return a +ve value if snapshot p1 is newer than p2. A -ve value if ** p1 is older than p2 and zero if p1 and p2 are the same snapshot. */ int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){ WalIndexHdr *pHdr1 = (WalIndexHdr*)p1; WalIndexHdr *pHdr2 = (WalIndexHdr*)p2; /* aSalt[0] is a copy of the value stored in the wal file header. It ** is incremented each time the wal file is restarted. */ if( pHdr1->aSalt[0]<pHdr2->aSalt[0] ) return -1; if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1; if( pHdr1->mxFrame<pHdr2->mxFrame ) return -1; if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1; return 0; } #endif /* SQLITE_ENABLE_SNAPSHOT */ #ifdef SQLITE_ENABLE_ZIPVFS /* ** If the argument is not NULL, it points to a Wal object that holds a ** read-lock. This function returns the database page-size if it is known, ** or zero if it is not (or if pWal is NULL). |
︙ | ︙ |
Changes to test/snapshot.test.
︙ | ︙ | |||
360 361 362 363 364 365 366 367 368 | db2 close sqlite3 db2 test.db db2 eval "BEGIN" list [catch {sqlite3_snapshot_open db2 main $::snapshot} msg] $msg } {1 SQLITE_ERROR} sqlite3_snapshot_free $snapshot finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | db2 close sqlite3 db2 test.db db2 eval "BEGIN" list [catch {sqlite3_snapshot_open db2 main $::snapshot} msg] $msg } {1 SQLITE_ERROR} sqlite3_snapshot_free $snapshot #------------------------------------------------------------------------- # The following tests investigate the sqlite3_snapshot_cmp() API. # # Compare snapshots $p1 and $p2, checking that the result is $r. # proc do_snapshot_cmp_test {tn p1 p2 r} { uplevel [list do_test $tn.1 [list sqlite3_snapshot_cmp $p1 $p2] $r] uplevel [list do_test $tn.2 [list sqlite3_snapshot_cmp $p2 $p1] [expr $r*-1]] uplevel [list do_test $tn.3 [list sqlite3_snapshot_cmp $p1 $p1] 0] uplevel [list do_test $tn.4 [list sqlite3_snapshot_cmp $p2 $p2] 0] } catch { db2 close } reset_db do_execsql_test 7.1 { PRAGMA journal_mode = wal; CREATE TABLE t1(x); } wal do_test 7.1.2 { execsql { BEGIN ; PRAGMA application_id } set p1 [sqlite3_snapshot_get db main] execsql { INSERT INTO t1 VALUES(10); COMMIT; } execsql { BEGIN ; PRAGMA application_id } set p2 [sqlite3_snapshot_get db main] execsql COMMIT } {} do_snapshot_cmp_test 7.1.3 $p1 $p2 -1 sqlite3_snapshot_free $p1 sqlite3_snapshot_free $p2 do_execsql_test 7.2.1 { INSERT INTO t1 VALUES(11); INSERT INTO t1 VALUES(12); INSERT INTO t1 VALUES(13); BEGIN; PRAGMA application_id; } {0} do_test 7.2.2 { set p1 [sqlite3_snapshot_get db main] execsql { COMMIT; INSERT INTO t1 VALUES(14); PRAGMA wal_checkpoint; BEGIN; PRAGMA application_id; } set p2 [sqlite3_snapshot_get db main] execsql COMMIT } {} do_snapshot_cmp_test 7.2.3 $p1 $p2 -1 sqlite3_snapshot_free $p2 do_test 7.3.1 { execsql { INSERT INTO t1 VALUES(14); BEGIN; PRAGMA application_id; } set p2 [sqlite3_snapshot_get db main] execsql COMMIT } {} do_snapshot_cmp_test 7.3.2 $p1 $p2 -1 sqlite3_snapshot_free $p1 sqlite3_snapshot_free $p2 finish_test |