Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge latest trunk changes, including test case fixes, with this branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | tempfiles-25 |
Files: | files | file ages | folders |
SHA1: |
99794aca7b6cb40f08ce4db9889a989f |
User & Date: | dan 2016-04-29 11:35:28.485 |
Context
2016-04-29
| ||
14:12 | Fix test script temptable2.test so that it works with the "inmemory_journal" and "journaltest" permutations. (Closed-Leaf check-in: b7bec7f2d3 user: dan tags: tempfiles-25) | |
11:35 | Merge latest trunk changes, including test case fixes, with this branch. (check-in: 99794aca7b user: dan tags: tempfiles-25) | |
11:33 | Modify the permutations.test script so as to set any permutation specific configuration values before running each individual test script. Fix a mostly harmless buffer overread in the sessions module. (check-in: 4cbd502454 user: dan tags: trunk) | |
2016-04-27
| ||
11:24 | Fix a couple of test script problems on this branch. Both related to the fact that temp database page sizes can no longer be changed by VACUUM or the backup API after the temp db is populated. (check-in: 6bb5aa2be2 user: dan tags: tempfiles-25) | |
Changes
Changes to ext/session/sessionfault.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl set testprefix sessionfault forcedelete test.db2 sqlite3 db2 test.db2 do_common_sql { CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b)); | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl ifcapable !session {finish_test; return} set testprefix sessionfault forcedelete test.db2 sqlite3 db2 test.db2 do_common_sql { CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b)); |
︙ | ︙ |
Changes to ext/session/sessionfault2.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl set testprefix sessionfault2 do_execsql_test 1.0.0 { CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); INSERT INTO t1 VALUES(1, 1); INSERT INTO t1 VALUES(2, 2); INSERT INTO t1 VALUES(3, 3); | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl ifcapable !session {finish_test; return} set testprefix sessionfault2 do_execsql_test 1.0.0 { CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); INSERT INTO t1 VALUES(1, 1); INSERT INTO t1 VALUES(2, 2); INSERT INTO t1 VALUES(3, 3); |
︙ | ︙ |
Changes to ext/session/sqlite3session.c.
︙ | ︙ | |||
588 589 590 591 592 593 594 | u8 *aRight /* Change record */ ){ u8 *a1 = aLeft; /* Cursor to iterate through aLeft */ u8 *a2 = aRight; /* Cursor to iterate through aRight */ int iCol; /* Used to iterate through table columns */ for(iCol=0; iCol<pTab->nCol; iCol++){ | > | | | | | > > > | | > | 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 | u8 *aRight /* Change record */ ){ u8 *a1 = aLeft; /* Cursor to iterate through aLeft */ u8 *a2 = aRight; /* Cursor to iterate through aRight */ int iCol; /* Used to iterate through table columns */ for(iCol=0; iCol<pTab->nCol; iCol++){ if( pTab->abPK[iCol] ){ int n1 = sessionSerialLen(a1); int n2 = sessionSerialLen(a2); if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){ return 0; } a1 += n1; a2 += n2; }else{ if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1); if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2); } } return 1; } /* ** Arguments aLeft and aRight both point to buffers containing change |
︙ | ︙ |
Changes to src/hash.c.
︙ | ︙ | |||
51 52 53 54 55 56 57 | /* ** The hashing function. */ static unsigned int strHash(const char *z){ unsigned int h = 0; unsigned char c; | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | /* ** The hashing function. */ static unsigned int strHash(const char *z){ unsigned int h = 0; unsigned char c; while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/ h = (h<<3) ^ h ^ sqlite3UpperToLower[c]; } return h; } /* Link pNew element into the hash table pH. If pEntry!=0 then also |
︙ | ︙ | |||
144 145 146 147 148 149 150 | const char *pKey, /* The key we are searching for */ unsigned int *pHash /* Write the hash value here */ ){ HashElem *elem; /* Used to loop thru the element list */ int count; /* Number of elements left to test */ unsigned int h; /* The computed hash */ | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | const char *pKey, /* The key we are searching for */ unsigned int *pHash /* Write the hash value here */ ){ HashElem *elem; /* Used to loop thru the element list */ int count; /* Number of elements left to test */ unsigned int h; /* The computed hash */ if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/ struct _ht *pEntry; h = strHash(pKey) % pH->htsize; pEntry = &pH->ht[h]; elem = pEntry->chain; count = pEntry->count; }else{ h = 0; |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
4284 4285 4286 4287 4288 4289 4290 | #else sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath); sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); #endif pShmNode->h = -1; pDbFd->pInode->pShmNode = pShmNode; pShmNode->pInode = pDbFd->pInode; | > | | | | > | 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 | #else sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath); sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); #endif pShmNode->h = -1; pDbFd->pInode->pShmNode = pShmNode; pShmNode->pInode = pDbFd->pInode; if( sqlite3GlobalConfig.bCoreMutex ){ pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pShmNode->mutex==0 ){ rc = SQLITE_NOMEM_BKPT; goto shm_open_err; } } if( pInode->bProcessLock==0 ){ int openFlags = O_RDWR | O_CREAT; if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ openFlags = O_RDONLY; pShmNode->isReadonly = 1; |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
1256 1257 1258 1259 1260 1261 1262 | ** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will ** be returned and no changes will be made to the Win32 native heap. */ int sqlite3_win32_reset_heap(){ int rc; MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */ | | | | 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 | ** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will ** be returned and no changes will be made to the Win32 native heap. */ int sqlite3_win32_reset_heap(){ int rc; MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */ MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); ) sqlite3_mutex_enter(pMaster); sqlite3_mutex_enter(pMem); winMemAssertMagic(); if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){ /* ** At this point, there should be no outstanding memory allocations on ** the heap. Also, since both the master and memsys locks are currently |
︙ | ︙ | |||
3760 3761 3762 3763 3764 3765 3766 | }else{ pShmNode = pNew; pNew = 0; ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; pShmNode->pNext = winShmNodeList; winShmNodeList = pShmNode; | > | | | | > | 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 | }else{ pShmNode = pNew; pNew = 0; ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; pShmNode->pNext = winShmNodeList; winShmNodeList = pShmNode; if( sqlite3GlobalConfig.bCoreMutex ){ pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pShmNode->mutex==0 ){ rc = SQLITE_IOERR_NOMEM_BKPT; goto shm_open_err; } } rc = winOpen(pDbFd->pVfs, pShmNode->zFilename, /* Name of the file (UTF-8) */ (sqlite3_file*)&pShmNode->hFile, /* File handle here */ SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); |
︙ | ︙ |
Changes to src/pcache1.c.
︙ | ︙ | |||
686 687 688 689 690 691 692 | || sqlite3GlobalConfig.bCoreMutex>0; #else pcache1.separateCache = sqlite3GlobalConfig.pPage==0; #endif #if SQLITE_THREADSAFE if( sqlite3GlobalConfig.bCoreMutex ){ | | | | 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 | || sqlite3GlobalConfig.bCoreMutex>0; #else pcache1.separateCache = sqlite3GlobalConfig.pPage==0; #endif #if SQLITE_THREADSAFE if( sqlite3GlobalConfig.bCoreMutex ){ pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU); pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM); } #endif if( pcache1.separateCache && sqlite3GlobalConfig.nPage!=0 && sqlite3GlobalConfig.pPage==0 ){ pcache1.nInitPage = sqlite3GlobalConfig.nPage; |
︙ | ︙ |
Changes to src/rowset.c.
︙ | ︙ | |||
53 54 55 56 57 58 59 | ** The cost of an INSERT is roughly constant. (Sometimes new memory ** has to be allocated on an INSERT.) The cost of a TEST with a new ** batch number is O(NlogN) where N is the number of elements in the RowSet. ** The cost of a TEST using the same batch number is O(logN). The cost ** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST ** primitives are constant time. The cost of DESTROY is O(N). ** | | > | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | ** The cost of an INSERT is roughly constant. (Sometimes new memory ** has to be allocated on an INSERT.) The cost of a TEST with a new ** batch number is O(NlogN) where N is the number of elements in the RowSet. ** The cost of a TEST using the same batch number is O(logN). The cost ** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST ** primitives are constant time. The cost of DESTROY is O(N). ** ** TEST and SMALLEST may not be used by the same RowSet. This used to ** be possible, but the feature was not used, so it was removed in order ** to simplify the code. */ #include "sqliteInt.h" /* ** Target size for allocation chunks. */ |
︙ | ︙ | |||
175 176 177 178 179 180 181 | ** objected. ** ** In an OOM situation, the RowSet.db->mallocFailed flag is set and this ** routine returns NULL. */ static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ assert( p!=0 ); | | > > | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | ** objected. ** ** In an OOM situation, the RowSet.db->mallocFailed flag is set and this ** routine returns NULL. */ static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ assert( p!=0 ); if( p->nFresh==0 ){ /*OPTIMIZATION-IF-FALSE*/ /* We could allocate a fresh RowSetEntry each time one is needed, but it ** is more efficient to pull a preallocated entry from the pool */ struct RowSetChunk *pNew; pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew)); if( pNew==0 ){ return 0; } pNew->pNextChunk = p->pChunk; p->pChunk = pNew; |
︙ | ︙ | |||
209 210 211 212 213 214 215 | pEntry = rowSetEntryAlloc(p); if( pEntry==0 ) return; pEntry->v = rowid; pEntry->pRight = 0; pLast = p->pLast; if( pLast ){ | | > > | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | pEntry = rowSetEntryAlloc(p); if( pEntry==0 ) return; pEntry->v = rowid; pEntry->pRight = 0; pLast = p->pLast; if( pLast ){ if( rowid<=pLast->v ){ /*OPTIMIZATION-IF-FALSE*/ /* Avoid unnecessary sorts by preserving the ROWSET_SORTED flags ** where possible */ p->rsFlags &= ~ROWSET_SORTED; } pLast->pRight = pEntry; }else{ p->pEntry = pEntry; } p->pLast = pEntry; |
︙ | ︙ | |||
331 332 333 334 335 336 337 | */ static struct RowSetEntry *rowSetNDeepTree( struct RowSetEntry **ppList, int iDepth ){ struct RowSetEntry *p; /* Root of the new tree */ struct RowSetEntry *pLeft; /* Left subtree */ | | > | | < | | | < | | | > > | | | | | > > > > > | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | */ static struct RowSetEntry *rowSetNDeepTree( struct RowSetEntry **ppList, int iDepth ){ struct RowSetEntry *p; /* Root of the new tree */ struct RowSetEntry *pLeft; /* Left subtree */ if( *ppList==0 ){ /*OPTIMIZATION-IF-TRUE*/ /* Prevent unnecessary deep recursion when we run out of entries */ return 0; } if( iDepth>1 ){ /*OPTIMIZATION-IF-TRUE*/ /* This branch causes a *balanced* tree to be generated. A valid tree ** is still generated without this branch, but the tree is wildly ** unbalanced and inefficient. */ pLeft = rowSetNDeepTree(ppList, iDepth-1); p = *ppList; if( p==0 ){ /*OPTIMIZATION-IF-FALSE*/ /* It is safe to always return here, but the resulting tree ** would be unbalanced */ return pLeft; } p->pLeft = pLeft; *ppList = p->pRight; p->pRight = rowSetNDeepTree(ppList, iDepth-1); }else{ p = *ppList; *ppList = p->pRight; p->pLeft = p->pRight = 0; } return p; } /* ** Convert a sorted list of elements into a binary tree. Make the tree ** as deep as it needs to be in order to contain the entire list. */ |
︙ | ︙ | |||
374 375 376 377 378 379 380 | pList = p->pRight; p->pLeft = pLeft; p->pRight = rowSetNDeepTree(&pList, iDepth); } return p; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > > > > > > | > > > > > | > | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | pList = p->pRight; p->pLeft = pLeft; p->pRight = rowSetNDeepTree(&pList, iDepth); } return p; } /* ** Extract the smallest element from the RowSet. ** Write the element into *pRowid. Return 1 on success. Return ** 0 if the RowSet is already empty. ** ** After this routine has been called, the sqlite3RowSetInsert() ** routine may not be called again. ** ** This routine may not be called after sqlite3RowSetTest() has ** been used. Older versions of RowSet allowed that, but as the ** capability was not used by the code generator, it was removed ** for code economy. */ int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ assert( p!=0 ); assert( p->pForest==0 ); /* Cannot be used with sqlite3RowSetText() */ /* Merge the forest into a single sorted list on first call */ if( (p->rsFlags & ROWSET_NEXT)==0 ){ /*OPTIMIZATION-IF-FALSE*/ if( (p->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/ p->pEntry = rowSetEntrySort(p->pEntry); } p->rsFlags |= ROWSET_SORTED|ROWSET_NEXT; } /* Return the next entry on the list */ if( p->pEntry ){ *pRowid = p->pEntry->v; p->pEntry = p->pEntry->pRight; if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/ /* Free memory immediately, rather than waiting on sqlite3_finalize() */ sqlite3RowSetClear(p); } return 1; }else{ return 0; } } |
︙ | ︙ | |||
449 450 451 452 453 454 455 | */ int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ struct RowSetEntry *p, *pTree; /* This routine is never called after sqlite3RowSetNext() */ assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); | | > | | > | 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | */ int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ struct RowSetEntry *p, *pTree; /* This routine is never called after sqlite3RowSetNext() */ assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); /* Sort entries into the forest on the first test of a new batch. ** To save unnecessary work, only do this when the batch number changes. */ if( iBatch!=pRowSet->iBatch ){ /*OPTIMIZATION-IF-FALSE*/ p = pRowSet->pEntry; if( p ){ struct RowSetEntry **ppPrevTree = &pRowSet->pForest; if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/ /* Only sort the current set of entiries if they need it */ p = rowSetEntrySort(p); } for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ ppPrevTree = &pTree->pRight; if( pTree->pLeft==0 ){ pTree->pLeft = rowSetListToTree(p); break; |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** ************************************************************************* ** Internal interface definitions for SQLite. ** */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Make sure that rand_s() is available on Windows systems with MSVC 2005 ** or higher. */ #if defined(_MSC_VER) && _MSC_VER>=1400 # define _CRT_RAND_S | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | ** ************************************************************************* ** Internal interface definitions for SQLite. ** */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* Special Comments: ** ** Some comments have special meaning to the tools that measure test ** coverage: ** ** NO_TEST - The branches on this line are not ** measured by branch coverage. This is ** used on lines of code that actually ** implement parts of coverage testing. ** ** OPTIMIZATION-IF-TRUE - This branch is allowed to alway be false ** and the correct answer is still obtained, ** though perhaps more slowly. ** ** OPTIMIZATION-IF-FALSE - This branch is allowed to alway be true ** and the correct answer is still obtained, ** though perhaps more slowly. ** ** PREVENTS-HARMLESS-OVERREAD - This branch prevents a buffer overread ** that would be harmless and undetectable ** if it did occur. ** ** In all cases, the special comment must be enclosed in the usual ** slash-asterisk...asterisk-slash comment marks, with no spaces between the ** asterisks and the comment text. */ /* ** Make sure that rand_s() is available on Windows systems with MSVC 2005 ** or higher. */ #if defined(_MSC_VER) && _MSC_VER>=1400 # define _CRT_RAND_S |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
1267 1268 1269 1270 1271 1272 1273 | char *z; if( argc!=5 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FORMAT INT INT INT\"", 0); return TCL_ERROR; } for(i=2; i<5; i++){ | | | 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 | char *z; if( argc!=5 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FORMAT INT INT INT\"", 0); return TCL_ERROR; } for(i=2; i<5; i++){ if( sqlite3Atoi64(argv[i], &a[i-2], sqlite3Strlen30(argv[i]), SQLITE_UTF8) ){ Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0); return TCL_ERROR; } } z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); Tcl_AppendResult(interp, z, 0); sqlite3_free(z); |
︙ | ︙ | |||
5209 5210 5211 5212 5213 5214 5215 | } nVfs = i; return TCL_OK; } /* ** tclcmd: vfs_reregister_all ** | | > > | | | 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 | } nVfs = i; return TCL_OK; } /* ** tclcmd: vfs_reregister_all ** ** Restore all VFSes that were removed using vfs_unregister_all. Taking ** care to put the linked list back together in the same order as it was ** in before vfs_unregister_all was invoked. */ static int vfs_reregister_all( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ int i; for(i=nVfs-1; i>=0; i--){ sqlite3_vfs_register(apVfs[i], 1); } return TCL_OK; } /* ** tclcmd: file_control_test DB |
︙ | ︙ |
Changes to src/test6.c.
︙ | ︙ | |||
697 698 699 700 701 702 703 704 705 706 707 708 709 710 | sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; return pVfs->xSleep(pVfs, nMicro); } static int cfCurrentTime(sqlite3_vfs *pCfVfs, double *pTimeOut){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; return pVfs->xCurrentTime(pVfs, pTimeOut); } static int processDevSymArgs( Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int *piDeviceChar, int *piSectorSize | > > > > | 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 | sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; return pVfs->xSleep(pVfs, nMicro); } static int cfCurrentTime(sqlite3_vfs *pCfVfs, double *pTimeOut){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; return pVfs->xCurrentTime(pVfs, pTimeOut); } static int cfGetLastError(sqlite3_vfs *pCfVfs, int n, char *z){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; return pVfs->xGetLastError(pVfs, n, z); } static int processDevSymArgs( Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int *piDeviceChar, int *piSectorSize |
︙ | ︙ | |||
823 824 825 826 827 828 829 | cfDlOpen, /* xDlOpen */ cfDlError, /* xDlError */ cfDlSym, /* xDlSym */ cfDlClose, /* xDlClose */ cfRandomness, /* xRandomness */ cfSleep, /* xSleep */ cfCurrentTime, /* xCurrentTime */ | | | 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 | cfDlOpen, /* xDlOpen */ cfDlError, /* xDlError */ cfDlSym, /* xDlSym */ cfDlClose, /* xDlClose */ cfRandomness, /* xRandomness */ cfSleep, /* xSleep */ cfCurrentTime, /* xCurrentTime */ cfGetLastError, /* xGetLastError */ 0, /* xCurrentTimeInt64 */ }; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "ENABLE"); return TCL_ERROR; } |
︙ | ︙ | |||
936 937 938 939 940 941 942 943 944 945 946 947 948 949 | if( processDevSymArgs(interp, objc-1, &objv[1], &iDc, &iSectorSize) ){ return TCL_ERROR; } devsym_register(iDc, iSectorSize); return TCL_OK; } /* ** tclcmd: register_jt_vfs ?-default? PARENT-VFS */ static int jtObjCmd( void * clientData, | > > > > > > > > > > > > > > > > > > > > > | 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 | if( processDevSymArgs(interp, objc-1, &objv[1], &iDc, &iSectorSize) ){ return TCL_ERROR; } devsym_register(iDc, iSectorSize); return TCL_OK; } /* ** tclcmd: unregister_devsim */ static int dsUnregisterObjCmd( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ void devsym_unregister(void); if( objc!=1 ){ Tcl_WrongNumArgs(interp, 1, objv, ""); return TCL_ERROR; } devsym_unregister(); return TCL_OK; } /* ** tclcmd: register_jt_vfs ?-default? PARENT-VFS */ static int jtObjCmd( void * clientData, |
︙ | ︙ | |||
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 | ** This procedure registers the TCL procedures defined in this file. */ int Sqlitetest6_Init(Tcl_Interp *interp){ #ifndef SQLITE_OMIT_DISKIO Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0); Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0); #endif return TCL_OK; } #endif /* SQLITE_TEST */ | > | 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 | ** This procedure registers the TCL procedures defined in this file. */ int Sqlitetest6_Init(Tcl_Interp *interp){ #ifndef SQLITE_OMIT_DISKIO Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0); Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "unregister_devsim", dsUnregisterObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0); #endif return TCL_OK; } #endif /* SQLITE_TEST */ |
Changes to src/test_devsym.c.
︙ | ︙ | |||
391 392 393 394 395 396 397 398 399 | } if( iSectorSize>=0 ){ g.iSectorSize = iSectorSize; }else{ g.iSectorSize = 512; } } #endif | > > > > > > > | 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | } if( iSectorSize>=0 ){ g.iSectorSize = iSectorSize; }else{ g.iSectorSize = 512; } } void devsym_unregister(){ sqlite3_vfs_unregister(&devsym_vfs); g.pVfs = 0; g.iDeviceChar = 0; g.iSectorSize = 0; } #endif |
Changes to src/test_journal.c.
︙ | ︙ | |||
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | static void jtDlError(sqlite3_vfs*, int nByte, char *zErrMsg); static void (*jtDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void); static void jtDlClose(sqlite3_vfs*, void*); static int jtRandomness(sqlite3_vfs*, int nByte, char *zOut); static int jtSleep(sqlite3_vfs*, int microseconds); static int jtCurrentTime(sqlite3_vfs*, double*); static int jtCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); static sqlite3_vfs jt_vfs = { 2, /* iVersion */ sizeof(jt_file), /* szOsFile */ JT_MAX_PATHNAME, /* mxPathname */ 0, /* pNext */ JT_VFS_NAME, /* zName */ 0, /* pAppData */ jtOpen, /* xOpen */ jtDelete, /* xDelete */ jtAccess, /* xAccess */ jtFullPathname, /* xFullPathname */ jtDlOpen, /* xDlOpen */ jtDlError, /* xDlError */ jtDlSym, /* xDlSym */ jtDlClose, /* xDlClose */ jtRandomness, /* xRandomness */ jtSleep, /* xSleep */ jtCurrentTime, /* xCurrentTime */ | > | | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | static void jtDlError(sqlite3_vfs*, int nByte, char *zErrMsg); static void (*jtDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void); static void jtDlClose(sqlite3_vfs*, void*); static int jtRandomness(sqlite3_vfs*, int nByte, char *zOut); static int jtSleep(sqlite3_vfs*, int microseconds); static int jtCurrentTime(sqlite3_vfs*, double*); static int jtCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); static int jtGetLastError(sqlite3_vfs*, int, char*); static sqlite3_vfs jt_vfs = { 2, /* iVersion */ sizeof(jt_file), /* szOsFile */ JT_MAX_PATHNAME, /* mxPathname */ 0, /* pNext */ JT_VFS_NAME, /* zName */ 0, /* pAppData */ jtOpen, /* xOpen */ jtDelete, /* xDelete */ jtAccess, /* xAccess */ jtFullPathname, /* xFullPathname */ jtDlOpen, /* xDlOpen */ jtDlError, /* xDlError */ jtDlSym, /* xDlSym */ jtDlClose, /* xDlClose */ jtRandomness, /* xRandomness */ jtSleep, /* xSleep */ jtCurrentTime, /* xCurrentTime */ jtGetLastError, /* xGetLastError */ jtCurrentTimeInt64 /* xCurrentTimeInt64 */ }; static sqlite3_io_methods jt_io_methods = { 1, /* iVersion */ jtClose, /* xClose */ jtRead, /* xRead */ |
︙ | ︙ | |||
281 282 283 284 285 286 287 | ** following properties: ** ** a) SQLITE_OPEN_MAIN_DB was specified when the file was opened. ** ** b) The file-name specified when the file was opened matches ** all but the final 8 characters of the journal file name. ** | | > | | | 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | ** following properties: ** ** a) SQLITE_OPEN_MAIN_DB was specified when the file was opened. ** ** b) The file-name specified when the file was opened matches ** all but the final 8 characters of the journal file name. ** ** c) There is currently a reserved lock on the file. This ** condition is waived if the noLock argument is non-zero. **/ static jt_file *locateDatabaseHandle(const char *zJournal, int noLock){ jt_file *pMain = 0; enterJtMutex(); for(pMain=g.pList; pMain; pMain=pMain->pNext){ int nName = (int)(strlen(zJournal) - strlen("-journal")); if( (pMain->flags&SQLITE_OPEN_MAIN_DB) && ((int)strlen(pMain->zName)==nName) && 0==memcmp(pMain->zName, zJournal, nName) && ((pMain->eLock>=SQLITE_LOCK_RESERVED) || noLock) ){ break; } } leaveJtMutex(); return pMain; } |
︙ | ︙ | |||
513 514 515 516 517 518 519 | int iAmt, sqlite_int64 iOfst ){ int rc; jt_file *p = (jt_file *)pFile; if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){ if( iOfst==0 ){ | | | 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | int iAmt, sqlite_int64 iOfst ){ int rc; jt_file *p = (jt_file *)pFile; if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){ if( iOfst==0 ){ jt_file *pMain = locateDatabaseHandle(p->zName, 0); assert( pMain ); if( iAmt==28 ){ /* Zeroing the first journal-file header. This is the end of a ** transaction. */ closeTransaction(pMain); }else if( iAmt!=12 ){ |
︙ | ︙ | |||
558 559 560 561 562 563 564 | assert( pgno<=p->nPage || p->nSync>0 ); assert( pgno>p->nPage || sqlite3BitvecTest(p->pWritable, pgno) ); } } rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst); if( (p->flags&SQLITE_OPEN_MAIN_JOURNAL) && iAmt==12 ){ | | | | 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | assert( pgno<=p->nPage || p->nSync>0 ); assert( pgno>p->nPage || sqlite3BitvecTest(p->pWritable, pgno) ); } } rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst); if( (p->flags&SQLITE_OPEN_MAIN_JOURNAL) && iAmt==12 ){ jt_file *pMain = locateDatabaseHandle(p->zName, 0); int rc2 = readJournalFile(p, pMain); if( rc==SQLITE_OK ) rc = rc2; } return rc; } /* ** Truncate an jt-file. */ static int jtTruncate(sqlite3_file *pFile, sqlite_int64 size){ jt_file *p = (jt_file *)pFile; if( p->flags&SQLITE_OPEN_MAIN_JOURNAL && size==0 ){ /* Truncating a journal file. This is the end of a transaction. */ jt_file *pMain = locateDatabaseHandle(p->zName, 0); closeTransaction(pMain); } if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){ u32 pgno; u32 locking_page = (u32)(PENDING_BYTE/p->nPagesize+1); for(pgno=(u32)(size/p->nPagesize+1); pgno<=p->nPage; pgno++){ assert( pgno==locking_page || sqlite3BitvecTest(p->pWritable, pgno) ); |
︙ | ︙ | |||
600 601 602 603 604 605 606 | jt_file *pMain; /* The associated database file */ /* The journal file is being synced. At this point, we inspect the ** contents of the file up to this point and set each bit in the ** jt_file.pWritable bitvec of the main database file associated with ** this journal file. */ | | < | | 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 | jt_file *pMain; /* The associated database file */ /* The journal file is being synced. At this point, we inspect the ** contents of the file up to this point and set each bit in the ** jt_file.pWritable bitvec of the main database file associated with ** this journal file. */ pMain = locateDatabaseHandle(p->zName, 0); /* Set the bitvec values */ if( pMain && pMain->pWritable ){ pMain->nSync++; rc = readJournalFile(p, pMain); if( rc!=SQLITE_OK ){ return rc; } } } |
︙ | ︙ | |||
726 727 728 729 730 731 732 | ** ensure the file-system modifications are synced to disk before ** returning. */ static int jtDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ int nPath = (int)strlen(zPath); if( nPath>8 && 0==strcmp("-journal", &zPath[nPath-8]) ){ /* Deleting a journal file. The end of a transaction. */ | | | 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 | ** ensure the file-system modifications are synced to disk before ** returning. */ static int jtDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ int nPath = (int)strlen(zPath); if( nPath>8 && 0==strcmp("-journal", &zPath[nPath-8]) ){ /* Deleting a journal file. The end of a transaction. */ jt_file *pMain = locateDatabaseHandle(zPath, 0); if( pMain ){ closeTransaction(pMain); } } return sqlite3OsDelete(g.pVfs, zPath, dirSync); } |
︙ | ︙ | |||
820 821 822 823 824 825 826 827 828 829 830 831 832 833 | } /* ** Return the current time as a Julian Day number in *pTimeOut. */ static int jtCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ return g.pVfs->xCurrentTimeInt64(g.pVfs, pTimeOut); } /************************************************************************** ** Start of public API. */ /* ** Configure the jt VFS as a wrapper around the VFS named by parameter | > > > > | 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 | } /* ** Return the current time as a Julian Day number in *pTimeOut. */ static int jtCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ return g.pVfs->xCurrentTimeInt64(g.pVfs, pTimeOut); } static int jtGetLastError(sqlite3_vfs *pVfs, int n, char *z){ return g.pVfs->xGetLastError(g.pVfs, n, z); } /************************************************************************** ** Start of public API. */ /* ** Configure the jt VFS as a wrapper around the VFS named by parameter |
︙ | ︙ |
Changes to src/test_syscall.c.
︙ | ︙ | |||
718 719 720 721 722 723 724 725 726 727 728 729 | { "list", test_syscall_list }, { "defaultvfs", test_syscall_defaultvfs }, { "pagesize", test_syscall_pagesize }, { 0, 0 } }; int iCmd; int rc; if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ..."); return TCL_ERROR; } | > > > > > | | | > | 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 | { "list", test_syscall_list }, { "defaultvfs", test_syscall_defaultvfs }, { "pagesize", test_syscall_pagesize }, { 0, 0 } }; int iCmd; int rc; sqlite3_vfs *pVfs = sqlite3_vfs_find(0); if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ..."); return TCL_ERROR; } if( pVfs->iVersion<3 || pVfs->xSetSystemCall==0 ){ Tcl_AppendResult(interp, "VFS does not support xSetSystemCall", 0); rc = TCL_ERROR; }else{ rc = Tcl_GetIndexFromObjStruct(interp, objv[1], aCmd, sizeof(aCmd[0]), "sub-command", 0, &iCmd ); } if( rc!=TCL_OK ) return rc; return aCmd[iCmd].xCmd(clientData, interp, objc, objv); } int SqlitetestSyscall_Init(Tcl_Interp *interp){ struct SyscallCmd { const char *zName; |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
351 352 353 354 355 356 357 | i64 s = 0; /* significand */ int d = 0; /* adjust exponent for shifting decimal point */ int esign = 1; /* sign of exponent */ int e = 0; /* exponent */ int eValid = 1; /* True exponent is either not used or is well-formed */ double result; int nDigits = 0; | | | < < < | > | > > | < < > > > > | > < | < < | | < | | > > > > > > | | > | > > > | | | | | > | | | | | | | | | | | | | > < < | | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 | i64 s = 0; /* significand */ int d = 0; /* adjust exponent for shifting decimal point */ int esign = 1; /* sign of exponent */ int e = 0; /* exponent */ int eValid = 1; /* True exponent is either not used or is well-formed */ double result; int nDigits = 0; int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ if( enc==SQLITE_UTF8 ){ incr = 1; }else{ int i; incr = 2; assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); for(i=3-enc; i<length && z[i]==0; i+=2){} nonNum = i<length; zEnd = &z[i^1]; z += (enc&1); } /* skip leading spaces */ while( z<zEnd && sqlite3Isspace(*z) ) z+=incr; if( z>=zEnd ) return 0; /* get sign of significand */ if( *z=='-' ){ sign = -1; z+=incr; }else if( *z=='+' ){ z+=incr; } /* copy max significant digits to significand */ while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ s = s*10 + (*z - '0'); z+=incr, nDigits++; } /* skip non-significant significand digits ** (increase exponent by d to shift decimal left) */ while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++; if( z>=zEnd ) goto do_atof_calc; /* if decimal point is present */ if( *z=='.' ){ z+=incr; /* copy digits from after decimal to significand ** (decrease exponent by d to shift decimal right) */ while( z<zEnd && sqlite3Isdigit(*z) ){ if( s<((LARGEST_INT64-9)/10) ){ s = s*10 + (*z - '0'); d--; } z+=incr, nDigits++; } } if( z>=zEnd ) goto do_atof_calc; /* if exponent is present */ if( *z=='e' || *z=='E' ){ z+=incr; eValid = 0; /* This branch is needed to avoid a (harmless) buffer overread. The ** special comment alerts the mutation tester that the correct answer ** is obtained even if the branch is omitted */ if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/ /* get sign of exponent */ if( *z=='-' ){ esign = -1; z+=incr; }else if( *z=='+' ){ z+=incr; } /* copy digits to exponent */ while( z<zEnd && sqlite3Isdigit(*z) ){ e = e<10000 ? (e*10 + (*z - '0')) : 10000; z+=incr; eValid = 1; } } /* skip trailing spaces */ while( z<zEnd && sqlite3Isspace(*z) ) z+=incr; do_atof_calc: /* adjust exponent by d, and update sign */ e = (e*esign) + d; if( e<0 ) { esign = -1; e *= -1; } else { esign = 1; } if( s==0 ) { /* In the IEEE 754 standard, zero is signed. */ result = sign<0 ? -(double)0 : (double)0; } else { /* Attempt to reduce exponent. ** ** Branches that are not required for the correct answer but which only ** help to obtain the correct answer faster are marked with special ** comments, as a hint to the mutation tester. */ while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/ if( esign>0 ){ if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/ s *= 10; }else{ if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/ s /= 10; } e--; } /* adjust the sign of significand */ s = sign<0 ? -s : s; if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/ result = (double)s; }else{ LONGDOUBLE_TYPE scale = 1.0; /* attempt to handle extremely small/large numbers better */ if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/ if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/ while( e%308 ) { scale *= 1.0e+1; e -= 1; } if( esign<0 ){ result = s / scale; result /= 1.0e+308; }else{ result = s * scale; result *= 1.0e+308; } }else{ assert( e>=342 ); if( esign<0 ){ result = 0.0*s; }else{ result = 1e308*1e308*s; /* Infinity */ } } }else{ /* 1.0e+22 is the largest power of 10 than can be ** represented exactly. */ while( e%22 ) { scale *= 1.0e+1; e -= 1; } while( e>0 ) { scale *= 1.0e+22; e -= 22; } if( esign<0 ){ result = s / scale; }else{ result = s * scale; } } } } /* store the result */ *pResult = result; /* return true if number and no extra non-whitespace chracters after */ return z==zEnd && nDigits>0 && eValid && nonNum==0; #else return !sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ } /* ** Compare the 19-character string zNum against the text representation |
︙ | ︙ | |||
561 562 563 564 565 566 567 | */ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ int incr; u64 u = 0; int neg = 0; /* assume positive */ int i; int c = 0; | | | | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | */ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ int incr; u64 u = 0; int neg = 0; /* assume positive */ int i; int c = 0; int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ const char *zStart; const char *zEnd = zNum + length; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); if( enc==SQLITE_UTF8 ){ incr = 1; }else{ incr = 2; assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); for(i=3-enc; i<length && zNum[i]==0; i+=2){} nonNum = i<length; zEnd = &zNum[i^1]; zNum += (enc&1); } while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr; if( zNum<zEnd ){ if( *zNum=='-' ){ neg = 1; zNum+=incr; |
︙ | ︙ | |||
599 600 601 602 603 604 605 | *pNum = -(i64)u; }else{ *pNum = (i64)u; } testcase( i==18 ); testcase( i==19 ); testcase( i==20 ); | > | | > > | 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 | *pNum = -(i64)u; }else{ *pNum = (i64)u; } testcase( i==18 ); testcase( i==19 ); testcase( i==20 ); if( &zNum[i]<zEnd /* Extra bytes at the end */ || (i==0 && zStart==zNum) /* No digits */ || i>19*incr /* Too many digits */ || nonNum /* UTF16 with high-order bytes non-zero */ ){ /* zNum is empty or contains non-numeric text or is longer ** than 19 digits (thus guaranteeing that it is too large) */ return 1; }else if( i<19*incr ){ /* Less than 19 digits, so we know that it fits in 64 bits */ assert( u<=LARGEST_INT64 ); return 0; |
︙ | ︙ | |||
642 643 644 645 646 647 648 | ** 1 Integer too large for a 64-bit signed integer or is malformed ** 2 Special case of 9223372036854775808 */ int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ #ifndef SQLITE_OMIT_HEX_INTEGER if( z[0]=='0' && (z[1]=='x' || z[1]=='X') | < | 654 655 656 657 658 659 660 661 662 663 664 665 666 667 | ** 1 Integer too large for a 64-bit signed integer or is malformed ** 2 Special case of 9223372036854775808 */ int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ #ifndef SQLITE_OMIT_HEX_INTEGER if( z[0]=='0' && (z[1]=='x' || z[1]=='X') ){ u64 u = 0; int i, k; for(i=2; z[i]=='0'; i++){} for(k=i; sqlite3Isxdigit(z[k]); k++){ u = u*16 + sqlite3HexToInt(z[k]); } |
︙ | ︙ | |||
1404 1405 1406 1407 1408 1409 1410 | LogEst sqlite3LogEst(u64 x){ static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; LogEst y = 40; if( x<8 ){ if( x<2 ) return 0; while( x<8 ){ y -= 10; x <<= 1; } }else{ | | | 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 | LogEst sqlite3LogEst(u64 x){ static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; LogEst y = 40; if( x<8 ){ if( x<2 ) return 0; while( x<8 ){ y -= 10; x <<= 1; } }else{ while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/ while( x>15 ){ y += 10; x >>= 1; } } return a[x&7] + y - 10; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
211 212 213 214 215 216 217 | int nByte; VdbeCursor *pCx = 0; nByte = ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); assert( iCur>=0 && iCur<p->nCursor ); | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | int nByte; VdbeCursor *pCx = 0; nByte = ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); assert( iCur>=0 && iCur<p->nCursor ); if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; memset(pCx, 0, sizeof(VdbeCursor)); pCx->eCurType = eCurType; |
︙ | ︙ | |||
288 289 290 291 292 293 294 | Mem *pRec, /* The value to apply affinity to */ char affinity, /* The affinity to be applied */ u8 enc /* Use this text encoding */ ){ if( affinity>=SQLITE_AFF_NUMERIC ){ assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL || affinity==SQLITE_AFF_NUMERIC ); | | | > | | > | > | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | Mem *pRec, /* The value to apply affinity to */ char affinity, /* The affinity to be applied */ u8 enc /* Use this text encoding */ ){ if( affinity>=SQLITE_AFF_NUMERIC ){ assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL || affinity==SQLITE_AFF_NUMERIC ); if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/ if( (pRec->flags & MEM_Real)==0 ){ if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); }else{ sqlite3VdbeIntegerAffinity(pRec); } } }else if( affinity==SQLITE_AFF_TEXT ){ /* Only attempt the conversion to TEXT if there is an integer or real ** representation (blob and NULL do not get converted) but no string ** representation. It would be harmless to repeat the conversion if ** there is already a string rep, but it is pointless to waste those ** CPU cycles. */ if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/ if( (pRec->flags&(MEM_Real|MEM_Int)) ){ sqlite3VdbeMemStringify(pRec, enc, 1); } } pRec->flags &= ~(MEM_Real|MEM_Int); } } /* ** Try to convert the type of a function argument or a result column |
︙ | ︙ | |||
538 539 540 541 542 543 544 | } static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ Mem *pOut; assert( pOp->p2>0 ); assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); pOut = &p->aMem[pOp->p2]; memAboutToChange(p, pOut); | | | 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 | } static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ Mem *pOut; assert( pOp->p2>0 ); assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); pOut = &p->aMem[pOp->p2]; memAboutToChange(p, pOut); if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/ return out2PrereleaseWithClear(pOut); }else{ pOut->flags = MEM_Int; return pOut; } } |
︙ | ︙ |
Changes to test/dbstatus2.test.
︙ | ︙ | |||
82 83 84 85 86 87 88 | execsql { INSERT INTO t1 VALUES(4, randomblob(600)) } db_write db } {0 4 0} do_test 2.3 { db_write db 1 } {0 4 0} do_test 2.4 { db_write db 0 } {0 0 0} do_test 2.5 { db_write db 1 } {0 0 0} | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | execsql { INSERT INTO t1 VALUES(4, randomblob(600)) } db_write db } {0 4 0} do_test 2.3 { db_write db 1 } {0 4 0} do_test 2.4 { db_write db 0 } {0 0 0} do_test 2.5 { db_write db 1 } {0 0 0} if {[wal_is_capable]} { do_test 2.6 { execsql { PRAGMA journal_mode = WAL } db_write db 1 } {0 1 0} } do_test 2.7 { execsql { INSERT INTO t1 VALUES(5, randomblob(600)) } |
︙ | ︙ |
Changes to test/e_vacuum.test.
︙ | ︙ | |||
172 173 174 175 176 177 178 | execsql VACUUM execsql { PRAGMA page_size ; PRAGMA auto_vacuum } } {2048 0} # EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the # auto_vacuum support property can be changed using VACUUM. # | | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | execsql VACUUM execsql { PRAGMA page_size ; PRAGMA auto_vacuum } } {2048 0} # EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the # auto_vacuum support property can be changed using VACUUM. # if {[wal_is_capable]} { do_test e_vacuum-1.3.3.1 { execsql { PRAGMA journal_mode = wal } execsql { PRAGMA page_size ; PRAGMA auto_vacuum } } {2048 0} do_test e_vacuum-1.3.3.2 { execsql { PRAGMA page_size = 1024 } execsql { PRAGMA auto_vacuum = FULL } |
︙ | ︙ |
Changes to test/exists.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl foreach jm {rollback wal} { set testprefix exists-$jm # This block of tests is targeted at CREATE XXX IF NOT EXISTS statements. # do_multiclient_test tn { | > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl foreach jm {rollback wal} { if {![wal_is_capable] && $jm=="wal"} continue set testprefix exists-$jm # This block of tests is targeted at CREATE XXX IF NOT EXISTS statements. # do_multiclient_test tn { |
︙ | ︙ |
Changes to test/hook.test.
︙ | ︙ | |||
700 701 702 703 704 705 706 | do_execsql_test 7.5.2.0 { CREATE TABLE t8(a, b); INSERT INTO t8 VALUES('one', 'two'); INSERT INTO t8 VALUES('three', 'four'); ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx'; } | | | 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 | do_execsql_test 7.5.2.0 { CREATE TABLE t8(a, b); INSERT INTO t8 VALUES('one', 'two'); INSERT INTO t8 VALUES('three', 'four'); ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx'; } if 0 { # At time of writing, these two are broken. They demonstrate that the # sqlite3_preupdate_old() method does not handle the case where ALTER TABLE # has been used to add a column with a default value other than NULL. # do_preupdate_test 7.5.2.1 { DELETE FROM t8 WHERE a = 'one' } { |
︙ | ︙ |
Changes to test/incrvacuum2.test.
︙ | ︙ | |||
130 131 132 133 134 135 136 | PRAGMA incremental_vacuum; COMMIT; } } {} integrity_check incrvacuum2-3.3 | | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | PRAGMA incremental_vacuum; COMMIT; } } {} integrity_check incrvacuum2-3.3 if {[wal_is_capable]} { # At one point, when a specific page was being extracted from the b-tree # free-list (e.g. during an incremental-vacuum), all trunk pages that # occurred before the specific page in the free-list trunk were being # written to the journal or wal file. This is not necessary. Only the # extracted page and the page that contains the pointer to it need to # be journalled. # |
︙ | ︙ |
Changes to test/journal2.test.
︙ | ︙ | |||
200 201 202 203 204 205 206 | #------------------------------------------------------------------------- # Test that it is possible to switch from journal_mode=truncate to # journal_mode=WAL on a SAFE_DELETE file-system. SQLite should close and # delete the journal file when committing the transaction that switches # the system to WAL mode. # | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | #------------------------------------------------------------------------- # Test that it is possible to switch from journal_mode=truncate to # journal_mode=WAL on a SAFE_DELETE file-system. SQLite should close and # delete the journal file when committing the transaction that switches # the system to WAL mode. # if {[wal_is_capable]} { do_test journal2-2.1 { faultsim_delete_and_reopen set ::oplog [list] execsql { PRAGMA journal_mode = persist } set ::oplog } {} do_test journal2-2.2 { |
︙ | ︙ |
Changes to test/permutations.test.
︙ | ︙ | |||
724 725 726 727 728 729 730 | pragma journal_mode = 'memory' } -files [test_set $::allquicktests -exclude { # Exclude all tests that simulate IO errors. autovacuum_ioerr2.test cffault.test incrvacuum_ioerr.test ioerr.test ioerr.test ioerr2.test ioerr3.test ioerr4.test ioerr5.test vacuum3.test incrblob_err.test diskfull.test backup_ioerr.test e_fts3.test fts3cov.test fts3malloc.test fts3rnd.test | | | 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 | pragma journal_mode = 'memory' } -files [test_set $::allquicktests -exclude { # Exclude all tests that simulate IO errors. autovacuum_ioerr2.test cffault.test incrvacuum_ioerr.test ioerr.test ioerr.test ioerr2.test ioerr3.test ioerr4.test ioerr5.test vacuum3.test incrblob_err.test diskfull.test backup_ioerr.test e_fts3.test fts3cov.test fts3malloc.test fts3rnd.test fts3snippet.test mmapfault.test sessionfault.test sessionfault2.test # Exclude test scripts that use tcl IO to access journal files or count # the number of fsync() calls. pager.test exclusive.test jrnlmode.test sync.test misc1.test journal1.test conflict.test crash8.test tkt3457.test io.test journal3.test 8_3_names.test |
︙ | ︙ | |||
938 939 940 941 942 943 944 | } -initialize { catch {db close} register_jt_vfs -default "" } -shutdown { unregister_jt_vfs } -files [test_set $::allquicktests -exclude { wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test | | > > | 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 | } -initialize { catch {db close} register_jt_vfs -default "" } -shutdown { unregister_jt_vfs } -files [test_set $::allquicktests -exclude { wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test async4.test bigfile.test backcompat.test e_wal* fstat.test mmap2.test pager1.test syscall.test tkt3457.test *malloc* mmap* multiplex* nolock* pager2.test *fault* rowal* snapshot* superlock* symlink.test }] if {[info commands register_demovfs] != ""} { test_suite "demovfs" -description { Check that the demovfs (code in test_demovfs.c) more or less works. } -initialize { register_demovfs |
︙ | ︙ | |||
1046 1047 1048 1049 1050 1051 1052 | set ::G(perm:name) $name set ::G(perm:prefix) $options(-prefix) set ::G(perm:presql) $options(-presql) set ::G(isquick) 1 set ::G(perm:dbconfig) $options(-dbconfig) | < < > < < | | > | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 | set ::G(perm:name) $name set ::G(perm:prefix) $options(-prefix) set ::G(perm:presql) $options(-presql) set ::G(isquick) 1 set ::G(perm:dbconfig) $options(-dbconfig) foreach file [lsort $options(-files)] { uplevel $options(-initialize) if {[file tail $file] == $file} { set file [file join $::testdir $file] } slave_test_file $file uplevel $options(-shutdown) } unset ::G(perm:name) unset ::G(perm:prefix) unset ::G(perm:presql) unset ::G(perm:dbconfig) } proc run_test_suite {name} { |
︙ | ︙ |
Changes to test/pragma3.test.
︙ | ︙ | |||
217 218 219 220 221 222 223 | } # Make sure this also works in WAL mode # # This will not work with the in-memory journal permutation, as opening # [db2] switches the journal mode back to "memory" # | | | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | } # Make sure this also works in WAL mode # # This will not work with the in-memory journal permutation, as opening # [db2] switches the journal mode back to "memory" # if {[wal_is_capable]} { if {[permutation]!="inmemory_journal"} { sqlite3 db test.db db eval {PRAGMA journal_mode=WAL} sqlite3 db2 test.db do_test pragma3-400 { db eval { |
︙ | ︙ |
Changes to test/quota.test.
︙ | ︙ | |||
523 524 525 526 527 528 529 530 | catch { sqlite3_quota_shutdown } sqlite3_quota_initialize "" 1 } -body { sqlite3_quota_set * 4096 {} } catch { sqlite3_quota_shutdown } finish_test | > > | 523 524 525 526 527 528 529 530 531 532 | catch { sqlite3_quota_shutdown } sqlite3_quota_initialize "" 1 } -body { sqlite3_quota_set * 4096 {} } catch { sqlite3_quota_shutdown } catch { db close } forcedelete test.db finish_test |
Changes to test/stat.test.
︙ | ︙ | |||
33 34 35 36 37 38 39 | register_dbstat_vtab db do_execsql_test stat-0.0 { PRAGMA auto_vacuum = OFF; CREATE VIRTUAL TABLE temp.stat USING dbstat; SELECT * FROM stat; } {} | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | register_dbstat_vtab db do_execsql_test stat-0.0 { PRAGMA auto_vacuum = OFF; CREATE VIRTUAL TABLE temp.stat USING dbstat; SELECT * FROM stat; } {} if {[wal_is_capable]} { do_execsql_test stat-0.1 { PRAGMA journal_mode = WAL; PRAGMA journal_mode = delete; SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload FROM stat; } {wal delete sqlite_master / 1 leaf 0 0 916 0} } |
︙ | ︙ |
Changes to test/sync.test.
︙ | ︙ | |||
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | INSERT INTO t2 VALUES(5,6); COMMIT; } cond_incr_sync_count 4 set sqlite_sync_count } 11 ifcapable pager_pragmas { do_test sync-1.4 { set sqlite_sync_count 0 execsql { PRAGMA main.synchronous=off; PRAGMA db2.synchronous=off; BEGIN; INSERT INTO t1 VALUES(5,6); INSERT INTO t2 VALUES(7,8); COMMIT; } set sqlite_sync_count } 0 } finish_test | > > | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | INSERT INTO t2 VALUES(5,6); COMMIT; } cond_incr_sync_count 4 set sqlite_sync_count } 11 ifcapable pager_pragmas { if {[permutation]!="journaltest"} { do_test sync-1.4 { set sqlite_sync_count 0 execsql { PRAGMA main.synchronous=off; PRAGMA db2.synchronous=off; BEGIN; INSERT INTO t1 VALUES(5,6); INSERT INTO t2 VALUES(7,8); COMMIT; } set sqlite_sync_count } 0 } } finish_test |
Changes to test/tester.tcl.
︙ | ︙ | |||
1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 | } proc wal_check_journal_mode {testname {db db}} { if { [wal_is_wal_mode] } { $db eval { SELECT * FROM sqlite_master } do_test $testname [list $db eval "PRAGMA main.journal_mode"] {wal} } } proc permutation {} { set perm "" catch {set perm $::G(perm:name)} set perm } proc presql {} { | > > > > > > | 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 | } proc wal_check_journal_mode {testname {db db}} { if { [wal_is_wal_mode] } { $db eval { SELECT * FROM sqlite_master } do_test $testname [list $db eval "PRAGMA main.journal_mode"] {wal} } } proc wal_is_capable {} { ifcapable !wal { return 0 } if {[permutation]=="journaltest"} { return 0 } return 1 } proc permutation {} { set perm "" catch {set perm $::G(perm:name)} set perm } proc presql {} { |
︙ | ︙ |
Changes to test/tkt-2d1a5c67d.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 | # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix tkt-2d1a5c67d | | > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix tkt-2d1a5c67d ifcapable {!vtab} {finish_test; return} if {[wal_is_capable]==0} {finish_test; return} for {set ii 1} {$ii<=10} {incr ii} { do_test tkt-2d1a5c67d.1.$ii { db close forcedelete test.db test.db-wal sqlite3 db test.db db eval "PRAGMA cache_size=$::ii" |
︙ | ︙ |
Changes to test/tkt-313723c356.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 | # fixed. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # fixed. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl if {![wal_is_capable]} { finish_test ; return } do_execsql_test tkt-313723c356.1 { PRAGMA page_size = 1024; PRAGMA journal_mode = WAL; CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a, b); INSERT INTO t1 VALUES(randomblob(400), randomblob(400)); |
︙ | ︙ |
Changes to test/tkt-5d863f876e.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 | # fixed. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl set ::testprefix tkt-5d863f876e | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # fixed. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl set ::testprefix tkt-5d863f876e if {![wal_is_capable]} {finish_test ; return } do_multiclient_test tn { do_test $tn.1 { sql1 { CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a, b); INSERT INTO t1 VALUES(1, 2); |
︙ | ︙ |
Changes to test/tkt-9d68c883.test.
︙ | ︙ | |||
46 47 48 49 50 51 52 53 | sqlite3_memdebug_fail -1 catchsql { ROLLBACK } execsql { PRAGMA integrity_check } } {ok} } finish_test | > > | 46 47 48 49 50 51 52 53 54 55 | sqlite3_memdebug_fail -1 catchsql { ROLLBACK } execsql { PRAGMA integrity_check } } {ok} } catch { db close } unregister_devsim finish_test |
Changes to test/zerodamage.test.
︙ | ︙ | |||
85 86 87 88 89 90 91 | sqlite3 db file:test.db?psow=FALSE -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; } concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] } {0 0 24704} | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | sqlite3 db file:test.db?psow=FALSE -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; } concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size] } {0 0 24704} if {[wal_is_capable]} { # Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the # WAL file does not get too big. # do_test zerodamage-3.0 { db eval { PRAGMA journal_mode=WAL; } |
︙ | ︙ |
Changes to tool/lemon.c.
︙ | ︙ | |||
4398 4399 4400 4401 4402 4403 4404 | struct rule *rp2; /* Other rules with the same action */ if( rp->code==0 ) continue; if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */ fprintf(out," case %d: /* ", rp->iRule); writeRuleText(out, rp); fprintf(out, " */\n"); lineno++; for(rp2=rp->next; rp2; rp2=rp2->next){ | | > | 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 | struct rule *rp2; /* Other rules with the same action */ if( rp->code==0 ) continue; if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */ fprintf(out," case %d: /* ", rp->iRule); writeRuleText(out, rp); fprintf(out, " */\n"); lineno++; for(rp2=rp->next; rp2; rp2=rp2->next){ if( rp2->code==rp->code && rp2->codePrefix==rp->codePrefix && rp2->codeSuffix==rp->codeSuffix ){ fprintf(out," case %d: /* ", rp2->iRule); writeRuleText(out, rp2); fprintf(out," */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++; rp2->code = 0; } } emit_code(out,rp,lemp,&lineno); |
︙ | ︙ |