}
} {}
do_rbu_vacuum_test 1.10.2 $step
+
+ # Database with empty tables.
+ #
+ reset_db
+ do_execsql_test 1.11.1 {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
+ CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
+ CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
+ CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
+ INSERT INTO t4 VALUES(1, 2);
+ }
+ do_rbu_vacuum_test 1.11.2 $step
+ do_execsql_test 1.11.3 {
+ SELECT * FROM t1;
+ SELECT * FROM t2;
+ SELECT * FROM t3;
+ SELECT * FROM t4;
+ } {1 2}
+ reset_db
+ do_execsql_test 1.12.1 {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
+ CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
+ CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
+ CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
+ INSERT INTO t1 VALUES(1, 2);
+ }
+ do_rbu_vacuum_test 1.12.2 $step
+ do_execsql_test 1.12.3 {
+ SELECT * FROM t1;
+ SELECT * FROM t2;
+ SELECT * FROM t3;
+ SELECT * FROM t4;
+ } {1 2}
}
+set ::testprefix rbuvacuum
#-------------------------------------------------------------------------
# Test some error cases:
} {1 {SQLITE_BUSY - database modified during rbu vacuum}}
}
+#-------------------------------------------------------------------------
+# Test that a database that uses custom collation sequences can be RBU
+# vacuumed.
+#
+reset_db
+forcedelete state.db
+proc noop {args} {}
+proc length_cmp {x y} {
+ set n1 [string length $x]
+ set n2 [string length $y]
+ return [expr $n1 - $n2]
+}
+sqlite3_create_collation_v2 db length length_cmp noop
+
+do_execsql_test 3.0 {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
+ INSERT INTO t1 VALUES(1, 'i');
+ INSERT INTO t1 VALUES(2, 'iiii');
+ INSERT INTO t1 VALUES(3, 'ii');
+ INSERT INTO t1 VALUES(4, 'iii');
+ SELECT a FROM t1 ORDER BY b COLLATE length;
+} {1 3 4 2}
+do_execsql_test 3.1 {
+ CREATE INDEX i1 ON t1(b COLLATE length);
+}
+
+do_test 3.2 {
+ sqlite3rbu_vacuum rbu test.db state.db
+ while {[rbu step]=="SQLITE_OK"} {}
+ list [catch { rbu close } msg] $msg
+} {1 {SQLITE_ERROR - no such collation sequence: length}}
+
+do_test 3.3 {
+ sqlite3rbu_vacuum rbu test.db state.db
+ set db1 [rbu db 0]
+ sqlite3_create_collation_v2 $db1 length length_cmp noop
+ while {[rbu step]=="SQLITE_OK"} {}
+ list [catch { rbu close } msg] $msg
+} {1 {SQLITE_ERROR - no such collation sequence: length}}
+
+do_test 3.4 {
+ sqlite3rbu_vacuum rbu test.db state.db
+ set db1 [rbu db 1]
+ sqlite3_create_collation_v2 $db1 length length_cmp noop
+ while {[rbu step]=="SQLITE_OK"} {}
+ list [catch { rbu close } msg] $msg
+} {1 {SQLITE_ERROR - no such collation sequence: length}}
+
+do_test 3.5 {
+ sqlite3rbu_vacuum rbu test.db state.db
+ set db1 [rbu db 0]
+ set db2 [rbu db 1]
+
+ sqlite3_create_collation_v2 $db1 length length_cmp noop
+ sqlite3_create_collation_v2 $db2 length length_cmp noop
+
+ while {[rbu step]=="SQLITE_OK"} {}
+ list [catch { rbu close } msg] $msg
+} {0 SQLITE_DONE}
+
+
catch { db close }
finish_test
}
+/*
+** The second argument passed to this function is the name of a PRAGMA
+** setting - "page_size", "auto_vacuum", "user_version" or "application_id".
+** This function executes the following on sqlite3rbu.dbRbu:
+**
+** "PRAGMA main.$zPragma"
+**
+** where $zPragma is the string passed as the second argument, then
+** on sqlite3rbu.dbMain:
+**
+** "PRAGMA main.$zPragma = $val"
+**
+** where $val is the value returned by the first PRAGMA invocation.
+**
+** In short, it copies the value of the specified PRAGMA setting from
+** dbRbu to dbMain.
+*/
+static void rbuCopyPragma(sqlite3rbu *p, const char *zPragma){
+ if( p->rc==SQLITE_OK ){
+ sqlite3_stmt *pPragma = 0;
+ p->rc = prepareFreeAndCollectError(p->dbRbu, &pPragma, &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA main.%s", zPragma)
+ );
+ if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPragma) ){
+ p->rc = rbuMPrintfExec(p, p->dbMain, "PRAGMA main.%s = %d",
+ zPragma, sqlite3_column_int(pPragma, 0)
+ );
+ }
+ rbuFinalize(p, pPragma);
+ }
+}
+
+/*
+** The RBU handle passed as the only argument has just been opened and
+** the state database is empty. If this RBU handle was opened for an
+** RBU vacuum operation, create the schema in the target db.
+*/
+static void rbuCreateTargetSchema(sqlite3rbu *p){
+ sqlite3_stmt *pSql = 0;
+ sqlite3_stmt *pInsert = 0;
+
+ assert( rbuIsVacuum(p) );
+ p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg);
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg,
+ "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0"
+ " AND name!='sqlite_sequence' "
+ " ORDER BY type DESC"
+ );
+ }
+
+ while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
+ const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
+ p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg);
+ }
+ rbuFinalize(p, pSql);
+ if( p->rc!=SQLITE_OK ) return;
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg,
+ "SELECT * FROM sqlite_master WHERE rootpage=0 OR rootpage IS NULL"
+ );
+ }
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareAndCollectError(p->dbMain, &pInsert, &p->zErrmsg,
+ "INSERT INTO sqlite_master VALUES(?,?,?,?,?)"
+ );
+ }
+
+ while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
+ int i;
+ for(i=0; i<5; i++){
+ sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i));
+ }
+ sqlite3_step(pInsert);
+ p->rc = sqlite3_reset(pInsert);
+ }
+ if( p->rc==SQLITE_OK ){
+ p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg);
+ }
+
+ rbuFinalize(p, pSql);
+ rbuFinalize(p, pInsert);
+}
+
/*
** Step the RBU object.
*/
switch( p->eStage ){
case RBU_STAGE_OAL: {
RbuObjIter *pIter = &p->objiter;
+
+ /* If this is an RBU vacuum operation and the state table was empty
+ ** when this handle was opened, create the target database schema. */
+ if( rbuIsVacuum(p) && p->nProgress==0 && p->rc==SQLITE_OK ){
+ rbuCreateTargetSchema(p);
+ rbuCopyPragma(p, "user_version");
+ rbuCopyPragma(p, "application_id");
+ }
+
while( p->rc==SQLITE_OK && pIter->zTbl ){
if( pIter->bCleanup ){
}
}
-/*
-** The second argument passed to this function is the name of a PRAGMA
-** setting - "page_size", "auto_vacuum", "user_version" or "application_id".
-** This function executes the following on sqlite3rbu.dbRbu:
-**
-** "PRAGMA main.$zPragma"
-**
-** where $zPragma is the string passed as the second argument, then
-** on sqlite3rbu.dbMain:
-**
-** "PRAGMA main.$zPragma = $val"
-**
-** where $val is the value returned by the first PRAGMA invocation.
-**
-** In short, it copies the value of the specified PRAGMA setting from
-** dbRbu to dbMain.
-*/
-static void rbuCopyPragma(sqlite3rbu *p, const char *zPragma){
- if( p->rc==SQLITE_OK ){
- sqlite3_stmt *pPragma = 0;
- p->rc = prepareFreeAndCollectError(p->dbRbu, &pPragma, &p->zErrmsg,
- sqlite3_mprintf("PRAGMA main.%s", zPragma)
- );
- if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPragma) ){
- p->rc = rbuMPrintfExec(p, p->dbMain, "PRAGMA main.%s = %d",
- zPragma, sqlite3_column_int(pPragma, 0)
- );
- }
- rbuFinalize(p, pPragma);
- }
-}
-
-/*
-** The RBU handle passed as the only argument has just been opened and
-** the state database is empty. If this RBU handle was opened for an
-** RBU vacuum operation, create the schema in the target db.
-*/
-static void rbuCreateTargetSchema(sqlite3rbu *p){
- sqlite3_stmt *pSql = 0;
- sqlite3_stmt *pInsert = 0;
-
- assert( rbuIsVacuum(p) );
- p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg);
- if( p->rc==SQLITE_OK ){
- p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg,
- "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0"
- " AND name!='sqlite_sequence' "
- " ORDER BY type DESC"
- );
- }
-
- while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
- const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
- p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg);
- }
- rbuFinalize(p, pSql);
- if( p->rc!=SQLITE_OK ) return;
-
- if( p->rc==SQLITE_OK ){
- p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg,
- "SELECT * FROM sqlite_master WHERE rootpage=0 OR rootpage IS NULL"
- );
- }
-
- if( p->rc==SQLITE_OK ){
- p->rc = prepareAndCollectError(p->dbMain, &pInsert, &p->zErrmsg,
- "INSERT INTO sqlite_master VALUES(?,?,?,?,?)"
- );
- }
-
- while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
- int i;
- for(i=0; i<5; i++){
- sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i));
- }
- sqlite3_step(pInsert);
- p->rc = sqlite3_reset(pInsert);
- }
- if( p->rc==SQLITE_OK ){
- p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg);
- }
-
- rbuFinalize(p, pSql);
- rbuFinalize(p, pInsert);
-}
-
static sqlite3rbu *openRbuHandle(
const char *zTarget,
}
}
- /* If this is an RBU vacuum operation and the state table was empty
- ** when this handle was opened, create the target database schema. */
- if( p->rc==SQLITE_OK && pState->eStage==0 && rbuIsVacuum(p) ){
- rbuCreateTargetSchema(p);
- rbuCopyPragma(p, "user_version");
- rbuCopyPragma(p, "application_id");
- }
-
/* Point the object iterator at the first object */
if( p->rc==SQLITE_OK ){
p->rc = rbuObjIterFirst(p, &p->objiter);
-C When\schecking\sfor\sthe\sWHERE-clause\spush-down\soptimization,\sverify\sthat\nall\sterms\sof\sthe\scompound\sinner\sSELECT\sare\snon-aggregate,\snot\sjust\sthe\nlast\sterm.\s\sFix\sfor\sticket\s[f7f8c97e97597].
-D 2016-04-25T02:20:10.236
+C Update\sthe\sRBU\svacuum\scode\sso\sthat\sdatabases\sthat\suse\scustom\scollation\ssequences\scan\sbe\svacuumed.
+D 2016-04-25T19:25:12.645
F Makefile.in a905f3180accdafbd5a534bf26126ee5306d5056
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
-F ext/rbu/rbuvacuum.test bcbc1dcd8e2a46a811e46477692ae1c0e8917a85
-F ext/rbu/sqlite3rbu.c 20922328dcebe89589638923bb46840df8bc7733
+F ext/rbu/rbuvacuum.test 66e02cf299836770e718e95c36686be0b26dbda3
+F ext/rbu/sqlite3rbu.c bf36625990c6865ecf08bd844d8097ed2d0a6958
F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930
-F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4
+F ext/rbu/test_rbu.c 9bbdf6bd8efd58fbc4f192698df50569598fbb9e
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P d0a579b35105810821bbfec6b50ecfebac7a17ee
-R 858c551be0612332d0982a3a42946fb6
-U drh
-Z c1158477a3c6966fdb5709eb9b3c8fe5
+P ec215f94ac9748c0acd82af0cc9e7a92249462f9
+R c0a43d6aa5e9f6d906be746461438b7f
+U dan
+Z 33a592aa08c77e06ce6e19e096f78faa