Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: third_party/sqlite/src/ext/rbu/sqlite3rbu.c

Issue 2751253002: [sql] Import SQLite 3.17.0. (Closed)
Patch Set: also clang on Linux i386 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/sqlite/src/ext/rbu/sqlite3rbu.h ('k') | third_party/sqlite/src/ext/rbu/test_rbu.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ** 2014 August 30 2 ** 2014 August 30
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 ** middle of an incremental checkpoint (an incremental checkpoint cannot 140 ** middle of an incremental checkpoint (an incremental checkpoint cannot
141 ** be continued if this happens). 141 ** be continued if this happens).
142 ** 142 **
143 ** RBU_STATE_COOKIE: 143 ** RBU_STATE_COOKIE:
144 ** Valid if STAGE==1. The current change-counter cookie value in the 144 ** Valid if STAGE==1. The current change-counter cookie value in the
145 ** target db file. 145 ** target db file.
146 ** 146 **
147 ** RBU_STATE_OALSZ: 147 ** RBU_STATE_OALSZ:
148 ** Valid if STAGE==1. The size in bytes of the *-oal file. 148 ** Valid if STAGE==1. The size in bytes of the *-oal file.
149 */ 149 */
150 #define RBU_STATE_STAGE 1 150 #define RBU_STATE_STAGE 1
151 #define RBU_STATE_TBL 2 151 #define RBU_STATE_TBL 2
152 #define RBU_STATE_IDX 3 152 #define RBU_STATE_IDX 3
153 #define RBU_STATE_ROW 4 153 #define RBU_STATE_ROW 4
154 #define RBU_STATE_PROGRESS 5 154 #define RBU_STATE_PROGRESS 5
155 #define RBU_STATE_CKPT 6 155 #define RBU_STATE_CKPT 6
156 #define RBU_STATE_COOKIE 7 156 #define RBU_STATE_COOKIE 7
157 #define RBU_STATE_OALSZ 8 157 #define RBU_STATE_OALSZ 8
158 #define RBU_STATE_PHASEONESTEP 9
158 159
159 #define RBU_STAGE_OAL 1 160 #define RBU_STAGE_OAL 1
160 #define RBU_STAGE_MOVE 2 161 #define RBU_STAGE_MOVE 2
161 #define RBU_STAGE_CAPTURE 3 162 #define RBU_STAGE_CAPTURE 3
162 #define RBU_STAGE_CKPT 4 163 #define RBU_STAGE_CKPT 4
163 #define RBU_STAGE_DONE 5 164 #define RBU_STAGE_DONE 5
164 165
165 166
166 #define RBU_CREATE_STATE \ 167 #define RBU_CREATE_STATE \
167 "CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)" 168 "CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)"
168 169
169 typedef struct RbuFrame RbuFrame; 170 typedef struct RbuFrame RbuFrame;
170 typedef struct RbuObjIter RbuObjIter; 171 typedef struct RbuObjIter RbuObjIter;
171 typedef struct RbuState RbuState; 172 typedef struct RbuState RbuState;
172 typedef struct rbu_vfs rbu_vfs; 173 typedef struct rbu_vfs rbu_vfs;
173 typedef struct rbu_file rbu_file; 174 typedef struct rbu_file rbu_file;
174 typedef struct RbuUpdateStmt RbuUpdateStmt; 175 typedef struct RbuUpdateStmt RbuUpdateStmt;
175 176
176 #if !defined(SQLITE_AMALGAMATION) 177 #if !defined(SQLITE_AMALGAMATION)
177 typedef unsigned int u32; 178 typedef unsigned int u32;
179 typedef unsigned short u16;
178 typedef unsigned char u8; 180 typedef unsigned char u8;
179 typedef sqlite3_int64 i64; 181 typedef sqlite3_int64 i64;
180 #endif 182 #endif
181 183
182 /* 184 /*
183 ** These values must match the values defined in wal.c for the equivalent 185 ** These values must match the values defined in wal.c for the equivalent
184 ** locks. These are not magic numbers as they are part of the SQLite file 186 ** locks. These are not magic numbers as they are part of the SQLite file
185 ** format. 187 ** format.
186 */ 188 */
187 #define WAL_LOCK_WRITE 0 189 #define WAL_LOCK_WRITE 0
188 #define WAL_LOCK_CKPT 1 190 #define WAL_LOCK_CKPT 1
189 #define WAL_LOCK_READ0 3 191 #define WAL_LOCK_READ0 3
190 192
193 #define SQLITE_FCNTL_RBUCNT 5149216
194
191 /* 195 /*
192 ** A structure to store values read from the rbu_state table in memory. 196 ** A structure to store values read from the rbu_state table in memory.
193 */ 197 */
194 struct RbuState { 198 struct RbuState {
195 int eStage; 199 int eStage;
196 char *zTbl; 200 char *zTbl;
197 char *zIdx; 201 char *zIdx;
198 i64 iWalCksum; 202 i64 iWalCksum;
199 int nRow; 203 int nRow;
200 i64 nProgress; 204 i64 nProgress;
201 u32 iCookie; 205 u32 iCookie;
202 i64 iOalSz; 206 i64 iOalSz;
207 i64 nPhaseOneStep;
203 }; 208 };
204 209
205 struct RbuUpdateStmt { 210 struct RbuUpdateStmt {
206 char *zMask; /* Copy of update mask used with pUpdate */ 211 char *zMask; /* Copy of update mask used with pUpdate */
207 sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ 212 sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */
208 RbuUpdateStmt *pNext; 213 RbuUpdateStmt *pNext;
209 }; 214 };
210 215
211 /* 216 /*
212 ** An iterator of this type is used to iterate through all objects in 217 ** An iterator of this type is used to iterate through all objects in
(...skipping 24 matching lines...) Expand all
237 int eType; /* Table type - an RBU_PK_XXX value */ 242 int eType; /* Table type - an RBU_PK_XXX value */
238 243
239 /* Output variables. zTbl==0 implies EOF. */ 244 /* Output variables. zTbl==0 implies EOF. */
240 int bCleanup; /* True in "cleanup" state */ 245 int bCleanup; /* True in "cleanup" state */
241 const char *zTbl; /* Name of target db table */ 246 const char *zTbl; /* Name of target db table */
242 const char *zDataTbl; /* Name of rbu db table (or null) */ 247 const char *zDataTbl; /* Name of rbu db table (or null) */
243 const char *zIdx; /* Name of target db index (or null) */ 248 const char *zIdx; /* Name of target db index (or null) */
244 int iTnum; /* Root page of current object */ 249 int iTnum; /* Root page of current object */
245 int iPkTnum; /* If eType==EXTERNAL, root of PK index */ 250 int iPkTnum; /* If eType==EXTERNAL, root of PK index */
246 int bUnique; /* Current index is unique */ 251 int bUnique; /* Current index is unique */
252 int nIndex; /* Number of aux. indexes on table zTbl */
247 253
248 /* Statements created by rbuObjIterPrepareAll() */ 254 /* Statements created by rbuObjIterPrepareAll() */
249 int nCol; /* Number of columns in current object */ 255 int nCol; /* Number of columns in current object */
250 sqlite3_stmt *pSelect; /* Source data */ 256 sqlite3_stmt *pSelect; /* Source data */
251 sqlite3_stmt *pInsert; /* Statement for INSERT operations */ 257 sqlite3_stmt *pInsert; /* Statement for INSERT operations */
252 sqlite3_stmt *pDelete; /* Statement for DELETE ops */ 258 sqlite3_stmt *pDelete; /* Statement for DELETE ops */
253 sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */ 259 sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */
254 260
255 /* Last UPDATE used (for PK b-tree updates only), or NULL. */ 261 /* Last UPDATE used (for PK b-tree updates only), or NULL. */
256 RbuUpdateStmt *pRbuUpdate; 262 RbuUpdateStmt *pRbuUpdate;
(...skipping 16 matching lines...) Expand all
273 #define RBU_PK_WITHOUT_ROWID 4 279 #define RBU_PK_WITHOUT_ROWID 4
274 #define RBU_PK_VTAB 5 280 #define RBU_PK_VTAB 5
275 281
276 282
277 /* 283 /*
278 ** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs 284 ** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs
279 ** one of the following operations. 285 ** one of the following operations.
280 */ 286 */
281 #define RBU_INSERT 1 /* Insert on a main table b-tree */ 287 #define RBU_INSERT 1 /* Insert on a main table b-tree */
282 #define RBU_DELETE 2 /* Delete a row from a main table b-tree */ 288 #define RBU_DELETE 2 /* Delete a row from a main table b-tree */
283 #define RBU_IDX_DELETE 3 /* Delete a row from an aux. index b-tree */ 289 #define RBU_REPLACE 3 /* Delete and then insert a row */
284 #define RBU_IDX_INSERT 4 /* Insert on an aux. index b-tree */ 290 #define RBU_IDX_DELETE 4 /* Delete a row from an aux. index b-tree */
285 #define RBU_UPDATE 5 /* Update a row in a main table b-tree */ 291 #define RBU_IDX_INSERT 5 /* Insert on an aux. index b-tree */
286 292
293 #define RBU_UPDATE 6 /* Update a row in a main table b-tree */
287 294
288 /* 295 /*
289 ** A single step of an incremental checkpoint - frame iWalFrame of the wal 296 ** A single step of an incremental checkpoint - frame iWalFrame of the wal
290 ** file should be copied to page iDbPage of the database file. 297 ** file should be copied to page iDbPage of the database file.
291 */ 298 */
292 struct RbuFrame { 299 struct RbuFrame {
293 u32 iDbPage; 300 u32 iDbPage;
294 u32 iWalFrame; 301 u32 iWalFrame;
295 }; 302 };
296 303
297 /* 304 /*
298 ** RBU handle. 305 ** RBU handle.
306 **
307 ** nPhaseOneStep:
308 ** If the RBU database contains an rbu_count table, this value is set to
309 ** a running estimate of the number of b-tree operations required to
310 ** finish populating the *-oal file. This allows the sqlite3_bp_progress()
311 ** API to calculate the permyriadage progress of populating the *-oal file
312 ** using the formula:
313 **
314 ** permyriadage = (10000 * nProgress) / nPhaseOneStep
315 **
316 ** nPhaseOneStep is initialized to the sum of:
317 **
318 ** nRow * (nIndex + 1)
319 **
320 ** for all source tables in the RBU database, where nRow is the number
321 ** of rows in the source table and nIndex the number of indexes on the
322 ** corresponding target database table.
323 **
324 ** This estimate is accurate if the RBU update consists entirely of
325 ** INSERT operations. However, it is inaccurate if:
326 **
327 ** * the RBU update contains any UPDATE operations. If the PK specified
328 ** for an UPDATE operation does not exist in the target table, then
329 ** no b-tree operations are required on index b-trees. Or if the
330 ** specified PK does exist, then (nIndex*2) such operations are
331 ** required (one delete and one insert on each index b-tree).
332 **
333 ** * the RBU update contains any DELETE operations for which the specified
334 ** PK does not exist. In this case no operations are required on index
335 ** b-trees.
336 **
337 ** * the RBU update contains REPLACE operations. These are similar to
338 ** UPDATE operations.
339 **
340 ** nPhaseOneStep is updated to account for the conditions above during the
341 ** first pass of each source table. The updated nPhaseOneStep value is
342 ** stored in the rbu_state table if the RBU update is suspended.
299 */ 343 */
300 struct sqlite3rbu { 344 struct sqlite3rbu {
301 int eStage; /* Value of RBU_STATE_STAGE field */ 345 int eStage; /* Value of RBU_STATE_STAGE field */
302 sqlite3 *dbMain; /* target database handle */ 346 sqlite3 *dbMain; /* target database handle */
303 sqlite3 *dbRbu; /* rbu database handle */ 347 sqlite3 *dbRbu; /* rbu database handle */
304 char *zTarget; /* Path to target db */ 348 char *zTarget; /* Path to target db */
305 char *zRbu; /* Path to rbu db */ 349 char *zRbu; /* Path to rbu db */
306 char *zState; /* Path to state db (or NULL if zRbu) */ 350 char *zState; /* Path to state db (or NULL if zRbu) */
307 char zStateDb[5]; /* Db name for state ("stat" or "main") */ 351 char zStateDb[5]; /* Db name for state ("stat" or "main") */
308 int rc; /* Value returned by last rbu_step() call */ 352 int rc; /* Value returned by last rbu_step() call */
309 char *zErrmsg; /* Error message if rc!=SQLITE_OK */ 353 char *zErrmsg; /* Error message if rc!=SQLITE_OK */
310 int nStep; /* Rows processed for current object */ 354 int nStep; /* Rows processed for current object */
311 int nProgress; /* Rows processed for all objects */ 355 int nProgress; /* Rows processed for all objects */
312 RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ 356 RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
313 const char *zVfsName; /* Name of automatically created rbu vfs */ 357 const char *zVfsName; /* Name of automatically created rbu vfs */
314 rbu_file *pTargetFd; /* File handle open on target db */ 358 rbu_file *pTargetFd; /* File handle open on target db */
315 i64 iOalSz; 359 i64 iOalSz;
360 i64 nPhaseOneStep;
316 361
317 /* The following state variables are used as part of the incremental 362 /* The following state variables are used as part of the incremental
318 ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding 363 ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding
319 ** function rbuSetupCheckpoint() for details. */ 364 ** function rbuSetupCheckpoint() for details. */
320 u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */ 365 u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */
321 u32 mLock; 366 u32 mLock;
322 int nFrame; /* Entries in aFrame[] array */ 367 int nFrame; /* Entries in aFrame[] array */
323 int nFrameAlloc; /* Allocated size of aFrame[] array */ 368 int nFrameAlloc; /* Allocated size of aFrame[] array */
324 RbuFrame *aFrame; 369 RbuFrame *aFrame;
325 int pgsz; 370 int pgsz;
326 u8 *aBuf; 371 u8 *aBuf;
327 i64 iWalCksum; 372 i64 iWalCksum;
373
374 /* Used in RBU vacuum mode only */
375 int nRbu; /* Number of RBU VFS in the stack */
376 rbu_file *pRbuFd; /* Fd for main db of dbRbu */
328 }; 377 };
329 378
330 /* 379 /*
331 ** An rbu VFS is implemented using an instance of this structure. 380 ** An rbu VFS is implemented using an instance of this structure.
332 */ 381 */
333 struct rbu_vfs { 382 struct rbu_vfs {
334 sqlite3_vfs base; /* rbu VFS shim methods */ 383 sqlite3_vfs base; /* rbu VFS shim methods */
335 sqlite3_vfs *pRealVfs; /* Underlying VFS */ 384 sqlite3_vfs *pRealVfs; /* Underlying VFS */
336 sqlite3_mutex *mutex; /* Mutex to protect pMain */ 385 sqlite3_mutex *mutex; /* Mutex to protect pMain */
337 rbu_file *pMain; /* Linked list of main db files */ 386 rbu_file *pMain; /* Linked list of main db files */
338 }; 387 };
339 388
340 /* 389 /*
341 ** Each file opened by an rbu VFS is represented by an instance of 390 ** Each file opened by an rbu VFS is represented by an instance of
342 ** the following structure. 391 ** the following structure.
343 */ 392 */
344 struct rbu_file { 393 struct rbu_file {
345 sqlite3_file base; /* sqlite3_file methods */ 394 sqlite3_file base; /* sqlite3_file methods */
346 sqlite3_file *pReal; /* Underlying file handle */ 395 sqlite3_file *pReal; /* Underlying file handle */
347 rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */ 396 rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */
348 sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */ 397 sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */
349 398
350 int openFlags; /* Flags this file was opened with */ 399 int openFlags; /* Flags this file was opened with */
351 u32 iCookie; /* Cookie value for main db files */ 400 u32 iCookie; /* Cookie value for main db files */
352 u8 iWriteVer; /* "write-version" value for main db files */ 401 u8 iWriteVer; /* "write-version" value for main db files */
402 u8 bNolock; /* True to fail EXCLUSIVE locks */
353 403
354 int nShm; /* Number of entries in apShm[] array */ 404 int nShm; /* Number of entries in apShm[] array */
355 char **apShm; /* Array of mmap'd *-shm regions */ 405 char **apShm; /* Array of mmap'd *-shm regions */
356 char *zDel; /* Delete this when closing file */ 406 char *zDel; /* Delete this when closing file */
357 407
358 const char *zWal; /* Wal filename for this main db file */ 408 const char *zWal; /* Wal filename for this main db file */
359 rbu_file *pWalFd; /* Wal file descriptor for this main db */ 409 rbu_file *pWalFd; /* Wal file descriptor for this main db */
360 rbu_file *pMainNext; /* Next MAIN_DB file */ 410 rbu_file *pMainNext; /* Next MAIN_DB file */
361 }; 411 };
362 412
413 /*
414 ** True for an RBU vacuum handle, or false otherwise.
415 */
416 #define rbuIsVacuum(p) ((p)->zTarget==0)
417
363 418
364 /************************************************************************* 419 /*************************************************************************
365 ** The following three functions, found below: 420 ** The following three functions, found below:
366 ** 421 **
367 ** rbuDeltaGetInt() 422 ** rbuDeltaGetInt()
368 ** rbuDeltaChecksum() 423 ** rbuDeltaChecksum()
369 ** rbuDeltaApply() 424 ** rbuDeltaApply()
370 ** 425 **
371 ** are lifted from the fossil source code (http://fossil-scm.org). They 426 ** are lifted from the fossil source code (http://fossil-scm.org). They
372 ** are used to implement the scalar SQL function rbu_fossil_delta(). 427 ** are used to implement the scalar SQL function rbu_fossil_delta().
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 if( rc!=SQLITE_OK ){ 856 if( rc!=SQLITE_OK ){
802 rbuObjIterFinalize(pIter); 857 rbuObjIterFinalize(pIter);
803 p->rc = rc; 858 p->rc = rc;
804 } 859 }
805 return rc; 860 return rc;
806 } 861 }
807 862
808 863
809 /* 864 /*
810 ** The implementation of the rbu_target_name() SQL function. This function 865 ** The implementation of the rbu_target_name() SQL function. This function
811 ** accepts one argument - the name of a table in the RBU database. If the 866 ** accepts one or two arguments. The first argument is the name of a table -
812 ** table name matches the pattern: 867 ** the name of a table in the RBU database. The second, if it is present, is 1
868 ** for a view or 0 for a table.
869 **
870 ** For a non-vacuum RBU handle, if the table name matches the pattern:
813 ** 871 **
814 ** data[0-9]_<name> 872 ** data[0-9]_<name>
815 ** 873 **
816 ** where <name> is any sequence of 1 or more characters, <name> is returned. 874 ** where <name> is any sequence of 1 or more characters, <name> is returned.
817 ** Otherwise, if the only argument does not match the above pattern, an SQL 875 ** Otherwise, if the only argument does not match the above pattern, an SQL
818 ** NULL is returned. 876 ** NULL is returned.
819 ** 877 **
820 ** "data_t1" -> "t1" 878 ** "data_t1" -> "t1"
821 ** "data0123_t2" -> "t2" 879 ** "data0123_t2" -> "t2"
822 ** "dataAB_t3" -> NULL 880 ** "dataAB_t3" -> NULL
881 **
882 ** For an rbu vacuum handle, a copy of the first argument is returned if
883 ** the second argument is either missing or 0 (not a view).
823 */ 884 */
824 static void rbuTargetNameFunc( 885 static void rbuTargetNameFunc(
825 sqlite3_context *context, 886 sqlite3_context *pCtx,
826 int argc, 887 int argc,
827 sqlite3_value **argv 888 sqlite3_value **argv
828 ){ 889 ){
890 sqlite3rbu *p = sqlite3_user_data(pCtx);
829 const char *zIn; 891 const char *zIn;
830 assert( argc==1 ); 892 assert( argc==1 || argc==2 );
831 893
832 zIn = (const char*)sqlite3_value_text(argv[0]); 894 zIn = (const char*)sqlite3_value_text(argv[0]);
833 if( zIn && strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){ 895 if( zIn ){
834 int i; 896 if( rbuIsVacuum(p) ){
835 for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++); 897 if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
836 if( zIn[i]=='_' && zIn[i+1] ){ 898 sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
837 sqlite3_result_text(context, &zIn[i+1], -1, SQLITE_STATIC); 899 }
900 }else{
901 if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){
902 int i;
903 for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++);
904 if( zIn[i]=='_' && zIn[i+1] ){
905 sqlite3_result_text(pCtx, &zIn[i+1], -1, SQLITE_STATIC);
906 }
907 }
838 } 908 }
839 } 909 }
840 } 910 }
841 911
842 /* 912 /*
843 ** Initialize the iterator structure passed as the second argument. 913 ** Initialize the iterator structure passed as the second argument.
844 ** 914 **
845 ** If no error occurs, SQLITE_OK is returned and the iterator is left 915 ** If no error occurs, SQLITE_OK is returned and the iterator is left
846 ** pointing to the first entry. Otherwise, an error code and message is 916 ** pointing to the first entry. Otherwise, an error code and message is
847 ** left in the RBU handle passed as the first argument. A copy of the 917 ** left in the RBU handle passed as the first argument. A copy of the
848 ** error code is returned. 918 ** error code is returned.
849 */ 919 */
850 static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){ 920 static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){
851 int rc; 921 int rc;
852 memset(pIter, 0, sizeof(RbuObjIter)); 922 memset(pIter, 0, sizeof(RbuObjIter));
853 923
854 rc = prepareAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, 924 rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg,
855 "SELECT rbu_target_name(name) AS target, name FROM sqlite_master " 925 sqlite3_mprintf(
926 "SELECT rbu_target_name(name, type='view') AS target, name "
927 "FROM sqlite_master "
856 "WHERE type IN ('table', 'view') AND target IS NOT NULL " 928 "WHERE type IN ('table', 'view') AND target IS NOT NULL "
929 " %s "
857 "ORDER BY name" 930 "ORDER BY name"
858 ); 931 , rbuIsVacuum(p) ? "AND rootpage!=0 AND rootpage IS NOT NULL" : ""));
859 932
860 if( rc==SQLITE_OK ){ 933 if( rc==SQLITE_OK ){
861 rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg, 934 rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg,
862 "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' " 935 "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' "
863 " FROM main.sqlite_master " 936 " FROM main.sqlite_master "
864 " WHERE type='index' AND tbl_name = ?" 937 " WHERE type='index' AND tbl_name = ?"
865 ); 938 );
866 } 939 }
867 940
868 pIter->bCleanup = 1; 941 pIter->bCleanup = 1;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 ** If an error (i.e. an OOM condition) occurs, return NULL and leave an 1001 ** If an error (i.e. an OOM condition) occurs, return NULL and leave an
929 ** error code in the rbu handle passed as the first argument. Or, if an 1002 ** error code in the rbu handle passed as the first argument. Or, if an
930 ** error has already occurred when this function is called, return NULL 1003 ** error has already occurred when this function is called, return NULL
931 ** immediately without attempting the allocation or modifying the stored 1004 ** immediately without attempting the allocation or modifying the stored
932 ** error code. 1005 ** error code.
933 */ 1006 */
934 static void *rbuMalloc(sqlite3rbu *p, int nByte){ 1007 static void *rbuMalloc(sqlite3rbu *p, int nByte){
935 void *pRet = 0; 1008 void *pRet = 0;
936 if( p->rc==SQLITE_OK ){ 1009 if( p->rc==SQLITE_OK ){
937 assert( nByte>0 ); 1010 assert( nByte>0 );
938 pRet = sqlite3_malloc(nByte); 1011 pRet = sqlite3_malloc64(nByte);
939 if( pRet==0 ){ 1012 if( pRet==0 ){
940 p->rc = SQLITE_NOMEM; 1013 p->rc = SQLITE_NOMEM;
941 }else{ 1014 }else{
942 memset(pRet, 0, nByte); 1015 memset(pRet, 0, nByte);
943 } 1016 }
944 } 1017 }
945 return pRet; 1018 return pRet;
946 } 1019 }
947 1020
948 1021
(...skipping 25 matching lines...) Expand all
974 ** 1047 **
975 ** If an OOM condition is encountered when attempting to allocate memory, 1048 ** If an OOM condition is encountered when attempting to allocate memory,
976 ** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise, 1049 ** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise,
977 ** if the allocation succeeds, (*pRc) is left unchanged. 1050 ** if the allocation succeeds, (*pRc) is left unchanged.
978 */ 1051 */
979 static char *rbuStrndup(const char *zStr, int *pRc){ 1052 static char *rbuStrndup(const char *zStr, int *pRc){
980 char *zRet = 0; 1053 char *zRet = 0;
981 1054
982 assert( *pRc==SQLITE_OK ); 1055 assert( *pRc==SQLITE_OK );
983 if( zStr ){ 1056 if( zStr ){
984 int nCopy = strlen(zStr) + 1; 1057 size_t nCopy = strlen(zStr) + 1;
985 zRet = (char*)sqlite3_malloc(nCopy); 1058 zRet = (char*)sqlite3_malloc64(nCopy);
986 if( zRet ){ 1059 if( zRet ){
987 memcpy(zRet, zStr, nCopy); 1060 memcpy(zRet, zStr, nCopy);
988 }else{ 1061 }else{
989 *pRc = SQLITE_NOMEM; 1062 *pRc = SQLITE_NOMEM;
990 } 1063 }
991 } 1064 }
992 1065
993 return zRet; 1066 return zRet;
994 } 1067 }
995 1068
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 sqlite3_stmt *pList = 0; 1209 sqlite3_stmt *pList = 0;
1137 int bIndex = 0; 1210 int bIndex = 0;
1138 1211
1139 if( p->rc==SQLITE_OK ){ 1212 if( p->rc==SQLITE_OK ){
1140 memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol); 1213 memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol);
1141 p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg, 1214 p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg,
1142 sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) 1215 sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
1143 ); 1216 );
1144 } 1217 }
1145 1218
1219 pIter->nIndex = 0;
1146 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){ 1220 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
1147 const char *zIdx = (const char*)sqlite3_column_text(pList, 1); 1221 const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
1148 sqlite3_stmt *pXInfo = 0; 1222 sqlite3_stmt *pXInfo = 0;
1149 if( zIdx==0 ) break; 1223 if( zIdx==0 ) break;
1150 p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, 1224 p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
1151 sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) 1225 sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
1152 ); 1226 );
1153 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ 1227 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
1154 int iCid = sqlite3_column_int(pXInfo, 1); 1228 int iCid = sqlite3_column_int(pXInfo, 1);
1155 if( iCid>=0 ) pIter->abIndexed[iCid] = 1; 1229 if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
1156 } 1230 }
1157 rbuFinalize(p, pXInfo); 1231 rbuFinalize(p, pXInfo);
1158 bIndex = 1; 1232 bIndex = 1;
1233 pIter->nIndex++;
1234 }
1235
1236 if( pIter->eType==RBU_PK_WITHOUT_ROWID ){
1237 /* "PRAGMA index_list" includes the main PK b-tree */
1238 pIter->nIndex--;
1159 } 1239 }
1160 1240
1161 rbuFinalize(p, pList); 1241 rbuFinalize(p, pList);
1162 if( bIndex==0 ) pIter->abIndexed = 0; 1242 if( bIndex==0 ) pIter->abIndexed = 0;
1163 } 1243 }
1164 1244
1165 1245
1166 /* 1246 /*
1167 ** If they are not already populated, populate the pIter->azTblCol[], 1247 ** If they are not already populated, populate the pIter->azTblCol[],
1168 ** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to 1248 ** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 pIter->azTblCol[pIter->nTblCol++] = zCopy; 1294 pIter->azTblCol[pIter->nTblCol++] = zCopy;
1215 } 1295 }
1216 else if( 0==sqlite3_stricmp("rbu_rowid", zName) ){ 1296 else if( 0==sqlite3_stricmp("rbu_rowid", zName) ){
1217 bRbuRowid = 1; 1297 bRbuRowid = 1;
1218 } 1298 }
1219 } 1299 }
1220 sqlite3_finalize(pStmt); 1300 sqlite3_finalize(pStmt);
1221 pStmt = 0; 1301 pStmt = 0;
1222 1302
1223 if( p->rc==SQLITE_OK 1303 if( p->rc==SQLITE_OK
1304 && rbuIsVacuum(p)==0
1224 && bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) 1305 && bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
1225 ){ 1306 ){
1226 p->rc = SQLITE_ERROR; 1307 p->rc = SQLITE_ERROR;
1227 p->zErrmsg = sqlite3_mprintf( 1308 p->zErrmsg = sqlite3_mprintf(
1228 "table %q %s rbu_rowid column", pIter->zDataTbl, 1309 "table %q %s rbu_rowid column", pIter->zDataTbl,
1229 (bRbuRowid ? "may not have" : "requires") 1310 (bRbuRowid ? "may not have" : "requires")
1230 ); 1311 );
1231 } 1312 }
1232 1313
1233 /* Check that all non-HIDDEN columns in the destination table are also 1314 /* Check that all non-HIDDEN columns in the destination table are also
(...skipping 28 matching lines...) Expand all
1262 pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc); 1343 pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
1263 pIter->abTblPk[iOrder] = (iPk!=0); 1344 pIter->abTblPk[iOrder] = (iPk!=0);
1264 pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0); 1345 pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
1265 iOrder++; 1346 iOrder++;
1266 } 1347 }
1267 } 1348 }
1268 1349
1269 rbuFinalize(p, pStmt); 1350 rbuFinalize(p, pStmt);
1270 rbuObjIterCacheIndexedCols(p, pIter); 1351 rbuObjIterCacheIndexedCols(p, pIter);
1271 assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 ); 1352 assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 );
1353 assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 );
1272 } 1354 }
1273 1355
1274 return p->rc; 1356 return p->rc;
1275 } 1357 }
1276 1358
1277 /* 1359 /*
1278 ** This function constructs and returns a pointer to a nul-terminated 1360 ** This function constructs and returns a pointer to a nul-terminated
1279 ** string containing some SQL clause or list based on one or more of the 1361 ** string containing some SQL clause or list based on one or more of the
1280 ** column names currently stored in the pIter->azTblCol[] array. 1362 ** column names currently stored in the pIter->azTblCol[] array.
1281 */ 1363 */
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 const char *zType; 1434 const char *zType;
1353 1435
1354 if( iCid<0 ){ 1436 if( iCid<0 ){
1355 /* An integer primary key. If the table has an explicit IPK, use 1437 /* An integer primary key. If the table has an explicit IPK, use
1356 ** its name. Otherwise, use "rbu_rowid". */ 1438 ** its name. Otherwise, use "rbu_rowid". */
1357 if( pIter->eType==RBU_PK_IPK ){ 1439 if( pIter->eType==RBU_PK_IPK ){
1358 int i; 1440 int i;
1359 for(i=0; pIter->abTblPk[i]==0; i++); 1441 for(i=0; pIter->abTblPk[i]==0; i++);
1360 assert( i<pIter->nTblCol ); 1442 assert( i<pIter->nTblCol );
1361 zCol = pIter->azTblCol[i]; 1443 zCol = pIter->azTblCol[i];
1444 }else if( rbuIsVacuum(p) ){
1445 zCol = "_rowid_";
1362 }else{ 1446 }else{
1363 zCol = "rbu_rowid"; 1447 zCol = "rbu_rowid";
1364 } 1448 }
1365 zType = "INTEGER"; 1449 zType = "INTEGER";
1366 }else{ 1450 }else{
1367 zCol = pIter->azTblCol[iCid]; 1451 zCol = pIter->azTblCol[iCid];
1368 zType = pIter->azTblType[iCid]; 1452 zType = pIter->azTblType[iCid];
1369 } 1453 }
1370 1454
1371 zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate); 1455 zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate);
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
1815 1899
1816 static void rbuTmpInsertFunc( 1900 static void rbuTmpInsertFunc(
1817 sqlite3_context *pCtx, 1901 sqlite3_context *pCtx,
1818 int nVal, 1902 int nVal,
1819 sqlite3_value **apVal 1903 sqlite3_value **apVal
1820 ){ 1904 ){
1821 sqlite3rbu *p = sqlite3_user_data(pCtx); 1905 sqlite3rbu *p = sqlite3_user_data(pCtx);
1822 int rc = SQLITE_OK; 1906 int rc = SQLITE_OK;
1823 int i; 1907 int i;
1824 1908
1909 assert( sqlite3_value_int(apVal[0])!=0
1910 || p->objiter.eType==RBU_PK_EXTERNAL
1911 || p->objiter.eType==RBU_PK_NONE
1912 );
1913 if( sqlite3_value_int(apVal[0])!=0 ){
1914 p->nPhaseOneStep += p->objiter.nIndex;
1915 }
1916
1825 for(i=0; rc==SQLITE_OK && i<nVal; i++){ 1917 for(i=0; rc==SQLITE_OK && i<nVal; i++){
1826 rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]); 1918 rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]);
1827 } 1919 }
1828 if( rc==SQLITE_OK ){ 1920 if( rc==SQLITE_OK ){
1829 sqlite3_step(p->objiter.pTmpInsert); 1921 sqlite3_step(p->objiter.pTmpInsert);
1830 rc = sqlite3_reset(p->objiter.pTmpInsert); 1922 rc = sqlite3_reset(p->objiter.pTmpInsert);
1831 } 1923 }
1832 1924
1833 if( rc!=SQLITE_OK ){ 1925 if( rc!=SQLITE_OK ){
1834 sqlite3_result_error_code(pCtx, rc); 1926 sqlite3_result_error_code(pCtx, rc);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1884 /* Create the statement to insert index entries */ 1976 /* Create the statement to insert index entries */
1885 pIter->nCol = nBind; 1977 pIter->nCol = nBind;
1886 if( p->rc==SQLITE_OK ){ 1978 if( p->rc==SQLITE_OK ){
1887 p->rc = prepareFreeAndCollectError( 1979 p->rc = prepareFreeAndCollectError(
1888 p->dbMain, &pIter->pInsert, &p->zErrmsg, 1980 p->dbMain, &pIter->pInsert, &p->zErrmsg,
1889 sqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind) 1981 sqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind)
1890 ); 1982 );
1891 } 1983 }
1892 1984
1893 /* And to delete index entries */ 1985 /* And to delete index entries */
1894 if( p->rc==SQLITE_OK ){ 1986 if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){
1895 p->rc = prepareFreeAndCollectError( 1987 p->rc = prepareFreeAndCollectError(
1896 p->dbMain, &pIter->pDelete, &p->zErrmsg, 1988 p->dbMain, &pIter->pDelete, &p->zErrmsg,
1897 sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere) 1989 sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere)
1898 ); 1990 );
1899 } 1991 }
1900 1992
1901 /* Create the SELECT statement to read keys in sorted order */ 1993 /* Create the SELECT statement to read keys in sorted order */
1902 if( p->rc==SQLITE_OK ){ 1994 if( p->rc==SQLITE_OK ){
1903 char *zSql; 1995 char *zSql;
1996 if( rbuIsVacuum(p) ){
1997 zSql = sqlite3_mprintf(
1998 "SELECT %s, 0 AS rbu_control FROM '%q' ORDER BY %s%s",
1999 zCollist,
2000 pIter->zDataTbl,
2001 zCollist, zLimit
2002 );
2003 }else
2004
1904 if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ 2005 if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
1905 zSql = sqlite3_mprintf( 2006 zSql = sqlite3_mprintf(
1906 "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s", 2007 "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s",
1907 zCollist, p->zStateDb, pIter->zDataTbl, 2008 zCollist, p->zStateDb, pIter->zDataTbl,
1908 zCollist, zLimit 2009 zCollist, zLimit
1909 ); 2010 );
1910 }else{ 2011 }else{
1911 zSql = sqlite3_mprintf( 2012 zSql = sqlite3_mprintf(
2013 "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
2014 "UNION ALL "
1912 "SELECT %s, rbu_control FROM '%q' " 2015 "SELECT %s, rbu_control FROM '%q' "
1913 "WHERE typeof(rbu_control)='integer' AND rbu_control!=1 " 2016 "WHERE typeof(rbu_control)='integer' AND rbu_control!=1 "
1914 "UNION ALL "
1915 "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
1916 "ORDER BY %s%s", 2017 "ORDER BY %s%s",
2018 zCollist, p->zStateDb, pIter->zDataTbl,
1917 zCollist, pIter->zDataTbl, 2019 zCollist, pIter->zDataTbl,
1918 zCollist, p->zStateDb, pIter->zDataTbl,
1919 zCollist, zLimit 2020 zCollist, zLimit
1920 ); 2021 );
1921 } 2022 }
1922 p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql); 2023 p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
1923 } 2024 }
1924 2025
1925 sqlite3_free(zImposterCols); 2026 sqlite3_free(zImposterCols);
1926 sqlite3_free(zImposterPK); 2027 sqlite3_free(zImposterPK);
1927 sqlite3_free(zWhere); 2028 sqlite3_free(zWhere);
1928 sqlite3_free(zBind); 2029 sqlite3_free(zBind);
1929 }else{ 2030 }else{
1930 int bRbuRowid = (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE); 2031 int bRbuRowid = (pIter->eType==RBU_PK_VTAB)
2032 ||(pIter->eType==RBU_PK_NONE)
2033 ||(pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p));
1931 const char *zTbl = pIter->zTbl; /* Table this step applies to */ 2034 const char *zTbl = pIter->zTbl; /* Table this step applies to */
1932 const char *zWrite; /* Imposter table name */ 2035 const char *zWrite; /* Imposter table name */
1933 2036
1934 char *zBindings = rbuObjIterGetBindlist(p, pIter->nTblCol + bRbuRowid); 2037 char *zBindings = rbuObjIterGetBindlist(p, pIter->nTblCol + bRbuRowid);
1935 char *zWhere = rbuObjIterGetWhere(p, pIter); 2038 char *zWhere = rbuObjIterGetWhere(p, pIter);
1936 char *zOldlist = rbuObjIterGetOldlist(p, pIter, "old"); 2039 char *zOldlist = rbuObjIterGetOldlist(p, pIter, "old");
1937 char *zNewlist = rbuObjIterGetOldlist(p, pIter, "new"); 2040 char *zNewlist = rbuObjIterGetOldlist(p, pIter, "new");
1938 2041
1939 zCollist = rbuObjIterGetCollist(p, pIter); 2042 zCollist = rbuObjIterGetCollist(p, pIter);
1940 pIter->nCol = pIter->nTblCol; 2043 pIter->nCol = pIter->nTblCol;
1941 2044
1942 /* Create the imposter table or tables (if required). */ 2045 /* Create the imposter table or tables (if required). */
1943 rbuCreateImposterTable(p, pIter); 2046 rbuCreateImposterTable(p, pIter);
1944 rbuCreateImposterTable2(p, pIter); 2047 rbuCreateImposterTable2(p, pIter);
1945 zWrite = (pIter->eType==RBU_PK_VTAB ? "" : "rbu_imp_"); 2048 zWrite = (pIter->eType==RBU_PK_VTAB ? "" : "rbu_imp_");
1946 2049
1947 /* Create the INSERT statement to write to the target PK b-tree */ 2050 /* Create the INSERT statement to write to the target PK b-tree */
1948 if( p->rc==SQLITE_OK ){ 2051 if( p->rc==SQLITE_OK ){
1949 p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz, 2052 p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz,
1950 sqlite3_mprintf( 2053 sqlite3_mprintf(
1951 "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)", 2054 "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)",
1952 zWrite, zTbl, zCollist, (bRbuRowid ? ", _rowid_" : ""), zBindings 2055 zWrite, zTbl, zCollist, (bRbuRowid ? ", _rowid_" : ""), zBindings
1953 ) 2056 )
1954 ); 2057 );
1955 } 2058 }
1956 2059
1957 /* Create the DELETE statement to write to the target PK b-tree */ 2060 /* Create the DELETE statement to write to the target PK b-tree.
1958 if( p->rc==SQLITE_OK ){ 2061 ** Because it only performs INSERT operations, this is not required for
2062 ** an rbu vacuum handle. */
2063 if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){
1959 p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz, 2064 p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz,
1960 sqlite3_mprintf( 2065 sqlite3_mprintf(
1961 "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere 2066 "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere
1962 ) 2067 )
1963 ); 2068 );
1964 } 2069 }
1965 2070
1966 if( pIter->abIndexed ){ 2071 if( rbuIsVacuum(p)==0 && pIter->abIndexed ){
1967 const char *zRbuRowid = ""; 2072 const char *zRbuRowid = "";
1968 if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ 2073 if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
1969 zRbuRowid = ", rbu_rowid"; 2074 zRbuRowid = ", rbu_rowid";
1970 } 2075 }
1971 2076
1972 /* Create the rbu_tmp_xxx table and the triggers to populate it. */ 2077 /* Create the rbu_tmp_xxx table and the triggers to populate it. */
1973 rbuMPrintfExec(p, p->dbRbu, 2078 rbuMPrintfExec(p, p->dbRbu,
1974 "CREATE TABLE IF NOT EXISTS %s.'rbu_tmp_%q' AS " 2079 "CREATE TABLE IF NOT EXISTS %s.'rbu_tmp_%q' AS "
1975 "SELECT *%s FROM '%q' WHERE 0;" 2080 "SELECT *%s FROM '%q' WHERE 0;"
1976 , p->zStateDb, pIter->zDataTbl 2081 , p->zStateDb, pIter->zDataTbl
1977 , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "") 2082 , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "")
1978 , pIter->zDataTbl 2083 , pIter->zDataTbl
1979 ); 2084 );
1980 2085
1981 rbuMPrintfExec(p, p->dbMain, 2086 rbuMPrintfExec(p, p->dbMain,
1982 "CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" " 2087 "CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" "
1983 "BEGIN " 2088 "BEGIN "
1984 " SELECT rbu_tmp_insert(2, %s);" 2089 " SELECT rbu_tmp_insert(3, %s);"
1985 "END;" 2090 "END;"
1986 2091
1987 "CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" " 2092 "CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" "
1988 "BEGIN " 2093 "BEGIN "
1989 " SELECT rbu_tmp_insert(2, %s);" 2094 " SELECT rbu_tmp_insert(3, %s);"
1990 "END;" 2095 "END;"
1991 2096
1992 "CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" " 2097 "CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" "
1993 "BEGIN " 2098 "BEGIN "
1994 " SELECT rbu_tmp_insert(3, %s);" 2099 " SELECT rbu_tmp_insert(4, %s);"
1995 "END;", 2100 "END;",
1996 zWrite, zTbl, zOldlist, 2101 zWrite, zTbl, zOldlist,
1997 zWrite, zTbl, zOldlist, 2102 zWrite, zTbl, zOldlist,
1998 zWrite, zTbl, zNewlist 2103 zWrite, zTbl, zNewlist
1999 ); 2104 );
2000 2105
2001 if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ 2106 if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
2002 rbuMPrintfExec(p, p->dbMain, 2107 rbuMPrintfExec(p, p->dbMain,
2003 "CREATE TEMP TRIGGER rbu_insert_tr AFTER INSERT ON \"%s%w\" " 2108 "CREATE TEMP TRIGGER rbu_insert_tr AFTER INSERT ON \"%s%w\" "
2004 "BEGIN " 2109 "BEGIN "
2005 " SELECT rbu_tmp_insert(0, %s);" 2110 " SELECT rbu_tmp_insert(0, %s);"
2006 "END;", 2111 "END;",
2007 zWrite, zTbl, zNewlist 2112 zWrite, zTbl, zNewlist
2008 ); 2113 );
2009 } 2114 }
2010 2115
2011 rbuObjIterPrepareTmpInsert(p, pIter, zCollist, zRbuRowid); 2116 rbuObjIterPrepareTmpInsert(p, pIter, zCollist, zRbuRowid);
2012 } 2117 }
2013 2118
2014 /* Create the SELECT statement to read keys from data_xxx */ 2119 /* Create the SELECT statement to read keys from data_xxx */
2015 if( p->rc==SQLITE_OK ){ 2120 if( p->rc==SQLITE_OK ){
2121 const char *zRbuRowid = "";
2122 if( bRbuRowid ){
2123 zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
2124 }
2016 p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, 2125 p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
2017 sqlite3_mprintf( 2126 sqlite3_mprintf(
2018 "SELECT %s, rbu_control%s FROM '%q'%s", 2127 "SELECT %s,%s rbu_control%s FROM '%q'%s",
2019 zCollist, (bRbuRowid ? ", rbu_rowid" : ""), 2128 zCollist,
2129 (rbuIsVacuum(p) ? "0 AS " : ""),
2130 zRbuRowid,
2020 pIter->zDataTbl, zLimit 2131 pIter->zDataTbl, zLimit
2021 ) 2132 )
2022 ); 2133 );
2023 } 2134 }
2024 2135
2025 sqlite3_free(zWhere); 2136 sqlite3_free(zWhere);
2026 sqlite3_free(zOldlist); 2137 sqlite3_free(zOldlist);
2027 sqlite3_free(zNewlist); 2138 sqlite3_free(zNewlist);
2028 sqlite3_free(zBindings); 2139 sqlite3_free(zBindings);
2029 } 2140 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2104 ); 2215 );
2105 *ppStmt = pUp->pUpdate; 2216 *ppStmt = pUp->pUpdate;
2106 } 2217 }
2107 sqlite3_free(zWhere); 2218 sqlite3_free(zWhere);
2108 sqlite3_free(zSet); 2219 sqlite3_free(zSet);
2109 } 2220 }
2110 2221
2111 return p->rc; 2222 return p->rc;
2112 } 2223 }
2113 2224
2114 static sqlite3 *rbuOpenDbhandle(sqlite3rbu *p, const char *zName){ 2225 static sqlite3 *rbuOpenDbhandle(
2226 sqlite3rbu *p,
2227 const char *zName,
2228 int bUseVfs
2229 ){
2115 sqlite3 *db = 0; 2230 sqlite3 *db = 0;
2116 if( p->rc==SQLITE_OK ){ 2231 if( p->rc==SQLITE_OK ){
2117 const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI; 2232 const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI;
2118 p->rc = sqlite3_open_v2(zName, &db, flags, p->zVfsName); 2233 p->rc = sqlite3_open_v2(zName, &db, flags, bUseVfs ? p->zVfsName : 0);
2119 if( p->rc ){ 2234 if( p->rc ){
2120 p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); 2235 p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
2121 sqlite3_close(db); 2236 sqlite3_close(db);
2122 db = 0; 2237 db = 0;
2123 } 2238 }
2124 } 2239 }
2125 return db; 2240 return db;
2126 } 2241 }
2127 2242
2128 /* 2243 /*
2244 ** Free an RbuState object allocated by rbuLoadState().
2245 */
2246 static void rbuFreeState(RbuState *p){
2247 if( p ){
2248 sqlite3_free(p->zTbl);
2249 sqlite3_free(p->zIdx);
2250 sqlite3_free(p);
2251 }
2252 }
2253
2254 /*
2255 ** Allocate an RbuState object and load the contents of the rbu_state
2256 ** table into it. Return a pointer to the new object. It is the
2257 ** responsibility of the caller to eventually free the object using
2258 ** sqlite3_free().
2259 **
2260 ** If an error occurs, leave an error code and message in the rbu handle
2261 ** and return NULL.
2262 */
2263 static RbuState *rbuLoadState(sqlite3rbu *p){
2264 RbuState *pRet = 0;
2265 sqlite3_stmt *pStmt = 0;
2266 int rc;
2267 int rc2;
2268
2269 pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState));
2270 if( pRet==0 ) return 0;
2271
2272 rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
2273 sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb)
2274 );
2275 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
2276 switch( sqlite3_column_int(pStmt, 0) ){
2277 case RBU_STATE_STAGE:
2278 pRet->eStage = sqlite3_column_int(pStmt, 1);
2279 if( pRet->eStage!=RBU_STAGE_OAL
2280 && pRet->eStage!=RBU_STAGE_MOVE
2281 && pRet->eStage!=RBU_STAGE_CKPT
2282 ){
2283 p->rc = SQLITE_CORRUPT;
2284 }
2285 break;
2286
2287 case RBU_STATE_TBL:
2288 pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
2289 break;
2290
2291 case RBU_STATE_IDX:
2292 pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
2293 break;
2294
2295 case RBU_STATE_ROW:
2296 pRet->nRow = sqlite3_column_int(pStmt, 1);
2297 break;
2298
2299 case RBU_STATE_PROGRESS:
2300 pRet->nProgress = sqlite3_column_int64(pStmt, 1);
2301 break;
2302
2303 case RBU_STATE_CKPT:
2304 pRet->iWalCksum = sqlite3_column_int64(pStmt, 1);
2305 break;
2306
2307 case RBU_STATE_COOKIE:
2308 pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
2309 break;
2310
2311 case RBU_STATE_OALSZ:
2312 pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
2313 break;
2314
2315 case RBU_STATE_PHASEONESTEP:
2316 pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1);
2317 break;
2318
2319 default:
2320 rc = SQLITE_CORRUPT;
2321 break;
2322 }
2323 }
2324 rc2 = sqlite3_finalize(pStmt);
2325 if( rc==SQLITE_OK ) rc = rc2;
2326
2327 p->rc = rc;
2328 return pRet;
2329 }
2330
2331
2332 /*
2129 ** Open the database handle and attach the RBU database as "rbu". If an 2333 ** Open the database handle and attach the RBU database as "rbu". If an
2130 ** error occurs, leave an error code and message in the RBU handle. 2334 ** error occurs, leave an error code and message in the RBU handle.
2131 */ 2335 */
2132 static void rbuOpenDatabase(sqlite3rbu *p){ 2336 static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
2133 assert( p->rc==SQLITE_OK ); 2337 assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
2134 assert( p->dbMain==0 && p->dbRbu==0 ); 2338 assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
2135 2339
2136 p->eStage = 0; 2340 /* Open the RBU database */
2137 p->dbMain = rbuOpenDbhandle(p, p->zTarget); 2341 p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
2138 p->dbRbu = rbuOpenDbhandle(p, p->zRbu); 2342
2343 if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
2344 sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
2345 if( p->zState==0 ){
2346 const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
2347 p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile);
2348 }
2349 }
2139 2350
2140 /* If using separate RBU and state databases, attach the state database to 2351 /* If using separate RBU and state databases, attach the state database to
2141 ** the RBU db handle now. */ 2352 ** the RBU db handle now. */
2142 if( p->zState ){ 2353 if( p->zState ){
2143 rbuMPrintfExec(p, p->dbRbu, "ATTACH %Q AS stat", p->zState); 2354 rbuMPrintfExec(p, p->dbRbu, "ATTACH %Q AS stat", p->zState);
2144 memcpy(p->zStateDb, "stat", 4); 2355 memcpy(p->zStateDb, "stat", 4);
2145 }else{ 2356 }else{
2146 memcpy(p->zStateDb, "main", 4); 2357 memcpy(p->zStateDb, "main", 4);
2147 } 2358 }
2148 2359
2360 #if 0
2361 if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
2362 p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, 0);
2363 }
2364 #endif
2365
2366 /* If it has not already been created, create the rbu_state table */
2367 rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb);
2368
2369 #if 0
2370 if( rbuIsVacuum(p) ){
2371 if( p->rc==SQLITE_OK ){
2372 int rc2;
2373 int bOk = 0;
2374 sqlite3_stmt *pCnt = 0;
2375 p->rc = prepareAndCollectError(p->dbRbu, &pCnt, &p->zErrmsg,
2376 "SELECT count(*) FROM stat.sqlite_master"
2377 );
2378 if( p->rc==SQLITE_OK
2379 && sqlite3_step(pCnt)==SQLITE_ROW
2380 && 1==sqlite3_column_int(pCnt, 0)
2381 ){
2382 bOk = 1;
2383 }
2384 rc2 = sqlite3_finalize(pCnt);
2385 if( p->rc==SQLITE_OK ) p->rc = rc2;
2386
2387 if( p->rc==SQLITE_OK && bOk==0 ){
2388 p->rc = SQLITE_ERROR;
2389 p->zErrmsg = sqlite3_mprintf("invalid state database");
2390 }
2391
2392 if( p->rc==SQLITE_OK ){
2393 p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
2394 }
2395 }
2396 }
2397 #endif
2398
2399 if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
2400 int bOpen = 0;
2401 int rc;
2402 p->nRbu = 0;
2403 p->pRbuFd = 0;
2404 rc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
2405 if( rc!=SQLITE_NOTFOUND ) p->rc = rc;
2406 if( p->eStage>=RBU_STAGE_MOVE ){
2407 bOpen = 1;
2408 }else{
2409 RbuState *pState = rbuLoadState(p);
2410 if( pState ){
2411 bOpen = (pState->eStage>=RBU_STAGE_MOVE);
2412 rbuFreeState(pState);
2413 }
2414 }
2415 if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, p->nRbu<=1);
2416 }
2417
2418 p->eStage = 0;
2419 if( p->rc==SQLITE_OK && p->dbMain==0 ){
2420 if( !rbuIsVacuum(p) ){
2421 p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
2422 }else if( p->pRbuFd->pWalFd ){
2423 if( pbRetry ){
2424 p->pRbuFd->bNolock = 0;
2425 sqlite3_close(p->dbRbu);
2426 sqlite3_close(p->dbMain);
2427 p->dbMain = 0;
2428 p->dbRbu = 0;
2429 *pbRetry = 1;
2430 return;
2431 }
2432 p->rc = SQLITE_ERROR;
2433 p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database");
2434 }else{
2435 char *zTarget;
2436 char *zExtra = 0;
2437 if( strlen(p->zRbu)>=5 && 0==memcmp("file:", p->zRbu, 5) ){
2438 zExtra = &p->zRbu[5];
2439 while( *zExtra ){
2440 if( *zExtra++=='?' ) break;
2441 }
2442 if( *zExtra=='\0' ) zExtra = 0;
2443 }
2444
2445 zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1%s%s",
2446 sqlite3_db_filename(p->dbRbu, "main"),
2447 (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra)
2448 );
2449
2450 if( zTarget==0 ){
2451 p->rc = SQLITE_NOMEM;
2452 return;
2453 }
2454 p->dbMain = rbuOpenDbhandle(p, zTarget, p->nRbu<=1);
2455 sqlite3_free(zTarget);
2456 }
2457 }
2458
2149 if( p->rc==SQLITE_OK ){ 2459 if( p->rc==SQLITE_OK ){
2150 p->rc = sqlite3_create_function(p->dbMain, 2460 p->rc = sqlite3_create_function(p->dbMain,
2151 "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0 2461 "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0
2152 ); 2462 );
2153 } 2463 }
2154 2464
2155 if( p->rc==SQLITE_OK ){ 2465 if( p->rc==SQLITE_OK ){
2156 p->rc = sqlite3_create_function(p->dbMain, 2466 p->rc = sqlite3_create_function(p->dbMain,
2157 "rbu_fossil_delta", 2, SQLITE_UTF8, 0, rbuFossilDeltaFunc, 0, 0 2467 "rbu_fossil_delta", 2, SQLITE_UTF8, 0, rbuFossilDeltaFunc, 0, 0
2158 ); 2468 );
2159 } 2469 }
2160 2470
2161 if( p->rc==SQLITE_OK ){ 2471 if( p->rc==SQLITE_OK ){
2162 p->rc = sqlite3_create_function(p->dbRbu, 2472 p->rc = sqlite3_create_function(p->dbRbu,
2163 "rbu_target_name", 1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0 2473 "rbu_target_name", -1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0
2164 ); 2474 );
2165 } 2475 }
2166 2476
2167 if( p->rc==SQLITE_OK ){ 2477 if( p->rc==SQLITE_OK ){
2168 p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); 2478 p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p);
2169 } 2479 }
2170 rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master"); 2480 rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master");
2171 2481
2172 /* Mark the database file just opened as an RBU target database. If 2482 /* Mark the database file just opened as an RBU target database. If
2173 ** this call returns SQLITE_NOTFOUND, then the RBU vfs is not in use. 2483 ** this call returns SQLITE_NOTFOUND, then the RBU vfs is not in use.
(...skipping 28 matching lines...) Expand all
2202 ** test.db-shm => test.shm 2512 ** test.db-shm => test.shm
2203 ** test.db-mj7f3319fa => test.9fa 2513 ** test.db-mj7f3319fa => test.9fa
2204 */ 2514 */
2205 static void rbuFileSuffix3(const char *zBase, char *z){ 2515 static void rbuFileSuffix3(const char *zBase, char *z){
2206 #ifdef SQLITE_ENABLE_8_3_NAMES 2516 #ifdef SQLITE_ENABLE_8_3_NAMES
2207 #if SQLITE_ENABLE_8_3_NAMES<2 2517 #if SQLITE_ENABLE_8_3_NAMES<2
2208 if( sqlite3_uri_boolean(zBase, "8_3_names", 0) ) 2518 if( sqlite3_uri_boolean(zBase, "8_3_names", 0) )
2209 #endif 2519 #endif
2210 { 2520 {
2211 int i, sz; 2521 int i, sz;
2212 sz = sqlite3Strlen30(z); 2522 sz = (int)strlen(z)&0xffffff;
2213 for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} 2523 for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
2214 if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); 2524 if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
2215 } 2525 }
2216 #endif 2526 #endif
2217 } 2527 }
2218 2528
2219 /* 2529 /*
2220 ** Return the current wal-index header checksum for the target database 2530 ** Return the current wal-index header checksum for the target database
2221 ** as a 64-bit integer. 2531 ** as a 64-bit integer.
2222 ** 2532 **
2223 ** The checksum is store in the first page of xShmMap memory as an 8-byte 2533 ** The checksum is store in the first page of xShmMap memory as an 8-byte
2224 ** blob starting at byte offset 40. 2534 ** blob starting at byte offset 40.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2292 ** data from the wal file into the database file according to the 2602 ** data from the wal file into the database file according to the
2293 ** contents of aFrame[]. 2603 ** contents of aFrame[].
2294 */ 2604 */
2295 if( p->rc==SQLITE_OK ){ 2605 if( p->rc==SQLITE_OK ){
2296 int rc2; 2606 int rc2;
2297 p->eStage = RBU_STAGE_CAPTURE; 2607 p->eStage = RBU_STAGE_CAPTURE;
2298 rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0); 2608 rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0);
2299 if( rc2!=SQLITE_INTERNAL ) p->rc = rc2; 2609 if( rc2!=SQLITE_INTERNAL ) p->rc = rc2;
2300 } 2610 }
2301 2611
2302 if( p->rc==SQLITE_OK ){ 2612 if( p->rc==SQLITE_OK && p->nFrame>0 ){
2303 p->eStage = RBU_STAGE_CKPT; 2613 p->eStage = RBU_STAGE_CKPT;
2304 p->nStep = (pState ? pState->nRow : 0); 2614 p->nStep = (pState ? pState->nRow : 0);
2305 p->aBuf = rbuMalloc(p, p->pgsz); 2615 p->aBuf = rbuMalloc(p, p->pgsz);
2306 p->iWalCksum = rbuShmChecksum(p); 2616 p->iWalCksum = rbuShmChecksum(p);
2307 } 2617 }
2308 2618
2309 if( p->rc==SQLITE_OK && pState && pState->iWalCksum!=p->iWalCksum ){ 2619 if( p->rc==SQLITE_OK ){
2310 p->rc = SQLITE_DONE; 2620 if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){
2311 p->eStage = RBU_STAGE_DONE; 2621 p->rc = SQLITE_DONE;
2622 p->eStage = RBU_STAGE_DONE;
2623 }
2312 } 2624 }
2313 } 2625 }
2314 2626
2315 /* 2627 /*
2316 ** Called when iAmt bytes are read from offset iOff of the wal file while 2628 ** Called when iAmt bytes are read from offset iOff of the wal file while
2317 ** the rbu object is in capture mode. Record the frame number of the frame 2629 ** the rbu object is in capture mode. Record the frame number of the frame
2318 ** being read in the aFrame[] array. 2630 ** being read in the aFrame[] array.
2319 */ 2631 */
2320 static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){ 2632 static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){
2321 const u32 mReq = (1<<WAL_LOCK_WRITE)|(1<<WAL_LOCK_CKPT)|(1<<WAL_LOCK_READ0); 2633 const u32 mReq = (1<<WAL_LOCK_WRITE)|(1<<WAL_LOCK_CKPT)|(1<<WAL_LOCK_READ0);
2322 u32 iFrame; 2634 u32 iFrame;
2323 2635
2324 if( pRbu->mLock!=mReq ){ 2636 if( pRbu->mLock!=mReq ){
2325 pRbu->rc = SQLITE_BUSY; 2637 pRbu->rc = SQLITE_BUSY;
2326 return SQLITE_INTERNAL; 2638 return SQLITE_INTERNAL;
2327 } 2639 }
2328 2640
2329 pRbu->pgsz = iAmt; 2641 pRbu->pgsz = iAmt;
2330 if( pRbu->nFrame==pRbu->nFrameAlloc ){ 2642 if( pRbu->nFrame==pRbu->nFrameAlloc ){
2331 int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2; 2643 int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2;
2332 RbuFrame *aNew; 2644 RbuFrame *aNew;
2333 aNew = (RbuFrame*)sqlite3_realloc(pRbu->aFrame, nNew * sizeof(RbuFrame)); 2645 aNew = (RbuFrame*)sqlite3_realloc64(pRbu->aFrame, nNew * sizeof(RbuFrame));
2334 if( aNew==0 ) return SQLITE_NOMEM; 2646 if( aNew==0 ) return SQLITE_NOMEM;
2335 pRbu->aFrame = aNew; 2647 pRbu->aFrame = aNew;
2336 pRbu->nFrameAlloc = nNew; 2648 pRbu->nFrameAlloc = nNew;
2337 } 2649 }
2338 2650
2339 iFrame = (u32)((iOff-32) / (i64)(iAmt+24)) + 1; 2651 iFrame = (u32)((iOff-32) / (i64)(iAmt+24)) + 1;
2340 if( pRbu->iMaxFrame<iFrame ) pRbu->iMaxFrame = iFrame; 2652 if( pRbu->iMaxFrame<iFrame ) pRbu->iMaxFrame = iFrame;
2341 pRbu->aFrame[pRbu->nFrame].iWalFrame = iFrame; 2653 pRbu->aFrame[pRbu->nFrame].iWalFrame = iFrame;
2342 pRbu->aFrame[pRbu->nFrame].iDbPage = 0; 2654 pRbu->aFrame[pRbu->nFrame].iDbPage = 0;
2343 pRbu->nFrame++; 2655 pRbu->nFrame++;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2388 2700
2389 #if defined(_WIN32_WCE) 2701 #if defined(_WIN32_WCE)
2390 static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){ 2702 static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
2391 int nChar; 2703 int nChar;
2392 LPWSTR zWideFilename; 2704 LPWSTR zWideFilename;
2393 2705
2394 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); 2706 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
2395 if( nChar==0 ){ 2707 if( nChar==0 ){
2396 return 0; 2708 return 0;
2397 } 2709 }
2398 zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) ); 2710 zWideFilename = sqlite3_malloc64( nChar*sizeof(zWideFilename[0]) );
2399 if( zWideFilename==0 ){ 2711 if( zWideFilename==0 ){
2400 return 0; 2712 return 0;
2401 } 2713 }
2402 memset(zWideFilename, 0, nChar*sizeof(zWideFilename[0])); 2714 memset(zWideFilename, 0, nChar*sizeof(zWideFilename[0]));
2403 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, 2715 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
2404 nChar); 2716 nChar);
2405 if( nChar==0 ){ 2717 if( nChar==0 ){
2406 sqlite3_free(zWideFilename); 2718 sqlite3_free(zWideFilename);
2407 zWideFilename = 0; 2719 zWideFilename = 0;
2408 } 2720 }
2409 return zWideFilename; 2721 return zWideFilename;
2410 } 2722 }
2411 #endif 2723 #endif
2412 2724
2413 /* 2725 /*
2414 ** The RBU handle is currently in RBU_STAGE_OAL state, with a SHARED lock 2726 ** The RBU handle is currently in RBU_STAGE_OAL state, with a SHARED lock
2415 ** on the database file. This proc moves the *-oal file to the *-wal path, 2727 ** on the database file. This proc moves the *-oal file to the *-wal path,
2416 ** then reopens the database file (this time in vanilla, non-oal, WAL mode). 2728 ** then reopens the database file (this time in vanilla, non-oal, WAL mode).
2417 ** If an error occurs, leave an error code and error message in the rbu 2729 ** If an error occurs, leave an error code and error message in the rbu
2418 ** handle. 2730 ** handle.
2419 */ 2731 */
2420 static void rbuMoveOalFile(sqlite3rbu *p){ 2732 static void rbuMoveOalFile(sqlite3rbu *p){
2421 const char *zBase = sqlite3_db_filename(p->dbMain, "main"); 2733 const char *zBase = sqlite3_db_filename(p->dbMain, "main");
2734 const char *zMove = zBase;
2735 char *zOal;
2736 char *zWal;
2422 2737
2423 char *zWal = sqlite3_mprintf("%s-wal", zBase); 2738 if( rbuIsVacuum(p) ){
2424 char *zOal = sqlite3_mprintf("%s-oal", zBase); 2739 zMove = sqlite3_db_filename(p->dbRbu, "main");
2740 }
2741 zOal = sqlite3_mprintf("%s-oal", zMove);
2742 zWal = sqlite3_mprintf("%s-wal", zMove);
2425 2743
2426 assert( p->eStage==RBU_STAGE_MOVE ); 2744 assert( p->eStage==RBU_STAGE_MOVE );
2427 assert( p->rc==SQLITE_OK && p->zErrmsg==0 ); 2745 assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
2428 if( zWal==0 || zOal==0 ){ 2746 if( zWal==0 || zOal==0 ){
2429 p->rc = SQLITE_NOMEM; 2747 p->rc = SQLITE_NOMEM;
2430 }else{ 2748 }else{
2431 /* Move the *-oal file to *-wal. At this point connection p->db is 2749 /* Move the *-oal file to *-wal. At this point connection p->db is
2432 ** holding a SHARED lock on the target database file (because it is 2750 ** holding a SHARED lock on the target database file (because it is
2433 ** in WAL mode). So no other connection may be writing the db. 2751 ** in WAL mode). So no other connection may be writing the db.
2434 ** 2752 **
2435 ** In order to ensure that there are no database readers, an EXCLUSIVE 2753 ** In order to ensure that there are no database readers, an EXCLUSIVE
2436 ** lock is obtained here before the *-oal is moved to *-wal. 2754 ** lock is obtained here before the *-oal is moved to *-wal.
2437 */ 2755 */
2438 rbuLockDatabase(p); 2756 rbuLockDatabase(p);
2439 if( p->rc==SQLITE_OK ){ 2757 if( p->rc==SQLITE_OK ){
2440 rbuFileSuffix3(zBase, zWal); 2758 rbuFileSuffix3(zBase, zWal);
2441 rbuFileSuffix3(zBase, zOal); 2759 rbuFileSuffix3(zBase, zOal);
2442 2760
2443 /* Re-open the databases. */ 2761 /* Re-open the databases. */
2444 rbuObjIterFinalize(&p->objiter); 2762 rbuObjIterFinalize(&p->objiter);
2763 sqlite3_close(p->dbRbu);
2445 sqlite3_close(p->dbMain); 2764 sqlite3_close(p->dbMain);
2446 sqlite3_close(p->dbRbu);
2447 p->dbMain = 0; 2765 p->dbMain = 0;
2448 p->dbRbu = 0; 2766 p->dbRbu = 0;
2449 2767
2450 #if defined(_WIN32_WCE) 2768 #if defined(_WIN32_WCE)
2451 { 2769 {
2452 LPWSTR zWideOal; 2770 LPWSTR zWideOal;
2453 LPWSTR zWideWal; 2771 LPWSTR zWideWal;
2454 2772
2455 zWideOal = rbuWinUtf8ToUnicode(zOal); 2773 zWideOal = rbuWinUtf8ToUnicode(zOal);
2456 if( zWideOal ){ 2774 if( zWideOal ){
(...skipping 11 matching lines...) Expand all
2468 sqlite3_free(zWideOal); 2786 sqlite3_free(zWideOal);
2469 }else{ 2787 }else{
2470 p->rc = SQLITE_IOERR_NOMEM; 2788 p->rc = SQLITE_IOERR_NOMEM;
2471 } 2789 }
2472 } 2790 }
2473 #else 2791 #else
2474 p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK; 2792 p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
2475 #endif 2793 #endif
2476 2794
2477 if( p->rc==SQLITE_OK ){ 2795 if( p->rc==SQLITE_OK ){
2478 rbuOpenDatabase(p); 2796 rbuOpenDatabase(p, 0);
2479 rbuSetupCheckpoint(p, 0); 2797 rbuSetupCheckpoint(p, 0);
2480 } 2798 }
2481 } 2799 }
2482 } 2800 }
2483 2801
2484 sqlite3_free(zWal); 2802 sqlite3_free(zWal);
2485 sqlite3_free(zOal); 2803 sqlite3_free(zOal);
2486 } 2804 }
2487 2805
2488 /* 2806 /*
(...skipping 13 matching lines...) Expand all
2502 ** If the rbu_control field contains an invalid value, an error code and 2820 ** If the rbu_control field contains an invalid value, an error code and
2503 ** message are left in the RBU handle and zero returned. 2821 ** message are left in the RBU handle and zero returned.
2504 */ 2822 */
2505 static int rbuStepType(sqlite3rbu *p, const char **pzMask){ 2823 static int rbuStepType(sqlite3rbu *p, const char **pzMask){
2506 int iCol = p->objiter.nCol; /* Index of rbu_control column */ 2824 int iCol = p->objiter.nCol; /* Index of rbu_control column */
2507 int res = 0; /* Return value */ 2825 int res = 0; /* Return value */
2508 2826
2509 switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){ 2827 switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){
2510 case SQLITE_INTEGER: { 2828 case SQLITE_INTEGER: {
2511 int iVal = sqlite3_column_int(p->objiter.pSelect, iCol); 2829 int iVal = sqlite3_column_int(p->objiter.pSelect, iCol);
2512 if( iVal==0 ){ 2830 switch( iVal ){
2513 res = RBU_INSERT; 2831 case 0: res = RBU_INSERT; break;
2514 }else if( iVal==1 ){ 2832 case 1: res = RBU_DELETE; break;
2515 res = RBU_DELETE; 2833 case 2: res = RBU_REPLACE; break;
2516 }else if( iVal==2 ){ 2834 case 3: res = RBU_IDX_DELETE; break;
2517 res = RBU_IDX_DELETE; 2835 case 4: res = RBU_IDX_INSERT; break;
2518 }else if( iVal==3 ){
2519 res = RBU_IDX_INSERT;
2520 } 2836 }
2521 break; 2837 break;
2522 } 2838 }
2523 2839
2524 case SQLITE_TEXT: { 2840 case SQLITE_TEXT: {
2525 const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol); 2841 const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol);
2526 if( z==0 ){ 2842 if( z==0 ){
2527 p->rc = SQLITE_NOMEM; 2843 p->rc = SQLITE_NOMEM;
2528 }else{ 2844 }else{
2529 *pzMask = (const char*)z; 2845 *pzMask = (const char*)z;
(...skipping 19 matching lines...) Expand all
2549 */ 2865 */
2550 static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){ 2866 static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){
2551 const char *zCol = sqlite3_column_name(pStmt, iCol); 2867 const char *zCol = sqlite3_column_name(pStmt, iCol);
2552 assert( 0==sqlite3_stricmp(zName, zCol) ); 2868 assert( 0==sqlite3_stricmp(zName, zCol) );
2553 } 2869 }
2554 #else 2870 #else
2555 # define assertColumnName(x,y,z) 2871 # define assertColumnName(x,y,z)
2556 #endif 2872 #endif
2557 2873
2558 /* 2874 /*
2875 ** Argument eType must be one of RBU_INSERT, RBU_DELETE, RBU_IDX_INSERT or
2876 ** RBU_IDX_DELETE. This function performs the work of a single
2877 ** sqlite3rbu_step() call for the type of operation specified by eType.
2878 */
2879 static void rbuStepOneOp(sqlite3rbu *p, int eType){
2880 RbuObjIter *pIter = &p->objiter;
2881 sqlite3_value *pVal;
2882 sqlite3_stmt *pWriter;
2883 int i;
2884
2885 assert( p->rc==SQLITE_OK );
2886 assert( eType!=RBU_DELETE || pIter->zIdx==0 );
2887 assert( eType==RBU_DELETE || eType==RBU_IDX_DELETE
2888 || eType==RBU_INSERT || eType==RBU_IDX_INSERT
2889 );
2890
2891 /* If this is a delete, decrement nPhaseOneStep by nIndex. If the DELETE
2892 ** statement below does actually delete a row, nPhaseOneStep will be
2893 ** incremented by the same amount when SQL function rbu_tmp_insert()
2894 ** is invoked by the trigger. */
2895 if( eType==RBU_DELETE ){
2896 p->nPhaseOneStep -= p->objiter.nIndex;
2897 }
2898
2899 if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){
2900 pWriter = pIter->pDelete;
2901 }else{
2902 pWriter = pIter->pInsert;
2903 }
2904
2905 for(i=0; i<pIter->nCol; i++){
2906 /* If this is an INSERT into a table b-tree and the table has an
2907 ** explicit INTEGER PRIMARY KEY, check that this is not an attempt
2908 ** to write a NULL into the IPK column. That is not permitted. */
2909 if( eType==RBU_INSERT
2910 && pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i]
2911 && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
2912 ){
2913 p->rc = SQLITE_MISMATCH;
2914 p->zErrmsg = sqlite3_mprintf("datatype mismatch");
2915 return;
2916 }
2917
2918 if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){
2919 continue;
2920 }
2921
2922 pVal = sqlite3_column_value(pIter->pSelect, i);
2923 p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
2924 if( p->rc ) return;
2925 }
2926 if( pIter->zIdx==0 ){
2927 if( pIter->eType==RBU_PK_VTAB
2928 || pIter->eType==RBU_PK_NONE
2929 || (pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p))
2930 ){
2931 /* For a virtual table, or a table with no primary key, the
2932 ** SELECT statement is:
2933 **
2934 ** SELECT <cols>, rbu_control, rbu_rowid FROM ....
2935 **
2936 ** Hence column_value(pIter->nCol+1).
2937 */
2938 assertColumnName(pIter->pSelect, pIter->nCol+1,
2939 rbuIsVacuum(p) ? "rowid" : "rbu_rowid"
2940 );
2941 pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
2942 p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
2943 }
2944 }
2945 if( p->rc==SQLITE_OK ){
2946 sqlite3_step(pWriter);
2947 p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
2948 }
2949 }
2950
2951 /*
2559 ** This function does the work for an sqlite3rbu_step() call. 2952 ** This function does the work for an sqlite3rbu_step() call.
2560 ** 2953 **
2561 ** The object-iterator (p->objiter) currently points to a valid object, 2954 ** The object-iterator (p->objiter) currently points to a valid object,
2562 ** and the input cursor (p->objiter.pSelect) currently points to a valid 2955 ** and the input cursor (p->objiter.pSelect) currently points to a valid
2563 ** input row. Perform whatever processing is required and return. 2956 ** input row. Perform whatever processing is required and return.
2564 ** 2957 **
2565 ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code 2958 ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code
2566 ** and message is left in the RBU handle and a copy of the error code 2959 ** and message is left in the RBU handle and a copy of the error code
2567 ** returned. 2960 ** returned.
2568 */ 2961 */
2569 static int rbuStep(sqlite3rbu *p){ 2962 static int rbuStep(sqlite3rbu *p){
2570 RbuObjIter *pIter = &p->objiter; 2963 RbuObjIter *pIter = &p->objiter;
2571 const char *zMask = 0; 2964 const char *zMask = 0;
2572 int i;
2573 int eType = rbuStepType(p, &zMask); 2965 int eType = rbuStepType(p, &zMask);
2574 2966
2575 if( eType ){ 2967 if( eType ){
2968 assert( eType==RBU_INSERT || eType==RBU_DELETE
2969 || eType==RBU_REPLACE || eType==RBU_IDX_DELETE
2970 || eType==RBU_IDX_INSERT || eType==RBU_UPDATE
2971 );
2576 assert( eType!=RBU_UPDATE || pIter->zIdx==0 ); 2972 assert( eType!=RBU_UPDATE || pIter->zIdx==0 );
2577 2973
2578 if( pIter->zIdx==0 && eType==RBU_IDX_DELETE ){ 2974 if( pIter->zIdx==0 && (eType==RBU_IDX_DELETE || eType==RBU_IDX_INSERT) ){
2579 rbuBadControlError(p); 2975 rbuBadControlError(p);
2580 } 2976 }
2581 else if( 2977 else if( eType==RBU_REPLACE ){
2582 eType==RBU_INSERT 2978 if( pIter->zIdx==0 ){
2583 || eType==RBU_DELETE 2979 p->nPhaseOneStep += p->objiter.nIndex;
2584 || eType==RBU_IDX_DELETE 2980 rbuStepOneOp(p, RBU_DELETE);
2585 || eType==RBU_IDX_INSERT
2586 ){
2587 sqlite3_value *pVal;
2588 sqlite3_stmt *pWriter;
2589
2590 assert( eType!=RBU_UPDATE );
2591 assert( eType!=RBU_DELETE || pIter->zIdx==0 );
2592
2593 if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){
2594 pWriter = pIter->pDelete;
2595 }else{
2596 pWriter = pIter->pInsert;
2597 } 2981 }
2598 2982 if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT);
2599 for(i=0; i<pIter->nCol; i++){ 2983 }
2600 /* If this is an INSERT into a table b-tree and the table has an 2984 else if( eType!=RBU_UPDATE ){
2601 ** explicit INTEGER PRIMARY KEY, check that this is not an attempt 2985 rbuStepOneOp(p, eType);
2602 ** to write a NULL into the IPK column. That is not permitted. */ 2986 }
2603 if( eType==RBU_INSERT 2987 else{
2604 && pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i]
2605 && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
2606 ){
2607 p->rc = SQLITE_MISMATCH;
2608 p->zErrmsg = sqlite3_mprintf("datatype mismatch");
2609 goto step_out;
2610 }
2611
2612 if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){
2613 continue;
2614 }
2615
2616 pVal = sqlite3_column_value(pIter->pSelect, i);
2617 p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
2618 if( p->rc ) goto step_out;
2619 }
2620 if( pIter->zIdx==0
2621 && (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
2622 ){
2623 /* For a virtual table, or a table with no primary key, the
2624 ** SELECT statement is:
2625 **
2626 ** SELECT <cols>, rbu_control, rbu_rowid FROM ....
2627 **
2628 ** Hence column_value(pIter->nCol+1).
2629 */
2630 assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid");
2631 pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
2632 p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
2633 }
2634 if( p->rc==SQLITE_OK ){
2635 sqlite3_step(pWriter);
2636 p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
2637 }
2638 }else{
2639 sqlite3_value *pVal; 2988 sqlite3_value *pVal;
2640 sqlite3_stmt *pUpdate = 0; 2989 sqlite3_stmt *pUpdate = 0;
2641 assert( eType==RBU_UPDATE ); 2990 assert( eType==RBU_UPDATE );
2991 p->nPhaseOneStep -= p->objiter.nIndex;
2642 rbuGetUpdateStmt(p, pIter, zMask, &pUpdate); 2992 rbuGetUpdateStmt(p, pIter, zMask, &pUpdate);
2643 if( pUpdate ){ 2993 if( pUpdate ){
2994 int i;
2644 for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){ 2995 for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){
2645 char c = zMask[pIter->aiSrcOrder[i]]; 2996 char c = zMask[pIter->aiSrcOrder[i]];
2646 pVal = sqlite3_column_value(pIter->pSelect, i); 2997 pVal = sqlite3_column_value(pIter->pSelect, i);
2647 if( pIter->abTblPk[i] || c!='.' ){ 2998 if( pIter->abTblPk[i] || c!='.' ){
2648 p->rc = sqlite3_bind_value(pUpdate, i+1, pVal); 2999 p->rc = sqlite3_bind_value(pUpdate, i+1, pVal);
2649 } 3000 }
2650 } 3001 }
2651 if( p->rc==SQLITE_OK 3002 if( p->rc==SQLITE_OK
2652 && (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) 3003 && (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE)
2653 ){ 3004 ){
2654 /* Bind the rbu_rowid value to column _rowid_ */ 3005 /* Bind the rbu_rowid value to column _rowid_ */
2655 assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid"); 3006 assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid");
2656 pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1); 3007 pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
2657 p->rc = sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal); 3008 p->rc = sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal);
2658 } 3009 }
2659 if( p->rc==SQLITE_OK ){ 3010 if( p->rc==SQLITE_OK ){
2660 sqlite3_step(pUpdate); 3011 sqlite3_step(pUpdate);
2661 p->rc = resetAndCollectError(pUpdate, &p->zErrmsg); 3012 p->rc = resetAndCollectError(pUpdate, &p->zErrmsg);
2662 } 3013 }
2663 } 3014 }
2664 } 3015 }
2665 } 3016 }
2666
2667 step_out:
2668 return p->rc; 3017 return p->rc;
2669 } 3018 }
2670 3019
2671 /* 3020 /*
2672 ** Increment the schema cookie of the main database opened by p->dbMain. 3021 ** Increment the schema cookie of the main database opened by p->dbMain.
3022 **
3023 ** Or, if this is an RBU vacuum, set the schema cookie of the main db
3024 ** opened by p->dbMain to one more than the schema cookie of the main
3025 ** db opened by p->dbRbu.
2673 */ 3026 */
2674 static void rbuIncrSchemaCookie(sqlite3rbu *p){ 3027 static void rbuIncrSchemaCookie(sqlite3rbu *p){
2675 if( p->rc==SQLITE_OK ){ 3028 if( p->rc==SQLITE_OK ){
3029 sqlite3 *dbread = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
2676 int iCookie = 1000000; 3030 int iCookie = 1000000;
2677 sqlite3_stmt *pStmt; 3031 sqlite3_stmt *pStmt;
2678 3032
2679 p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, 3033 p->rc = prepareAndCollectError(dbread, &pStmt, &p->zErrmsg,
2680 "PRAGMA schema_version" 3034 "PRAGMA schema_version"
2681 ); 3035 );
2682 if( p->rc==SQLITE_OK ){ 3036 if( p->rc==SQLITE_OK ){
2683 /* Coverage: it may be that this sqlite3_step() cannot fail. There 3037 /* Coverage: it may be that this sqlite3_step() cannot fail. There
2684 ** is already a transaction open, so the prepared statement cannot 3038 ** is already a transaction open, so the prepared statement cannot
2685 ** throw an SQLITE_SCHEMA exception. The only database page the 3039 ** throw an SQLITE_SCHEMA exception. The only database page the
2686 ** statement reads is page 1, which is guaranteed to be in the cache. 3040 ** statement reads is page 1, which is guaranteed to be in the cache.
2687 ** And no memory allocations are required. */ 3041 ** And no memory allocations are required. */
2688 if( SQLITE_ROW==sqlite3_step(pStmt) ){ 3042 if( SQLITE_ROW==sqlite3_step(pStmt) ){
2689 iCookie = sqlite3_column_int(pStmt, 0); 3043 iCookie = sqlite3_column_int(pStmt, 0);
2690 } 3044 }
2691 rbuFinalize(p, pStmt); 3045 rbuFinalize(p, pStmt);
2692 } 3046 }
2693 if( p->rc==SQLITE_OK ){ 3047 if( p->rc==SQLITE_OK ){
2694 rbuMPrintfExec(p, p->dbMain, "PRAGMA schema_version = %d", iCookie+1); 3048 rbuMPrintfExec(p, p->dbMain, "PRAGMA schema_version = %d", iCookie+1);
2695 } 3049 }
2696 } 3050 }
2697 } 3051 }
2698 3052
2699 /* 3053 /*
2700 ** Update the contents of the rbu_state table within the rbu database. The 3054 ** Update the contents of the rbu_state table within the rbu database. The
2701 ** value stored in the RBU_STATE_STAGE column is eStage. All other values 3055 ** value stored in the RBU_STATE_STAGE column is eStage. All other values
2702 ** are determined by inspecting the rbu handle passed as the first argument. 3056 ** are determined by inspecting the rbu handle passed as the first argument.
2703 */ 3057 */
2704 static void rbuSaveState(sqlite3rbu *p, int eStage){ 3058 static void rbuSaveState(sqlite3rbu *p, int eStage){
2705 if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){ 3059 if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){
2706 sqlite3_stmt *pInsert = 0; 3060 sqlite3_stmt *pInsert = 0;
3061 rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
2707 int rc; 3062 int rc;
2708 3063
2709 assert( p->zErrmsg==0 ); 3064 assert( p->zErrmsg==0 );
2710 rc = prepareFreeAndCollectError(p->dbRbu, &pInsert, &p->zErrmsg, 3065 rc = prepareFreeAndCollectError(p->dbRbu, &pInsert, &p->zErrmsg,
2711 sqlite3_mprintf( 3066 sqlite3_mprintf(
2712 "INSERT OR REPLACE INTO %s.rbu_state(k, v) VALUES " 3067 "INSERT OR REPLACE INTO %s.rbu_state(k, v) VALUES "
2713 "(%d, %d), " 3068 "(%d, %d), "
2714 "(%d, %Q), " 3069 "(%d, %Q), "
2715 "(%d, %Q), " 3070 "(%d, %Q), "
2716 "(%d, %d), " 3071 "(%d, %d), "
2717 "(%d, %d), " 3072 "(%d, %d), "
2718 "(%d, %lld), " 3073 "(%d, %lld), "
2719 "(%d, %lld), " 3074 "(%d, %lld), "
3075 "(%d, %lld), "
2720 "(%d, %lld) ", 3076 "(%d, %lld) ",
2721 p->zStateDb, 3077 p->zStateDb,
2722 RBU_STATE_STAGE, eStage, 3078 RBU_STATE_STAGE, eStage,
2723 RBU_STATE_TBL, p->objiter.zTbl, 3079 RBU_STATE_TBL, p->objiter.zTbl,
2724 RBU_STATE_IDX, p->objiter.zIdx, 3080 RBU_STATE_IDX, p->objiter.zIdx,
2725 RBU_STATE_ROW, p->nStep, 3081 RBU_STATE_ROW, p->nStep,
2726 RBU_STATE_PROGRESS, p->nProgress, 3082 RBU_STATE_PROGRESS, p->nProgress,
2727 RBU_STATE_CKPT, p->iWalCksum, 3083 RBU_STATE_CKPT, p->iWalCksum,
2728 RBU_STATE_COOKIE, (i64)p->pTargetFd->iCookie, 3084 RBU_STATE_COOKIE, (i64)pFd->iCookie,
2729 RBU_STATE_OALSZ, p->iOalSz 3085 RBU_STATE_OALSZ, p->iOalSz,
3086 RBU_STATE_PHASEONESTEP, p->nPhaseOneStep
2730 ) 3087 )
2731 ); 3088 );
2732 assert( pInsert==0 || rc==SQLITE_OK ); 3089 assert( pInsert==0 || rc==SQLITE_OK );
2733 3090
2734 if( rc==SQLITE_OK ){ 3091 if( rc==SQLITE_OK ){
2735 sqlite3_step(pInsert); 3092 sqlite3_step(pInsert);
2736 rc = sqlite3_finalize(pInsert); 3093 rc = sqlite3_finalize(pInsert);
2737 } 3094 }
2738 if( rc!=SQLITE_OK ) p->rc = rc; 3095 if( rc!=SQLITE_OK ) p->rc = rc;
2739 } 3096 }
2740 } 3097 }
2741 3098
2742 3099
2743 /* 3100 /*
3101 ** The second argument passed to this function is the name of a PRAGMA
3102 ** setting - "page_size", "auto_vacuum", "user_version" or "application_id".
3103 ** This function executes the following on sqlite3rbu.dbRbu:
3104 **
3105 ** "PRAGMA main.$zPragma"
3106 **
3107 ** where $zPragma is the string passed as the second argument, then
3108 ** on sqlite3rbu.dbMain:
3109 **
3110 ** "PRAGMA main.$zPragma = $val"
3111 **
3112 ** where $val is the value returned by the first PRAGMA invocation.
3113 **
3114 ** In short, it copies the value of the specified PRAGMA setting from
3115 ** dbRbu to dbMain.
3116 */
3117 static void rbuCopyPragma(sqlite3rbu *p, const char *zPragma){
3118 if( p->rc==SQLITE_OK ){
3119 sqlite3_stmt *pPragma = 0;
3120 p->rc = prepareFreeAndCollectError(p->dbRbu, &pPragma, &p->zErrmsg,
3121 sqlite3_mprintf("PRAGMA main.%s", zPragma)
3122 );
3123 if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPragma) ){
3124 p->rc = rbuMPrintfExec(p, p->dbMain, "PRAGMA main.%s = %d",
3125 zPragma, sqlite3_column_int(pPragma, 0)
3126 );
3127 }
3128 rbuFinalize(p, pPragma);
3129 }
3130 }
3131
3132 /*
3133 ** The RBU handle passed as the only argument has just been opened and
3134 ** the state database is empty. If this RBU handle was opened for an
3135 ** RBU vacuum operation, create the schema in the target db.
3136 */
3137 static void rbuCreateTargetSchema(sqlite3rbu *p){
3138 sqlite3_stmt *pSql = 0;
3139 sqlite3_stmt *pInsert = 0;
3140
3141 assert( rbuIsVacuum(p) );
3142 p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg);
3143 if( p->rc==SQLITE_OK ){
3144 p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg,
3145 "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0"
3146 " AND name!='sqlite_sequence' "
3147 " ORDER BY type DESC"
3148 );
3149 }
3150
3151 while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
3152 const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
3153 p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg);
3154 }
3155 rbuFinalize(p, pSql);
3156 if( p->rc!=SQLITE_OK ) return;
3157
3158 if( p->rc==SQLITE_OK ){
3159 p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg,
3160 "SELECT * FROM sqlite_master WHERE rootpage=0 OR rootpage IS NULL"
3161 );
3162 }
3163
3164 if( p->rc==SQLITE_OK ){
3165 p->rc = prepareAndCollectError(p->dbMain, &pInsert, &p->zErrmsg,
3166 "INSERT INTO sqlite_master VALUES(?,?,?,?,?)"
3167 );
3168 }
3169
3170 while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){
3171 int i;
3172 for(i=0; i<5; i++){
3173 sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i));
3174 }
3175 sqlite3_step(pInsert);
3176 p->rc = sqlite3_reset(pInsert);
3177 }
3178 if( p->rc==SQLITE_OK ){
3179 p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg);
3180 }
3181
3182 rbuFinalize(p, pSql);
3183 rbuFinalize(p, pInsert);
3184 }
3185
3186 /*
2744 ** Step the RBU object. 3187 ** Step the RBU object.
2745 */ 3188 */
2746 int sqlite3rbu_step(sqlite3rbu *p){ 3189 int sqlite3rbu_step(sqlite3rbu *p){
2747 if( p ){ 3190 if( p ){
2748 switch( p->eStage ){ 3191 switch( p->eStage ){
2749 case RBU_STAGE_OAL: { 3192 case RBU_STAGE_OAL: {
2750 RbuObjIter *pIter = &p->objiter; 3193 RbuObjIter *pIter = &p->objiter;
3194
3195 /* If this is an RBU vacuum operation and the state table was empty
3196 ** when this handle was opened, create the target database schema. */
3197 if( rbuIsVacuum(p) && p->nProgress==0 && p->rc==SQLITE_OK ){
3198 rbuCreateTargetSchema(p);
3199 rbuCopyPragma(p, "user_version");
3200 rbuCopyPragma(p, "application_id");
3201 }
3202
2751 while( p->rc==SQLITE_OK && pIter->zTbl ){ 3203 while( p->rc==SQLITE_OK && pIter->zTbl ){
2752 3204
2753 if( pIter->bCleanup ){ 3205 if( pIter->bCleanup ){
2754 /* Clean up the rbu_tmp_xxx table for the previous table. It 3206 /* Clean up the rbu_tmp_xxx table for the previous table. It
2755 ** cannot be dropped as there are currently active SQL statements. 3207 ** cannot be dropped as there are currently active SQL statements.
2756 ** But the contents can be deleted. */ 3208 ** But the contents can be deleted. */
2757 if( pIter->abIndexed ){ 3209 if( rbuIsVacuum(p)==0 && pIter->abIndexed ){
2758 rbuMPrintfExec(p, p->dbRbu, 3210 rbuMPrintfExec(p, p->dbRbu,
2759 "DELETE FROM %s.'rbu_tmp_%q'", p->zStateDb, pIter->zDataTbl 3211 "DELETE FROM %s.'rbu_tmp_%q'", p->zStateDb, pIter->zDataTbl
2760 ); 3212 );
2761 } 3213 }
2762 }else{ 3214 }else{
2763 rbuObjIterPrepareAll(p, pIter, 0); 3215 rbuObjIterPrepareAll(p, pIter, 0);
2764 3216
2765 /* Advance to the next row to process. */ 3217 /* Advance to the next row to process. */
2766 if( p->rc==SQLITE_OK ){ 3218 if( p->rc==SQLITE_OK ){
2767 int rc = sqlite3_step(pIter->pSelect); 3219 int rc = sqlite3_step(pIter->pSelect);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2835 default: 3287 default:
2836 break; 3288 break;
2837 } 3289 }
2838 return p->rc; 3290 return p->rc;
2839 }else{ 3291 }else{
2840 return SQLITE_NOMEM; 3292 return SQLITE_NOMEM;
2841 } 3293 }
2842 } 3294 }
2843 3295
2844 /* 3296 /*
2845 ** Free an RbuState object allocated by rbuLoadState().
2846 */
2847 static void rbuFreeState(RbuState *p){
2848 if( p ){
2849 sqlite3_free(p->zTbl);
2850 sqlite3_free(p->zIdx);
2851 sqlite3_free(p);
2852 }
2853 }
2854
2855 /*
2856 ** Allocate an RbuState object and load the contents of the rbu_state
2857 ** table into it. Return a pointer to the new object. It is the
2858 ** responsibility of the caller to eventually free the object using
2859 ** sqlite3_free().
2860 **
2861 ** If an error occurs, leave an error code and message in the rbu handle
2862 ** and return NULL.
2863 */
2864 static RbuState *rbuLoadState(sqlite3rbu *p){
2865 RbuState *pRet = 0;
2866 sqlite3_stmt *pStmt = 0;
2867 int rc;
2868 int rc2;
2869
2870 pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState));
2871 if( pRet==0 ) return 0;
2872
2873 rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
2874 sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb)
2875 );
2876 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
2877 switch( sqlite3_column_int(pStmt, 0) ){
2878 case RBU_STATE_STAGE:
2879 pRet->eStage = sqlite3_column_int(pStmt, 1);
2880 if( pRet->eStage!=RBU_STAGE_OAL
2881 && pRet->eStage!=RBU_STAGE_MOVE
2882 && pRet->eStage!=RBU_STAGE_CKPT
2883 ){
2884 p->rc = SQLITE_CORRUPT;
2885 }
2886 break;
2887
2888 case RBU_STATE_TBL:
2889 pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
2890 break;
2891
2892 case RBU_STATE_IDX:
2893 pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
2894 break;
2895
2896 case RBU_STATE_ROW:
2897 pRet->nRow = sqlite3_column_int(pStmt, 1);
2898 break;
2899
2900 case RBU_STATE_PROGRESS:
2901 pRet->nProgress = sqlite3_column_int64(pStmt, 1);
2902 break;
2903
2904 case RBU_STATE_CKPT:
2905 pRet->iWalCksum = sqlite3_column_int64(pStmt, 1);
2906 break;
2907
2908 case RBU_STATE_COOKIE:
2909 pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
2910 break;
2911
2912 case RBU_STATE_OALSZ:
2913 pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
2914 break;
2915
2916 default:
2917 rc = SQLITE_CORRUPT;
2918 break;
2919 }
2920 }
2921 rc2 = sqlite3_finalize(pStmt);
2922 if( rc==SQLITE_OK ) rc = rc2;
2923
2924 p->rc = rc;
2925 return pRet;
2926 }
2927
2928 /*
2929 ** Compare strings z1 and z2, returning 0 if they are identical, or non-zero 3297 ** Compare strings z1 and z2, returning 0 if they are identical, or non-zero
2930 ** otherwise. Either or both argument may be NULL. Two NULL values are 3298 ** otherwise. Either or both argument may be NULL. Two NULL values are
2931 ** considered equal, and NULL is considered distinct from all other values. 3299 ** considered equal, and NULL is considered distinct from all other values.
2932 */ 3300 */
2933 static int rbuStrCompare(const char *z1, const char *z2){ 3301 static int rbuStrCompare(const char *z1, const char *z2){
2934 if( z1==0 && z2==0 ) return 0; 3302 if( z1==0 && z2==0 ) return 0;
2935 if( z1==0 || z2==0 ) return 1; 3303 if( z1==0 || z2==0 ) return 1;
2936 return (sqlite3_stricmp(z1, z2)!=0); 3304 return (sqlite3_stricmp(z1, z2)!=0);
2937 } 3305 }
2938 3306
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
3014 ** argument by an earlier call to rbuCreateVfs(). 3382 ** argument by an earlier call to rbuCreateVfs().
3015 */ 3383 */
3016 static void rbuDeleteVfs(sqlite3rbu *p){ 3384 static void rbuDeleteVfs(sqlite3rbu *p){
3017 if( p->zVfsName ){ 3385 if( p->zVfsName ){
3018 sqlite3rbu_destroy_vfs(p->zVfsName); 3386 sqlite3rbu_destroy_vfs(p->zVfsName);
3019 p->zVfsName = 0; 3387 p->zVfsName = 0;
3020 } 3388 }
3021 } 3389 }
3022 3390
3023 /* 3391 /*
3024 ** Open and return a new RBU handle. 3392 ** This user-defined SQL function is invoked with a single argument - the
3393 ** name of a table expected to appear in the target database. It returns
3394 ** the number of auxilliary indexes on the table.
3025 */ 3395 */
3026 sqlite3rbu *sqlite3rbu_open( 3396 static void rbuIndexCntFunc(
3397 sqlite3_context *pCtx,
3398 int nVal,
3399 sqlite3_value **apVal
3400 ){
3401 sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx);
3402 sqlite3_stmt *pStmt = 0;
3403 char *zErrmsg = 0;
3404 int rc;
3405
3406 assert( nVal==1 );
3407
3408 rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg,
3409 sqlite3_mprintf("SELECT count(*) FROM sqlite_master "
3410 "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
3411 );
3412 if( rc!=SQLITE_OK ){
3413 sqlite3_result_error(pCtx, zErrmsg, -1);
3414 }else{
3415 int nIndex = 0;
3416 if( SQLITE_ROW==sqlite3_step(pStmt) ){
3417 nIndex = sqlite3_column_int(pStmt, 0);
3418 }
3419 rc = sqlite3_finalize(pStmt);
3420 if( rc==SQLITE_OK ){
3421 sqlite3_result_int(pCtx, nIndex);
3422 }else{
3423 sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1);
3424 }
3425 }
3426
3427 sqlite3_free(zErrmsg);
3428 }
3429
3430 /*
3431 ** If the RBU database contains the rbu_count table, use it to initialize
3432 ** the sqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table
3433 ** is assumed to contain the same columns as:
3434 **
3435 ** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
3436 **
3437 ** There should be one row in the table for each data_xxx table in the
3438 ** database. The 'tbl' column should contain the name of a data_xxx table,
3439 ** and the cnt column the number of rows it contains.
3440 **
3441 ** sqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt
3442 ** for all rows in the rbu_count table, where nIndex is the number of
3443 ** indexes on the corresponding target database table.
3444 */
3445 static void rbuInitPhaseOneSteps(sqlite3rbu *p){
3446 if( p->rc==SQLITE_OK ){
3447 sqlite3_stmt *pStmt = 0;
3448 int bExists = 0; /* True if rbu_count exists */
3449
3450 p->nPhaseOneStep = -1;
3451
3452 p->rc = sqlite3_create_function(p->dbRbu,
3453 "rbu_index_cnt", 1, SQLITE_UTF8, (void*)p, rbuIndexCntFunc, 0, 0
3454 );
3455
3456 /* Check for the rbu_count table. If it does not exist, or if an error
3457 ** occurs, nPhaseOneStep will be left set to -1. */
3458 if( p->rc==SQLITE_OK ){
3459 p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
3460 "SELECT 1 FROM sqlite_master WHERE tbl_name = 'rbu_count'"
3461 );
3462 }
3463 if( p->rc==SQLITE_OK ){
3464 if( SQLITE_ROW==sqlite3_step(pStmt) ){
3465 bExists = 1;
3466 }
3467 p->rc = sqlite3_finalize(pStmt);
3468 }
3469
3470 if( p->rc==SQLITE_OK && bExists ){
3471 p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
3472 "SELECT sum(cnt * (1 + rbu_index_cnt(rbu_target_name(tbl))))"
3473 "FROM rbu_count"
3474 );
3475 if( p->rc==SQLITE_OK ){
3476 if( SQLITE_ROW==sqlite3_step(pStmt) ){
3477 p->nPhaseOneStep = sqlite3_column_int64(pStmt, 0);
3478 }
3479 p->rc = sqlite3_finalize(pStmt);
3480 }
3481 }
3482 }
3483 }
3484
3485
3486 static sqlite3rbu *openRbuHandle(
3027 const char *zTarget, 3487 const char *zTarget,
3028 const char *zRbu, 3488 const char *zRbu,
3029 const char *zState 3489 const char *zState
3030 ){ 3490 ){
3031 sqlite3rbu *p; 3491 sqlite3rbu *p;
3032 int nTarget = strlen(zTarget); 3492 size_t nTarget = zTarget ? strlen(zTarget) : 0;
3033 int nRbu = strlen(zRbu); 3493 size_t nRbu = strlen(zRbu);
3034 int nState = zState ? strlen(zState) : 0; 3494 size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1;
3035 3495
3036 p = (sqlite3rbu*)sqlite3_malloc(sizeof(sqlite3rbu)+nTarget+1+nRbu+1+nState+1); 3496 p = (sqlite3rbu*)sqlite3_malloc64(nByte);
3037 if( p ){ 3497 if( p ){
3038 RbuState *pState = 0; 3498 RbuState *pState = 0;
3039 3499
3040 /* Create the custom VFS. */ 3500 /* Create the custom VFS. */
3041 memset(p, 0, sizeof(sqlite3rbu)); 3501 memset(p, 0, sizeof(sqlite3rbu));
3042 rbuCreateVfs(p); 3502 rbuCreateVfs(p);
3043 3503
3044 /* Open the target database */ 3504 /* Open the target, RBU and state databases */
3045 if( p->rc==SQLITE_OK ){ 3505 if( p->rc==SQLITE_OK ){
3046 p->zTarget = (char*)&p[1]; 3506 char *pCsr = (char*)&p[1];
3047 memcpy(p->zTarget, zTarget, nTarget+1); 3507 int bRetry = 0;
3048 p->zRbu = &p->zTarget[nTarget+1]; 3508 if( zTarget ){
3509 p->zTarget = pCsr;
3510 memcpy(p->zTarget, zTarget, nTarget+1);
3511 pCsr += nTarget+1;
3512 }
3513 p->zRbu = pCsr;
3049 memcpy(p->zRbu, zRbu, nRbu+1); 3514 memcpy(p->zRbu, zRbu, nRbu+1);
3515 pCsr += nRbu+1;
3050 if( zState ){ 3516 if( zState ){
3051 p->zState = &p->zRbu[nRbu+1]; 3517 p->zState = rbuMPrintf(p, "%s", zState);
3052 memcpy(p->zState, zState, nState+1);
3053 } 3518 }
3054 rbuOpenDatabase(p); 3519
3520 /* If the first attempt to open the database file fails and the bRetry
3521 ** flag it set, this means that the db was not opened because it seemed
3522 ** to be a wal-mode db. But, this may have happened due to an earlier
3523 ** RBU vacuum operation leaving an old wal file in the directory.
3524 ** If this is the case, it will have been checkpointed and deleted
3525 ** when the handle was closed and a second attempt to open the
3526 ** database may succeed. */
3527 rbuOpenDatabase(p, &bRetry);
3528 if( bRetry ){
3529 rbuOpenDatabase(p, 0);
3530 }
3055 } 3531 }
3056 3532
3057 /* If it has not already been created, create the rbu_state table */
3058 rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb);
3059
3060 if( p->rc==SQLITE_OK ){ 3533 if( p->rc==SQLITE_OK ){
3061 pState = rbuLoadState(p); 3534 pState = rbuLoadState(p);
3062 assert( pState || p->rc!=SQLITE_OK ); 3535 assert( pState || p->rc!=SQLITE_OK );
3063 if( p->rc==SQLITE_OK ){ 3536 if( p->rc==SQLITE_OK ){
3064 3537
3065 if( pState->eStage==0 ){ 3538 if( pState->eStage==0 ){
3066 rbuDeleteOalFile(p); 3539 rbuDeleteOalFile(p);
3540 rbuInitPhaseOneSteps(p);
3067 p->eStage = RBU_STAGE_OAL; 3541 p->eStage = RBU_STAGE_OAL;
3068 }else{ 3542 }else{
3069 p->eStage = pState->eStage; 3543 p->eStage = pState->eStage;
3544 p->nPhaseOneStep = pState->nPhaseOneStep;
3070 } 3545 }
3071 p->nProgress = pState->nProgress; 3546 p->nProgress = pState->nProgress;
3072 p->iOalSz = pState->iOalSz; 3547 p->iOalSz = pState->iOalSz;
3073 } 3548 }
3074 } 3549 }
3075 assert( p->rc!=SQLITE_OK || p->eStage!=0 ); 3550 assert( p->rc!=SQLITE_OK || p->eStage!=0 );
3076 3551
3077 if( p->rc==SQLITE_OK && p->pTargetFd->pWalFd ){ 3552 if( p->rc==SQLITE_OK && p->pTargetFd->pWalFd ){
3078 if( p->eStage==RBU_STAGE_OAL ){ 3553 if( p->eStage==RBU_STAGE_OAL ){
3079 p->rc = SQLITE_ERROR; 3554 p->rc = SQLITE_ERROR;
3080 p->zErrmsg = sqlite3_mprintf("cannot update wal mode database"); 3555 p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
3081 }else if( p->eStage==RBU_STAGE_MOVE ){ 3556 }else if( p->eStage==RBU_STAGE_MOVE ){
3082 p->eStage = RBU_STAGE_CKPT; 3557 p->eStage = RBU_STAGE_CKPT;
3083 p->nStep = 0; 3558 p->nStep = 0;
3084 } 3559 }
3085 } 3560 }
3086 3561
3087 if( p->rc==SQLITE_OK 3562 if( p->rc==SQLITE_OK
3088 && (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE) 3563 && (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE)
3089 && pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie 3564 && pState->eStage!=0
3090 ){ 3565 ){
3091 /* At this point (pTargetFd->iCookie) contains the value of the 3566 rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd);
3092 ** change-counter cookie (the thing that gets incremented when a 3567 if( pFd->iCookie!=pState->iCookie ){
3093 ** transaction is committed in rollback mode) currently stored on 3568 /* At this point (pTargetFd->iCookie) contains the value of the
3094 ** page 1 of the database file. */ 3569 ** change-counter cookie (the thing that gets incremented when a
3095 p->rc = SQLITE_BUSY; 3570 ** transaction is committed in rollback mode) currently stored on
3096 p->zErrmsg = sqlite3_mprintf("database modified during rbu update"); 3571 ** page 1 of the database file. */
3572 p->rc = SQLITE_BUSY;
3573 p->zErrmsg = sqlite3_mprintf("database modified during rbu %s",
3574 (rbuIsVacuum(p) ? "vacuum" : "update")
3575 );
3576 }
3097 } 3577 }
3098 3578
3099 if( p->rc==SQLITE_OK ){ 3579 if( p->rc==SQLITE_OK ){
3100 if( p->eStage==RBU_STAGE_OAL ){ 3580 if( p->eStage==RBU_STAGE_OAL ){
3101 sqlite3 *db = p->dbMain; 3581 sqlite3 *db = p->dbMain;
3102 3582 p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg);
3103 /* Open transactions both databases. The *-oal file is opened or
3104 ** created at this point. */
3105 p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
3106 if( p->rc==SQLITE_OK ){
3107 p->rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
3108 }
3109
3110 /* Check if the main database is a zipvfs db. If it is, set the upper
3111 ** level pager to use "journal_mode=off". This prevents it from
3112 ** generating a large journal using a temp file. */
3113 if( p->rc==SQLITE_OK ){
3114 int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0);
3115 if( frc==SQLITE_OK ){
3116 p->rc = sqlite3_exec(db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg);
3117 }
3118 }
3119 3583
3120 /* Point the object iterator at the first object */ 3584 /* Point the object iterator at the first object */
3121 if( p->rc==SQLITE_OK ){ 3585 if( p->rc==SQLITE_OK ){
3122 p->rc = rbuObjIterFirst(p, &p->objiter); 3586 p->rc = rbuObjIterFirst(p, &p->objiter);
3123 } 3587 }
3124 3588
3125 /* If the RBU database contains no data_xxx tables, declare the RBU 3589 /* If the RBU database contains no data_xxx tables, declare the RBU
3126 ** update finished. */ 3590 ** update finished. */
3127 if( p->rc==SQLITE_OK && p->objiter.zTbl==0 ){ 3591 if( p->rc==SQLITE_OK && p->objiter.zTbl==0 ){
3128 p->rc = SQLITE_DONE; 3592 p->rc = SQLITE_DONE;
3593 p->eStage = RBU_STAGE_DONE;
3594 }else{
3595 if( p->rc==SQLITE_OK && pState->eStage==0 && rbuIsVacuum(p) ){
3596 rbuCopyPragma(p, "page_size");
3597 rbuCopyPragma(p, "auto_vacuum");
3598 }
3599
3600 /* Open transactions both databases. The *-oal file is opened or
3601 ** created at this point. */
3602 if( p->rc==SQLITE_OK ){
3603 p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
3604 }
3605
3606 /* Check if the main database is a zipvfs db. If it is, set the upper
3607 ** level pager to use "journal_mode=off". This prevents it from
3608 ** generating a large journal using a temp file. */
3609 if( p->rc==SQLITE_OK ){
3610 int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0);
3611 if( frc==SQLITE_OK ){
3612 p->rc = sqlite3_exec(
3613 db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg);
3614 }
3615 }
3616
3617 if( p->rc==SQLITE_OK ){
3618 rbuSetupOal(p, pState);
3619 }
3129 } 3620 }
3130
3131 if( p->rc==SQLITE_OK ){
3132 rbuSetupOal(p, pState);
3133 }
3134
3135 }else if( p->eStage==RBU_STAGE_MOVE ){ 3621 }else if( p->eStage==RBU_STAGE_MOVE ){
3136 /* no-op */ 3622 /* no-op */
3137 }else if( p->eStage==RBU_STAGE_CKPT ){ 3623 }else if( p->eStage==RBU_STAGE_CKPT ){
3138 rbuSetupCheckpoint(p, pState); 3624 rbuSetupCheckpoint(p, pState);
3139 }else if( p->eStage==RBU_STAGE_DONE ){ 3625 }else if( p->eStage==RBU_STAGE_DONE ){
3140 p->rc = SQLITE_DONE; 3626 p->rc = SQLITE_DONE;
3141 }else{ 3627 }else{
3142 p->rc = SQLITE_CORRUPT; 3628 p->rc = SQLITE_CORRUPT;
3143 } 3629 }
3144 } 3630 }
3145 3631
3146 rbuFreeState(pState); 3632 rbuFreeState(pState);
3147 } 3633 }
3148 3634
3149 return p; 3635 return p;
3150 } 3636 }
3151 3637
3638 /*
3639 ** Allocate and return an RBU handle with all fields zeroed except for the
3640 ** error code, which is set to SQLITE_MISUSE.
3641 */
3642 static sqlite3rbu *rbuMisuseError(void){
3643 sqlite3rbu *pRet;
3644 pRet = sqlite3_malloc64(sizeof(sqlite3rbu));
3645 if( pRet ){
3646 memset(pRet, 0, sizeof(sqlite3rbu));
3647 pRet->rc = SQLITE_MISUSE;
3648 }
3649 return pRet;
3650 }
3651
3652 /*
3653 ** Open and return a new RBU handle.
3654 */
3655 sqlite3rbu *sqlite3rbu_open(
3656 const char *zTarget,
3657 const char *zRbu,
3658 const char *zState
3659 ){
3660 if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
3661 /* TODO: Check that zTarget and zRbu are non-NULL */
3662 return openRbuHandle(zTarget, zRbu, zState);
3663 }
3664
3665 /*
3666 ** Open a handle to begin or resume an RBU VACUUM operation.
3667 */
3668 sqlite3rbu *sqlite3rbu_vacuum(
3669 const char *zTarget,
3670 const char *zState
3671 ){
3672 if( zTarget==0 ){ return rbuMisuseError(); }
3673 /* TODO: Check that both arguments are non-NULL */
3674 return openRbuHandle(0, zTarget, zState);
3675 }
3152 3676
3153 /* 3677 /*
3154 ** Return the database handle used by pRbu. 3678 ** Return the database handle used by pRbu.
3155 */ 3679 */
3156 sqlite3 *sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){ 3680 sqlite3 *sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){
3157 sqlite3 *db = 0; 3681 sqlite3 *db = 0;
3158 if( pRbu ){ 3682 if( pRbu ){
3159 db = (bRbu ? pRbu->dbRbu : pRbu->dbMain); 3683 db = (bRbu ? pRbu->dbRbu : pRbu->dbMain);
3160 } 3684 }
3161 return db; 3685 return db;
3162 } 3686 }
3163 3687
3164 3688
3165 /* 3689 /*
3166 ** If the error code currently stored in the RBU handle is SQLITE_CONSTRAINT, 3690 ** If the error code currently stored in the RBU handle is SQLITE_CONSTRAINT,
3167 ** then edit any error message string so as to remove all occurrences of 3691 ** then edit any error message string so as to remove all occurrences of
3168 ** the pattern "rbu_imp_[0-9]*". 3692 ** the pattern "rbu_imp_[0-9]*".
3169 */ 3693 */
3170 static void rbuEditErrmsg(sqlite3rbu *p){ 3694 static void rbuEditErrmsg(sqlite3rbu *p){
3171 if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){ 3695 if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){
3172 int i; 3696 unsigned int i;
3173 int nErrmsg = strlen(p->zErrmsg); 3697 size_t nErrmsg = strlen(p->zErrmsg);
3174 for(i=0; i<(nErrmsg-8); i++){ 3698 for(i=0; i<(nErrmsg-8); i++){
3175 if( memcmp(&p->zErrmsg[i], "rbu_imp_", 8)==0 ){ 3699 if( memcmp(&p->zErrmsg[i], "rbu_imp_", 8)==0 ){
3176 int nDel = 8; 3700 int nDel = 8;
3177 while( p->zErrmsg[i+nDel]>='0' && p->zErrmsg[i+nDel]<='9' ) nDel++; 3701 while( p->zErrmsg[i+nDel]>='0' && p->zErrmsg[i+nDel]<='9' ) nDel++;
3178 memmove(&p->zErrmsg[i], &p->zErrmsg[i+nDel], nErrmsg + 1 - i - nDel); 3702 memmove(&p->zErrmsg[i], &p->zErrmsg[i+nDel], nErrmsg + 1 - i - nDel);
3179 nErrmsg -= nDel; 3703 nErrmsg -= nDel;
3180 } 3704 }
3181 } 3705 }
3182 } 3706 }
3183 } 3707 }
(...skipping 12 matching lines...) Expand all
3196 3720
3197 rbuSaveState(p, p->eStage); 3721 rbuSaveState(p, p->eStage);
3198 3722
3199 if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){ 3723 if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){
3200 p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg); 3724 p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg);
3201 } 3725 }
3202 3726
3203 /* Close any open statement handles. */ 3727 /* Close any open statement handles. */
3204 rbuObjIterFinalize(&p->objiter); 3728 rbuObjIterFinalize(&p->objiter);
3205 3729
3730 /* If this is an RBU vacuum handle and the vacuum has either finished
3731 ** successfully or encountered an error, delete the contents of the
3732 ** state table. This causes the next call to sqlite3rbu_vacuum()
3733 ** specifying the current target and state databases to start a new
3734 ** vacuum from scratch. */
3735 if( rbuIsVacuum(p) && p->rc!=SQLITE_OK && p->dbRbu ){
3736 int rc2 = sqlite3_exec(p->dbRbu, "DELETE FROM stat.rbu_state", 0, 0, 0);
3737 if( p->rc==SQLITE_DONE && rc2!=SQLITE_OK ) p->rc = rc2;
3738 }
3739
3206 /* Close the open database handle and VFS object. */ 3740 /* Close the open database handle and VFS object. */
3741 sqlite3_close(p->dbRbu);
3207 sqlite3_close(p->dbMain); 3742 sqlite3_close(p->dbMain);
3208 sqlite3_close(p->dbRbu);
3209 rbuDeleteVfs(p); 3743 rbuDeleteVfs(p);
3210 sqlite3_free(p->aBuf); 3744 sqlite3_free(p->aBuf);
3211 sqlite3_free(p->aFrame); 3745 sqlite3_free(p->aFrame);
3212 3746
3213 rbuEditErrmsg(p); 3747 rbuEditErrmsg(p);
3214 rc = p->rc; 3748 rc = p->rc;
3215 *pzErrmsg = p->zErrmsg; 3749 *pzErrmsg = p->zErrmsg;
3750 sqlite3_free(p->zState);
3216 sqlite3_free(p); 3751 sqlite3_free(p);
3217 }else{ 3752 }else{
3218 rc = SQLITE_NOMEM; 3753 rc = SQLITE_NOMEM;
3219 *pzErrmsg = 0; 3754 *pzErrmsg = 0;
3220 } 3755 }
3221 return rc; 3756 return rc;
3222 } 3757 }
3223 3758
3224 /* 3759 /*
3225 ** Return the total number of key-value operations (inserts, deletes or 3760 ** Return the total number of key-value operations (inserts, deletes or
3226 ** updates) that have been performed on the target database since the 3761 ** updates) that have been performed on the target database since the
3227 ** current RBU update was started. 3762 ** current RBU update was started.
3228 */ 3763 */
3229 sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu){ 3764 sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu){
3230 return pRbu->nProgress; 3765 return pRbu->nProgress;
3231 } 3766 }
3232 3767
3768 /*
3769 ** Return permyriadage progress indications for the two main stages of
3770 ** an RBU update.
3771 */
3772 void sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){
3773 const int MAX_PROGRESS = 10000;
3774 switch( p->eStage ){
3775 case RBU_STAGE_OAL:
3776 if( p->nPhaseOneStep>0 ){
3777 *pnOne = (int)(MAX_PROGRESS * (i64)p->nProgress/(i64)p->nPhaseOneStep);
3778 }else{
3779 *pnOne = -1;
3780 }
3781 *pnTwo = 0;
3782 break;
3783
3784 case RBU_STAGE_MOVE:
3785 *pnOne = MAX_PROGRESS;
3786 *pnTwo = 0;
3787 break;
3788
3789 case RBU_STAGE_CKPT:
3790 *pnOne = MAX_PROGRESS;
3791 *pnTwo = (int)(MAX_PROGRESS * (i64)p->nStep / (i64)p->nFrame);
3792 break;
3793
3794 case RBU_STAGE_DONE:
3795 *pnOne = MAX_PROGRESS;
3796 *pnTwo = MAX_PROGRESS;
3797 break;
3798
3799 default:
3800 assert( 0 );
3801 }
3802 }
3803
3804 /*
3805 ** Return the current state of the RBU vacuum or update operation.
3806 */
3807 int sqlite3rbu_state(sqlite3rbu *p){
3808 int aRes[] = {
3809 0, SQLITE_RBU_STATE_OAL, SQLITE_RBU_STATE_MOVE,
3810 0, SQLITE_RBU_STATE_CHECKPOINT, SQLITE_RBU_STATE_DONE
3811 };
3812
3813 assert( RBU_STAGE_OAL==1 );
3814 assert( RBU_STAGE_MOVE==2 );
3815 assert( RBU_STAGE_CKPT==4 );
3816 assert( RBU_STAGE_DONE==5 );
3817 assert( aRes[RBU_STAGE_OAL]==SQLITE_RBU_STATE_OAL );
3818 assert( aRes[RBU_STAGE_MOVE]==SQLITE_RBU_STATE_MOVE );
3819 assert( aRes[RBU_STAGE_CKPT]==SQLITE_RBU_STATE_CHECKPOINT );
3820 assert( aRes[RBU_STAGE_DONE]==SQLITE_RBU_STATE_DONE );
3821
3822 if( p->rc!=SQLITE_OK && p->rc!=SQLITE_DONE ){
3823 return SQLITE_RBU_STATE_ERROR;
3824 }else{
3825 assert( p->rc!=SQLITE_DONE || p->eStage==RBU_STAGE_DONE );
3826 assert( p->eStage==RBU_STAGE_OAL
3827 || p->eStage==RBU_STAGE_MOVE
3828 || p->eStage==RBU_STAGE_CKPT
3829 || p->eStage==RBU_STAGE_DONE
3830 );
3831 return aRes[p->eStage];
3832 }
3833 }
3834
3233 int sqlite3rbu_savestate(sqlite3rbu *p){ 3835 int sqlite3rbu_savestate(sqlite3rbu *p){
3234 int rc = p->rc; 3836 int rc = p->rc;
3235
3236 if( rc==SQLITE_DONE ) return SQLITE_OK; 3837 if( rc==SQLITE_DONE ) return SQLITE_OK;
3237 3838
3238 assert( p->eStage>=RBU_STAGE_OAL && p->eStage<=RBU_STAGE_DONE ); 3839 assert( p->eStage>=RBU_STAGE_OAL && p->eStage<=RBU_STAGE_DONE );
3239 if( p->eStage==RBU_STAGE_OAL ){ 3840 if( p->eStage==RBU_STAGE_OAL ){
3240 assert( rc!=SQLITE_DONE ); 3841 assert( rc!=SQLITE_DONE );
3241 if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0); 3842 if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0);
3242 } 3843 }
3243 3844
3244 p->rc = rc; 3845 p->rc = rc;
3245 rbuSaveState(p, p->eStage); 3846 rbuSaveState(p, p->eStage);
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
3365 ** passed as the only argument. 3966 ** passed as the only argument.
3366 */ 3967 */
3367 static u32 rbuGetU32(u8 *aBuf){ 3968 static u32 rbuGetU32(u8 *aBuf){
3368 return ((u32)aBuf[0] << 24) 3969 return ((u32)aBuf[0] << 24)
3369 + ((u32)aBuf[1] << 16) 3970 + ((u32)aBuf[1] << 16)
3370 + ((u32)aBuf[2] << 8) 3971 + ((u32)aBuf[2] << 8)
3371 + ((u32)aBuf[3]); 3972 + ((u32)aBuf[3]);
3372 } 3973 }
3373 3974
3374 /* 3975 /*
3976 ** Write an unsigned 32-bit value in big-endian format to the supplied
3977 ** buffer.
3978 */
3979 static void rbuPutU32(u8 *aBuf, u32 iVal){
3980 aBuf[0] = (iVal >> 24) & 0xFF;
3981 aBuf[1] = (iVal >> 16) & 0xFF;
3982 aBuf[2] = (iVal >> 8) & 0xFF;
3983 aBuf[3] = (iVal >> 0) & 0xFF;
3984 }
3985
3986 static void rbuPutU16(u8 *aBuf, u16 iVal){
3987 aBuf[0] = (iVal >> 8) & 0xFF;
3988 aBuf[1] = (iVal >> 0) & 0xFF;
3989 }
3990
3991 /*
3375 ** Read data from an rbuVfs-file. 3992 ** Read data from an rbuVfs-file.
3376 */ 3993 */
3377 static int rbuVfsRead( 3994 static int rbuVfsRead(
3378 sqlite3_file *pFile, 3995 sqlite3_file *pFile,
3379 void *zBuf, 3996 void *zBuf,
3380 int iAmt, 3997 int iAmt,
3381 sqlite_int64 iOfst 3998 sqlite_int64 iOfst
3382 ){ 3999 ){
3383 rbu_file *p = (rbu_file*)pFile; 4000 rbu_file *p = (rbu_file*)pFile;
3384 sqlite3rbu *pRbu = p->pRbu; 4001 sqlite3rbu *pRbu = p->pRbu;
3385 int rc; 4002 int rc;
3386 4003
3387 if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){ 4004 if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
3388 assert( p->openFlags & SQLITE_OPEN_WAL ); 4005 assert( p->openFlags & SQLITE_OPEN_WAL );
3389 rc = rbuCaptureWalRead(p->pRbu, iOfst, iAmt); 4006 rc = rbuCaptureWalRead(p->pRbu, iOfst, iAmt);
3390 }else{ 4007 }else{
3391 if( pRbu && pRbu->eStage==RBU_STAGE_OAL 4008 if( pRbu && pRbu->eStage==RBU_STAGE_OAL
3392 && (p->openFlags & SQLITE_OPEN_WAL) 4009 && (p->openFlags & SQLITE_OPEN_WAL)
3393 && iOfst>=pRbu->iOalSz 4010 && iOfst>=pRbu->iOalSz
3394 ){ 4011 ){
3395 rc = SQLITE_OK; 4012 rc = SQLITE_OK;
3396 memset(zBuf, 0, iAmt); 4013 memset(zBuf, 0, iAmt);
3397 }else{ 4014 }else{
3398 rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); 4015 rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
4016 #if 1
4017 /* If this is being called to read the first page of the target
4018 ** database as part of an rbu vacuum operation, synthesize the
4019 ** contents of the first page if it does not yet exist. Otherwise,
4020 ** SQLite will not check for a *-wal file. */
4021 if( pRbu && rbuIsVacuum(pRbu)
4022 && rc==SQLITE_IOERR_SHORT_READ && iOfst==0
4023 && (p->openFlags & SQLITE_OPEN_MAIN_DB)
4024 && pRbu->rc==SQLITE_OK
4025 ){
4026 sqlite3_file *pFd = (sqlite3_file*)pRbu->pRbuFd;
4027 rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst);
4028 if( rc==SQLITE_OK ){
4029 u8 *aBuf = (u8*)zBuf;
4030 u32 iRoot = rbuGetU32(&aBuf[52]) ? 1 : 0;
4031 rbuPutU32(&aBuf[52], iRoot); /* largest root page number */
4032 rbuPutU32(&aBuf[36], 0); /* number of free pages */
4033 rbuPutU32(&aBuf[32], 0); /* first page on free list trunk */
4034 rbuPutU32(&aBuf[28], 1); /* size of db file in pages */
4035 rbuPutU32(&aBuf[24], pRbu->pRbuFd->iCookie+1); /* Change counter */
4036
4037 if( iAmt>100 ){
4038 memset(&aBuf[100], 0, iAmt-100);
4039 rbuPutU16(&aBuf[105], iAmt & 0xFFFF);
4040 aBuf[100] = 0x0D;
4041 }
4042 }
4043 }
4044 #endif
3399 } 4045 }
3400 if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ 4046 if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
3401 /* These look like magic numbers. But they are stable, as they are part 4047 /* These look like magic numbers. But they are stable, as they are part
3402 ** of the definition of the SQLite file format, which may not change. */ 4048 ** of the definition of the SQLite file format, which may not change. */
3403 u8 *pBuf = (u8*)zBuf; 4049 u8 *pBuf = (u8*)zBuf;
3404 p->iCookie = rbuGetU32(&pBuf[24]); 4050 p->iCookie = rbuGetU32(&pBuf[24]);
3405 p->iWriteVer = pBuf[19]; 4051 p->iWriteVer = pBuf[19];
3406 } 4052 }
3407 } 4053 }
3408 return rc; 4054 return rc;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3463 return SQLITE_OK; 4109 return SQLITE_OK;
3464 } 4110 }
3465 return p->pReal->pMethods->xSync(p->pReal, flags); 4111 return p->pReal->pMethods->xSync(p->pReal, flags);
3466 } 4112 }
3467 4113
3468 /* 4114 /*
3469 ** Return the current file-size of an rbuVfs-file. 4115 ** Return the current file-size of an rbuVfs-file.
3470 */ 4116 */
3471 static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ 4117 static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
3472 rbu_file *p = (rbu_file *)pFile; 4118 rbu_file *p = (rbu_file *)pFile;
3473 return p->pReal->pMethods->xFileSize(p->pReal, pSize); 4119 int rc;
4120 rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
4121
4122 /* If this is an RBU vacuum operation and this is the target database,
4123 ** pretend that it has at least one page. Otherwise, SQLite will not
4124 ** check for the existance of a *-wal file. rbuVfsRead() contains
4125 ** similar logic. */
4126 if( rc==SQLITE_OK && *pSize==0
4127 && p->pRbu && rbuIsVacuum(p->pRbu)
4128 && (p->openFlags & SQLITE_OPEN_MAIN_DB)
4129 ){
4130 *pSize = 1024;
4131 }
4132 return rc;
3474 } 4133 }
3475 4134
3476 /* 4135 /*
3477 ** Lock an rbuVfs-file. 4136 ** Lock an rbuVfs-file.
3478 */ 4137 */
3479 static int rbuVfsLock(sqlite3_file *pFile, int eLock){ 4138 static int rbuVfsLock(sqlite3_file *pFile, int eLock){
3480 rbu_file *p = (rbu_file*)pFile; 4139 rbu_file *p = (rbu_file*)pFile;
3481 sqlite3rbu *pRbu = p->pRbu; 4140 sqlite3rbu *pRbu = p->pRbu;
3482 int rc = SQLITE_OK; 4141 int rc = SQLITE_OK;
3483 4142
3484 assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); 4143 assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
3485 if( pRbu && eLock==SQLITE_LOCK_EXCLUSIVE && pRbu->eStage!=RBU_STAGE_DONE ){ 4144 if( eLock==SQLITE_LOCK_EXCLUSIVE
4145 && (p->bNolock || (pRbu && pRbu->eStage!=RBU_STAGE_DONE))
4146 ){
3486 /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this 4147 /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this
3487 ** prevents it from checkpointing the database from sqlite3_close(). */ 4148 ** prevents it from checkpointing the database from sqlite3_close(). */
3488 rc = SQLITE_BUSY; 4149 rc = SQLITE_BUSY;
3489 }else{ 4150 }else{
3490 rc = p->pReal->pMethods->xLock(p->pReal, eLock); 4151 rc = p->pReal->pMethods->xLock(p->pReal, eLock);
3491 } 4152 }
3492 4153
3493 return rc; 4154 return rc;
3494 } 4155 }
3495 4156
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3538 pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error"); 4199 pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error");
3539 }else if( rc==SQLITE_NOTFOUND ){ 4200 }else if( rc==SQLITE_NOTFOUND ){
3540 pRbu->pTargetFd = p; 4201 pRbu->pTargetFd = p;
3541 p->pRbu = pRbu; 4202 p->pRbu = pRbu;
3542 if( p->pWalFd ) p->pWalFd->pRbu = pRbu; 4203 if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
3543 rc = SQLITE_OK; 4204 rc = SQLITE_OK;
3544 } 4205 }
3545 } 4206 }
3546 return rc; 4207 return rc;
3547 } 4208 }
4209 else if( op==SQLITE_FCNTL_RBUCNT ){
4210 sqlite3rbu *pRbu = (sqlite3rbu*)pArg;
4211 pRbu->nRbu++;
4212 pRbu->pRbuFd = p;
4213 p->bNolock = 1;
4214 }
3548 4215
3549 rc = xControl(p->pReal, op, pArg); 4216 rc = xControl(p->pReal, op, pArg);
3550 if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){ 4217 if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
3551 rbu_vfs *pRbuVfs = p->pRbuVfs; 4218 rbu_vfs *pRbuVfs = p->pRbuVfs;
3552 char *zIn = *(char**)pArg; 4219 char *zIn = *(char**)pArg;
3553 char *zOut = sqlite3_mprintf("rbu(%s)/%z", pRbuVfs->base.zName, zIn); 4220 char *zOut = sqlite3_mprintf("rbu(%s)/%z", pRbuVfs->base.zName, zIn);
3554 *(char**)pArg = zOut; 4221 *(char**)pArg = zOut;
3555 if( zOut==0 ) rc = SQLITE_NOMEM; 4222 if( zOut==0 ) rc = SQLITE_NOMEM;
3556 } 4223 }
3557 4224
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3627 int rc = SQLITE_OK; 4294 int rc = SQLITE_OK;
3628 int eStage = (p->pRbu ? p->pRbu->eStage : 0); 4295 int eStage = (p->pRbu ? p->pRbu->eStage : 0);
3629 4296
3630 /* If not in RBU_STAGE_OAL, allow this call to pass through. Or, if this 4297 /* If not in RBU_STAGE_OAL, allow this call to pass through. Or, if this
3631 ** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space 4298 ** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space
3632 ** instead of a file on disk. */ 4299 ** instead of a file on disk. */
3633 assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); 4300 assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
3634 if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){ 4301 if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
3635 if( iRegion<=p->nShm ){ 4302 if( iRegion<=p->nShm ){
3636 int nByte = (iRegion+1) * sizeof(char*); 4303 int nByte = (iRegion+1) * sizeof(char*);
3637 char **apNew = (char**)sqlite3_realloc(p->apShm, nByte); 4304 char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
3638 if( apNew==0 ){ 4305 if( apNew==0 ){
3639 rc = SQLITE_NOMEM; 4306 rc = SQLITE_NOMEM;
3640 }else{ 4307 }else{
3641 memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm)); 4308 memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
3642 p->apShm = apNew; 4309 p->apShm = apNew;
3643 p->nShm = iRegion+1; 4310 p->nShm = iRegion+1;
3644 } 4311 }
3645 } 4312 }
3646 4313
3647 if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){ 4314 if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
3648 char *pNew = (char*)sqlite3_malloc(szRegion); 4315 char *pNew = (char*)sqlite3_malloc64(szRegion);
3649 if( pNew==0 ){ 4316 if( pNew==0 ){
3650 rc = SQLITE_NOMEM; 4317 rc = SQLITE_NOMEM;
3651 }else{ 4318 }else{
3652 memset(pNew, 0, szRegion); 4319 memset(pNew, 0, szRegion);
3653 p->apShm[iRegion] = pNew; 4320 p->apShm[iRegion] = pNew;
3654 } 4321 }
3655 } 4322 }
3656 4323
3657 if( rc==SQLITE_OK ){ 4324 if( rc==SQLITE_OK ){
3658 *pp = p->apShm[iRegion]; 4325 *pp = p->apShm[iRegion];
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3696 4363
3697 /* 4364 /*
3698 ** Given that zWal points to a buffer containing a wal file name passed to 4365 ** Given that zWal points to a buffer containing a wal file name passed to
3699 ** either the xOpen() or xAccess() VFS method, return a pointer to the 4366 ** either the xOpen() or xAccess() VFS method, return a pointer to the
3700 ** file-handle opened by the same database connection on the corresponding 4367 ** file-handle opened by the same database connection on the corresponding
3701 ** database file. 4368 ** database file.
3702 */ 4369 */
3703 static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){ 4370 static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
3704 rbu_file *pDb; 4371 rbu_file *pDb;
3705 sqlite3_mutex_enter(pRbuVfs->mutex); 4372 sqlite3_mutex_enter(pRbuVfs->mutex);
3706 for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext); 4373 for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
3707 sqlite3_mutex_leave(pRbuVfs->mutex); 4374 sqlite3_mutex_leave(pRbuVfs->mutex);
3708 return pDb; 4375 return pDb;
3709 } 4376 }
3710 4377
4378 /*
4379 ** A main database named zName has just been opened. The following
4380 ** function returns a pointer to a buffer owned by SQLite that contains
4381 ** the name of the *-wal file this db connection will use. SQLite
4382 ** happens to pass a pointer to this buffer when using xAccess()
4383 ** or xOpen() to operate on the *-wal file.
4384 */
4385 static const char *rbuMainToWal(const char *zName, int flags){
4386 int n = (int)strlen(zName);
4387 const char *z = &zName[n];
4388 if( flags & SQLITE_OPEN_URI ){
4389 int odd = 0;
4390 while( 1 ){
4391 if( z[0]==0 ){
4392 odd = 1 - odd;
4393 if( odd && z[1]==0 ) break;
4394 }
4395 z++;
4396 }
4397 z += 2;
4398 }else{
4399 while( *z==0 ) z++;
4400 }
4401 z += (n + 8 + 1);
4402 return z;
4403 }
4404
3711 /* 4405 /*
3712 ** Open an rbu file handle. 4406 ** Open an rbu file handle.
3713 */ 4407 */
3714 static int rbuVfsOpen( 4408 static int rbuVfsOpen(
3715 sqlite3_vfs *pVfs, 4409 sqlite3_vfs *pVfs,
3716 const char *zName, 4410 const char *zName,
3717 sqlite3_file *pFile, 4411 sqlite3_file *pFile,
3718 int flags, 4412 int flags,
3719 int *pOutFlags 4413 int *pOutFlags
3720 ){ 4414 ){
(...skipping 15 matching lines...) Expand all
3736 rbuVfsShmLock, /* xShmLock */ 4430 rbuVfsShmLock, /* xShmLock */
3737 rbuVfsShmBarrier, /* xShmBarrier */ 4431 rbuVfsShmBarrier, /* xShmBarrier */
3738 rbuVfsShmUnmap, /* xShmUnmap */ 4432 rbuVfsShmUnmap, /* xShmUnmap */
3739 0, 0 /* xFetch, xUnfetch */ 4433 0, 0 /* xFetch, xUnfetch */
3740 }; 4434 };
3741 rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs; 4435 rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs;
3742 sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs; 4436 sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs;
3743 rbu_file *pFd = (rbu_file *)pFile; 4437 rbu_file *pFd = (rbu_file *)pFile;
3744 int rc = SQLITE_OK; 4438 int rc = SQLITE_OK;
3745 const char *zOpen = zName; 4439 const char *zOpen = zName;
4440 int oflags = flags;
3746 4441
3747 memset(pFd, 0, sizeof(rbu_file)); 4442 memset(pFd, 0, sizeof(rbu_file));
3748 pFd->pReal = (sqlite3_file*)&pFd[1]; 4443 pFd->pReal = (sqlite3_file*)&pFd[1];
3749 pFd->pRbuVfs = pRbuVfs; 4444 pFd->pRbuVfs = pRbuVfs;
3750 pFd->openFlags = flags; 4445 pFd->openFlags = flags;
3751 if( zName ){ 4446 if( zName ){
3752 if( flags & SQLITE_OPEN_MAIN_DB ){ 4447 if( flags & SQLITE_OPEN_MAIN_DB ){
3753 /* A main database has just been opened. The following block sets 4448 /* A main database has just been opened. The following block sets
3754 ** (pFd->zWal) to point to a buffer owned by SQLite that contains 4449 ** (pFd->zWal) to point to a buffer owned by SQLite that contains
3755 ** the name of the *-wal file this db connection will use. SQLite 4450 ** the name of the *-wal file this db connection will use. SQLite
3756 ** happens to pass a pointer to this buffer when using xAccess() 4451 ** happens to pass a pointer to this buffer when using xAccess()
3757 ** or xOpen() to operate on the *-wal file. */ 4452 ** or xOpen() to operate on the *-wal file. */
3758 int n = strlen(zName); 4453 pFd->zWal = rbuMainToWal(zName, flags);
3759 const char *z = &zName[n];
3760 if( flags & SQLITE_OPEN_URI ){
3761 int odd = 0;
3762 while( 1 ){
3763 if( z[0]==0 ){
3764 odd = 1 - odd;
3765 if( odd && z[1]==0 ) break;
3766 }
3767 z++;
3768 }
3769 z += 2;
3770 }else{
3771 while( *z==0 ) z++;
3772 }
3773 z += (n + 8 + 1);
3774 pFd->zWal = z;
3775 } 4454 }
3776 else if( flags & SQLITE_OPEN_WAL ){ 4455 else if( flags & SQLITE_OPEN_WAL ){
3777 rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName); 4456 rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
3778 if( pDb ){ 4457 if( pDb ){
3779 if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ 4458 if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
3780 /* This call is to open a *-wal file. Intead, open the *-oal. This 4459 /* This call is to open a *-wal file. Intead, open the *-oal. This
3781 ** code ensures that the string passed to xOpen() is terminated by a 4460 ** code ensures that the string passed to xOpen() is terminated by a
3782 ** pair of '\0' bytes in case the VFS attempts to extract a URI 4461 ** pair of '\0' bytes in case the VFS attempts to extract a URI
3783 ** parameter from it. */ 4462 ** parameter from it. */
3784 int nCopy = strlen(zName); 4463 const char *zBase = zName;
3785 char *zCopy = sqlite3_malloc(nCopy+2); 4464 size_t nCopy;
4465 char *zCopy;
4466 if( rbuIsVacuum(pDb->pRbu) ){
4467 zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
4468 zBase = rbuMainToWal(zBase, SQLITE_OPEN_URI);
4469 }
4470 nCopy = strlen(zBase);
4471 zCopy = sqlite3_malloc64(nCopy+2);
3786 if( zCopy ){ 4472 if( zCopy ){
3787 memcpy(zCopy, zName, nCopy); 4473 memcpy(zCopy, zBase, nCopy);
3788 zCopy[nCopy-3] = 'o'; 4474 zCopy[nCopy-3] = 'o';
3789 zCopy[nCopy] = '\0'; 4475 zCopy[nCopy] = '\0';
3790 zCopy[nCopy+1] = '\0'; 4476 zCopy[nCopy+1] = '\0';
3791 zOpen = (const char*)(pFd->zDel = zCopy); 4477 zOpen = (const char*)(pFd->zDel = zCopy);
3792 }else{ 4478 }else{
3793 rc = SQLITE_NOMEM; 4479 rc = SQLITE_NOMEM;
3794 } 4480 }
3795 pFd->pRbu = pDb->pRbu; 4481 pFd->pRbu = pDb->pRbu;
3796 } 4482 }
3797 pDb->pWalFd = pFd; 4483 pDb->pWalFd = pFd;
3798 } 4484 }
3799 } 4485 }
3800 } 4486 }
3801 4487
4488 if( oflags & SQLITE_OPEN_MAIN_DB
4489 && sqlite3_uri_boolean(zName, "rbu_memory", 0)
4490 ){
4491 assert( oflags & SQLITE_OPEN_MAIN_DB );
4492 oflags = SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
4493 SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
4494 zOpen = 0;
4495 }
4496
3802 if( rc==SQLITE_OK ){ 4497 if( rc==SQLITE_OK ){
3803 rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, flags, pOutFlags); 4498 rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags);
3804 } 4499 }
3805 if( pFd->pReal->pMethods ){ 4500 if( pFd->pReal->pMethods ){
3806 /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods 4501 /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
3807 ** pointer and, if the file is a main database file, link it into the 4502 ** pointer and, if the file is a main database file, link it into the
3808 ** mutex protected linked list of all such files. */ 4503 ** mutex protected linked list of all such files. */
3809 pFile->pMethods = &rbuvfs_io_methods; 4504 pFile->pMethods = &rbuvfs_io_methods;
3810 if( flags & SQLITE_OPEN_MAIN_DB ){ 4505 if( flags & SQLITE_OPEN_MAIN_DB ){
3811 sqlite3_mutex_enter(pRbuVfs->mutex); 4506 sqlite3_mutex_enter(pRbuVfs->mutex);
3812 pFd->pMainNext = pRbuVfs->pMain; 4507 pFd->pMainNext = pRbuVfs->pMain;
3813 pRbuVfs->pMain = pFd; 4508 pRbuVfs->pMain = pFd;
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
4004 4699
4005 rbuVfsRandomness, /* xRandomness */ 4700 rbuVfsRandomness, /* xRandomness */
4006 rbuVfsSleep, /* xSleep */ 4701 rbuVfsSleep, /* xSleep */
4007 rbuVfsCurrentTime, /* xCurrentTime */ 4702 rbuVfsCurrentTime, /* xCurrentTime */
4008 rbuVfsGetLastError, /* xGetLastError */ 4703 rbuVfsGetLastError, /* xGetLastError */
4009 0, /* xCurrentTimeInt64 (version 2) */ 4704 0, /* xCurrentTimeInt64 (version 2) */
4010 0, 0, 0 /* Unimplemented version 3 methods */ 4705 0, 0, 0 /* Unimplemented version 3 methods */
4011 }; 4706 };
4012 4707
4013 rbu_vfs *pNew = 0; /* Newly allocated VFS */ 4708 rbu_vfs *pNew = 0; /* Newly allocated VFS */
4014 int nName;
4015 int rc = SQLITE_OK; 4709 int rc = SQLITE_OK;
4710 size_t nName;
4711 size_t nByte;
4016 4712
4017 int nByte;
4018 nName = strlen(zName); 4713 nName = strlen(zName);
4019 nByte = sizeof(rbu_vfs) + nName + 1; 4714 nByte = sizeof(rbu_vfs) + nName + 1;
4020 pNew = (rbu_vfs*)sqlite3_malloc(nByte); 4715 pNew = (rbu_vfs*)sqlite3_malloc64(nByte);
4021 if( pNew==0 ){ 4716 if( pNew==0 ){
4022 rc = SQLITE_NOMEM; 4717 rc = SQLITE_NOMEM;
4023 }else{ 4718 }else{
4024 sqlite3_vfs *pParent; /* Parent VFS */ 4719 sqlite3_vfs *pParent; /* Parent VFS */
4025 memset(pNew, 0, nByte); 4720 memset(pNew, 0, nByte);
4026 pParent = sqlite3_vfs_find(zParent); 4721 pParent = sqlite3_vfs_find(zParent);
4027 if( pParent==0 ){ 4722 if( pParent==0 ){
4028 rc = SQLITE_NOTFOUND; 4723 rc = SQLITE_NOTFOUND;
4029 }else{ 4724 }else{
4030 char *zSpace; 4725 char *zSpace;
(...skipping 19 matching lines...) Expand all
4050 } 4745 }
4051 } 4746 }
4052 4747
4053 return rc; 4748 return rc;
4054 } 4749 }
4055 4750
4056 4751
4057 /**************************************************************************/ 4752 /**************************************************************************/
4058 4753
4059 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */ 4754 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */
OLDNEW
« no previous file with comments | « third_party/sqlite/src/ext/rbu/sqlite3rbu.h ('k') | third_party/sqlite/src/ext/rbu/test_rbu.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698