Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge 3.12.0 changes. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | begin-concurrent |
Files: | files | file ages | folders |
SHA1: |
d7381efff47c0a2f307478f196d03df7 |
User & Date: | drh 2016-03-29 10:36:07.964 |
Context
2016-04-20
| ||
12:16 | Merge all recent enhancements from trunk. (check-in: 1f709fbf93 user: drh tags: begin-concurrent) | |
2016-03-29
| ||
10:36 | Merge 3.12.0 changes. (check-in: d7381efff4 user: drh tags: begin-concurrent) | |
10:14 | Version 3.12.0 (check-in: e9bb4cf40f user: drh tags: trunk, release, version-3.12.0) | |
2016-03-21
| ||
15:54 | Merge all recent changes from trunk. (check-in: 8ee7d346c1 user: drh tags: begin-concurrent) | |
Changes
Changes to ext/fts5/fts5Int.h.
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 | ** Constants for the largest and smallest possible 64-bit signed integers. */ # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) #endif /* ** Maximum number of prefix indexes on single FTS5 table. This must be ** less than 32. If it is set to anything large than that, an #error ** directive in fts5_index.c will cause the build to fail. */ #define FTS5_MAX_PREFIX_INDEXES 31 | > > > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | ** Constants for the largest and smallest possible 64-bit signed integers. */ # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) #endif /* Truncate very long tokens to this many bytes. Hard limit is ** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset ** field that occurs at the start of each leaf page (see fts5_index.c). */ #define FTS5_MAX_TOKEN_SIZE 32768 /* ** Maximum number of prefix indexes on single FTS5 table. This must be ** less than 32. If it is set to anything large than that, an #error ** directive in fts5_index.c will cause the build to fail. */ #define FTS5_MAX_PREFIX_INDEXES 31 |
︙ | ︙ |
Changes to ext/fts5/fts5_expr.c.
︙ | ︙ | |||
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 | TokenCtx *pCtx = (TokenCtx*)pContext; Fts5ExprPhrase *pPhrase = pCtx->pPhrase; UNUSED_PARAM2(iUnused1, iUnused2); /* If an error has already occurred, this is a no-op */ if( pCtx->rc!=SQLITE_OK ) return pCtx->rc; if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){ Fts5ExprTerm *pSyn; int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1; pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte); if( pSyn==0 ){ rc = SQLITE_NOMEM; | > | 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 | TokenCtx *pCtx = (TokenCtx*)pContext; Fts5ExprPhrase *pPhrase = pCtx->pPhrase; UNUSED_PARAM2(iUnused1, iUnused2); /* If an error has already occurred, this is a no-op */ if( pCtx->rc!=SQLITE_OK ) return pCtx->rc; if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){ Fts5ExprTerm *pSyn; int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1; pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte); if( pSyn==0 ){ rc = SQLITE_NOMEM; |
︙ | ︙ | |||
2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 | ){ Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx; Fts5Expr *pExpr = p->pExpr; int i; UNUSED_PARAM2(iUnused1, iUnused2); if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++; for(i=0; i<pExpr->nPhrase; i++){ Fts5ExprTerm *pTerm; if( p->aPopulator[i].bOk==0 ) continue; for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ int nTerm = (int)strlen(pTerm->zTerm); if( (nTerm==nToken || (nTerm<nToken && pTerm->bPrefix)) | > | 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 | ){ Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx; Fts5Expr *pExpr = p->pExpr; int i; UNUSED_PARAM2(iUnused1, iUnused2); if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++; for(i=0; i<pExpr->nPhrase; i++){ Fts5ExprTerm *pTerm; if( p->aPopulator[i].bOk==0 ) continue; for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ int nTerm = (int)strlen(pTerm->zTerm); if( (nTerm==nToken || (nTerm<nToken && pTerm->bPrefix)) |
︙ | ︙ |
Changes to ext/fts5/fts5_index.c.
︙ | ︙ | |||
1023 1024 1025 1026 1027 1028 1029 | if( p->pStruct==0 ){ p->iStructVersion = fts5IndexDataVersion(p); if( p->rc==SQLITE_OK ){ p->pStruct = fts5StructureReadUncached(p); } } | | | 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 | if( p->pStruct==0 ){ p->iStructVersion = fts5IndexDataVersion(p); if( p->rc==SQLITE_OK ){ p->pStruct = fts5StructureReadUncached(p); } } #if 0 else{ Fts5Structure *pTest = fts5StructureReadUncached(p); if( pTest ){ int i, j; assert_nc( p->pStruct->nSegment==pTest->nSegment ); assert_nc( p->pStruct->nLevel==pTest->nLevel ); for(i=0; i<pTest->nLevel; i++){ |
︙ | ︙ | |||
2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 | pIter->iEndofDoclist = iTermOff + nExtra; } pIter->iPgidxOff = iPgidx; fts5SegIterLoadRowid(p, pIter); fts5SegIterLoadNPos(p, pIter); } /* ** Initialize the object pIter to point to term pTerm/nTerm within segment ** pSeg. If there is no such term in the index, the iterator is set to EOF. ** ** If an error occurs, Fts5Index.rc is set to an appropriate error code. If ** an error has already occurred when this function is called, it is a no-op. */ static void fts5SegIterSeekInit( Fts5Index *p, /* FTS5 backend */ const u8 *pTerm, int nTerm, /* Term to seek to */ int flags, /* Mask of FTS5INDEX_XXX flags */ Fts5StructureSegment *pSeg, /* Description of segment */ Fts5SegIter *pIter /* Object to populate */ ){ int iPg = 1; int bGe = (flags & FTS5INDEX_QUERY_SCAN); int bDlidx = 0; /* True if there is a doclist-index */ assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 ); assert( pTerm && nTerm ); memset(pIter, 0, sizeof(*pIter)); pIter->pSeg = pSeg; /* This block sets stack variable iPg to the leaf page number that may ** contain term (pTerm/nTerm), if it is present in the segment. */ | > > > > > > > > > > > > > | < < < < < < < | | | | | | 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 | pIter->iEndofDoclist = iTermOff + nExtra; } pIter->iPgidxOff = iPgidx; fts5SegIterLoadRowid(p, pIter); fts5SegIterLoadNPos(p, pIter); } static sqlite3_stmt *fts5IdxSelectStmt(Fts5Index *p){ if( p->pIdxSelect==0 ){ Fts5Config *pConfig = p->pConfig; fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf( "SELECT pgno FROM '%q'.'%q_idx' WHERE " "segid=? AND term<=? ORDER BY term DESC LIMIT 1", pConfig->zDb, pConfig->zName )); } return p->pIdxSelect; } /* ** Initialize the object pIter to point to term pTerm/nTerm within segment ** pSeg. If there is no such term in the index, the iterator is set to EOF. ** ** If an error occurs, Fts5Index.rc is set to an appropriate error code. If ** an error has already occurred when this function is called, it is a no-op. */ static void fts5SegIterSeekInit( Fts5Index *p, /* FTS5 backend */ const u8 *pTerm, int nTerm, /* Term to seek to */ int flags, /* Mask of FTS5INDEX_XXX flags */ Fts5StructureSegment *pSeg, /* Description of segment */ Fts5SegIter *pIter /* Object to populate */ ){ int iPg = 1; int bGe = (flags & FTS5INDEX_QUERY_SCAN); int bDlidx = 0; /* True if there is a doclist-index */ sqlite3_stmt *pIdxSelect = 0; assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 ); assert( pTerm && nTerm ); memset(pIter, 0, sizeof(*pIter)); pIter->pSeg = pSeg; /* This block sets stack variable iPg to the leaf page number that may ** contain term (pTerm/nTerm), if it is present in the segment. */ pIdxSelect = fts5IdxSelectStmt(p); if( p->rc ) return; sqlite3_bind_int(pIdxSelect, 1, pSeg->iSegid); sqlite3_bind_blob(pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC); if( SQLITE_ROW==sqlite3_step(pIdxSelect) ){ i64 val = sqlite3_column_int(pIdxSelect, 0); iPg = (int)(val>>1); bDlidx = (val & 0x0001); } p->rc = sqlite3_reset(pIdxSelect); if( iPg<pSeg->pgnoFirst ){ iPg = pSeg->pgnoFirst; bDlidx = 0; } pIter->iLeafPgno = iPg - 1; |
︙ | ︙ | |||
3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 | #ifdef SQLITE_DEBUG for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ); } } assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT ); #endif } } return iSegid; } | > > > > > > > > > > > | 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 | #ifdef SQLITE_DEBUG for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ); } } assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT ); { sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p); if( p->rc==SQLITE_OK ){ u8 aBlob[2] = {0xff, 0xff}; sqlite3_bind_int(pIdxSelect, 1, iSegid); sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC); assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW ); p->rc = sqlite3_reset(pIdxSelect); } } #endif } } return iSegid; } |
︙ | ︙ | |||
3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 | } } static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){ static const u8 zero[] = { 0x00, 0x00, 0x00, 0x00 }; Fts5PageWriter *pPage = &pWriter->writer; i64 iRowid; assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) ); /* Set the szLeaf header field. */ assert( 0==fts5GetU16(&pPage->buf.p[2]) ); fts5PutU16(&pPage->buf.p[2], (u16)pPage->buf.n); | > > > | 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 | } } static void fts5WriteFlushLeaf(Fts5Index *p, Fts5SegWriter *pWriter){ static const u8 zero[] = { 0x00, 0x00, 0x00, 0x00 }; Fts5PageWriter *pPage = &pWriter->writer; i64 iRowid; static int nCall = 0; nCall++; assert( (pPage->pgidx.n==0)==(pWriter->bFirstTermInPage) ); /* Set the szLeaf header field. */ assert( 0==fts5GetU16(&pPage->buf.p[2]) ); fts5PutU16(&pPage->buf.p[2], (u16)pPage->buf.n); |
︙ | ︙ | |||
4599 4600 4601 4602 4603 4604 4605 | } nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel); pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ Fts5StructureLevel *pLvl; | | | 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 | } nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel); pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ Fts5StructureLevel *pLvl; nByte = nSeg * sizeof(Fts5StructureSegment); pNew->nLevel = pStruct->nLevel+1; pNew->nRef = 1; pNew->nWriteCounter = pStruct->nWriteCounter; pLvl = &pNew->aLevel[pStruct->nLevel]; pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pLvl->aSeg ){ int iLvl, iSeg; |
︙ | ︙ |
Changes to ext/fts5/fts5_storage.c.
︙ | ︙ | |||
365 366 367 368 369 370 371 372 373 374 375 376 377 378 | int nToken, /* Size of token in bytes */ int iUnused1, /* Start offset of token */ int iUnused2 /* End offset of token */ ){ Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext; Fts5Index *pIdx = pCtx->pStorage->pIndex; UNUSED_PARAM2(iUnused1, iUnused2); if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){ pCtx->szCol++; } return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken); } /* | > | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | int nToken, /* Size of token in bytes */ int iUnused1, /* Start offset of token */ int iUnused2 /* End offset of token */ ){ Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext; Fts5Index *pIdx = pCtx->pStorage->pIndex; UNUSED_PARAM2(iUnused1, iUnused2); if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){ pCtx->szCol++; } return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken); } /* |
︙ | ︙ | |||
811 812 813 814 815 816 817 818 819 820 821 822 823 824 | int bPresent; int ii; int rc = SQLITE_OK; int iPos; int iCol; UNUSED_PARAM2(iUnused1, iUnused2); if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){ pCtx->szCol++; } switch( pCtx->pConfig->eDetail ){ case FTS5_DETAIL_FULL: | > | 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 | int bPresent; int ii; int rc = SQLITE_OK; int iPos; int iCol; UNUSED_PARAM2(iUnused1, iUnused2); if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){ pCtx->szCol++; } switch( pCtx->pConfig->eDetail ){ case FTS5_DETAIL_FULL: |
︙ | ︙ |
Changes to ext/fts5/test/fts5aa.test.
︙ | ︙ | |||
428 429 430 431 432 433 434 435 436 | set fd [db incrblob main n1_data block 10] fconfigure $fd -encoding binary -translation binary puts -nonewline $fd "\x44\x45" close $fd } db func funk funk do_catchsql_test 16.2 { SELECT funk(), bm25(n1), funk() FROM n1 WHERE n1 MATCH 'a+b+c+d' | > > > > > > > | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 | set fd [db incrblob main n1_data block 10] fconfigure $fd -encoding binary -translation binary puts -nonewline $fd "\x44\x45" close $fd } db func funk funk # This test case corrupts the structure record within the first invocation # of function funk(). Which used to cause the bm25() function to throw an # exception. But since bm25() can now used the cached structure record, # it never sees the corruption introduced by funk() and so the following # statement no longer fails. # do_catchsql_test 16.2 { SELECT funk(), bm25(n1), funk() FROM n1 WHERE n1 MATCH 'a+b+c+d' } {0 {{} -1e-06 {}}} # {1 {SQL logic error or missing database}} #------------------------------------------------------------------------- # reset_db do_execsql_test 17.1 { CREATE VIRTUAL TABLE b2 USING fts5(x, detail=%DETAIL%); INSERT INTO b2 VALUES('a'); |
︙ | ︙ |
Added ext/fts5/test/fts5determin.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # 2016 March 21 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the FTS5 module. # # Specifically, that the fts5 module is deterministic. At one point, when # segment ids were allocated using sqlite3_randomness(), this was not the # case. # source [file join [file dirname [info script]] fts5_common.tcl] set testprefix fts5aa return_if_no_fts5 proc do_determin_test {tn} { uplevel [list do_execsql_test $tn { SELECT (SELECT md5sum(id, block) FROM t1_data)== (SELECT md5sum(id, block) FROM t2_data), (SELECT md5sum(id, block) FROM t1_data)== (SELECT md5sum(id, block) FROM t3_data) } {1 1} ] } foreach_detail_mode $::testprefix { do_execsql_test 1.0 { CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix="1 2", detail=%DETAIL%); CREATE VIRTUAL TABLE t2 USING fts5(a, b, prefix="1 2", detail=%DETAIL%); CREATE VIRTUAL TABLE t3 USING fts5(a, b, prefix="1 2", detail=%DETAIL%); } do_test 1.1 { foreach t {t1 t2 t3} { execsql [string map [list TBL $t] { INSERT INTO TBL VALUES('a b c', 'd e f'); INSERT INTO TBL VALUES('c1 c2 c3', 'c1 c2 c3'); INSERT INTO TBL VALUES('xyzxyzxyz', 'xyzxyzxyz'); }] } } {} do_determin_test 1.2 do_test 1.3 { foreach t {t1 t2 t3} { execsql [string map [list TBL $t] { INSERT INTO TBL(TBL) VALUES('optimize'); }] } } {} do_determin_test 1.4 } finish_test |
Changes to ext/fts5/test/fts5fault4.test.
︙ | ︙ | |||
82 83 84 85 86 87 88 | } set ::res [db eval {SELECT rowid, x1 FROM x1 WHERE x1 MATCH '*reads'}] do_faultsim_test 4 -faults oom-* -body { db eval {SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'} } -test { | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | } set ::res [db eval {SELECT rowid, x1 FROM x1 WHERE x1 MATCH '*reads'}] do_faultsim_test 4 -faults oom-* -body { db eval {SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'} } -test { faultsim_test_result {0 {0 {} 3}} } #------------------------------------------------------------------------- # An OOM within a query that uses a custom rank function. # reset_db do_execsql_test 5.0 { |
︙ | ︙ |
Changes to ext/fts5/test/fts5simple.test.
︙ | ︙ | |||
336 337 338 339 340 341 342 | } do_test 14.2 { fts5_level_segs ttt } {1} #------------------------------------------------------------------------- db func rnddoc fts5_rnddoc | | | | | 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 | } do_test 14.2 { fts5_level_segs ttt } {1} #------------------------------------------------------------------------- db func rnddoc fts5_rnddoc do_execsql_test 14.3 { CREATE VIRTUAL TABLE x1 USING fts5(x); INSERT INTO x1(x1, rank) VALUES('pgsz', 32); WITH ii(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<10 ) INSERT INTO x1 SELECT rnddoc(5) FROM ii; } do_execsql_test 14.4 { SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads' } {0 {} 3} #------------------------------------------------------------------------- reset_db do_execsql_test 15.0 { CREATE VIRTUAL TABLE x2 USING fts5(x, prefix=1); INSERT INTO x2 VALUES('ab'); } |
︙ | ︙ | |||
443 444 445 446 447 448 449 450 451 | execsql { INSERT INTO x1(x1) VALUES('optimize'); } execsql { DELETE FROM x1 WHERE rowid = 4; } } {} do_execsql_test 20.2 { INSERT INTO x1(x1) VALUES('optimize'); INSERT INTO x1(x1) VALUES('integrity-check'); } {} finish_test | > > > > > > > > > > > > > > > > > > > > | 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 | execsql { INSERT INTO x1(x1) VALUES('optimize'); } execsql { DELETE FROM x1 WHERE rowid = 4; } } {} do_execsql_test 20.2 { INSERT INTO x1(x1) VALUES('optimize'); INSERT INTO x1(x1) VALUES('integrity-check'); } {} #------------------------------------------------------------------------- reset_db set doc "a b [string repeat x 100000]" do_execsql_test 21.0 { CREATE VIRTUAL TABLE x1 USING fts5(x); INSERT INTO x1(rowid, x) VALUES(11111, $doc); INSERT INTO x1(rowid, x) VALUES(11112, $doc); } do_execsql_test 21.1 { INSERT INTO x1(x1) VALUES('integrity-check'); } do_execsql_test 21.2 { SELECT rowid FROM x1($doc); } {11111 11112} do_execsql_test 21.3 { DELETE FROM x1 WHERE rowid=11111; INSERT INTO x1(x1) VALUES('integrity-check'); SELECT rowid FROM x1($doc); } {11112} finish_test |
Changes to src/btree.c.
︙ | ︙ | |||
2559 2560 2561 2562 2563 2564 2565 | */ if( p->sharable ){ int i; Btree *pSib; for(i=0; i<db->nDb; i++){ if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){ while( pSib->pPrev ){ pSib = pSib->pPrev; } | | | | 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 | */ if( p->sharable ){ int i; Btree *pSib; for(i=0; i<db->nDb; i++){ if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){ while( pSib->pPrev ){ pSib = pSib->pPrev; } if( (uptr)p->pBt<(uptr)pSib->pBt ){ p->pNext = pSib; p->pPrev = 0; pSib->pPrev = p; }else{ while( pSib->pNext && (uptr)pSib->pNext->pBt<(uptr)p->pBt ){ pSib = pSib->pNext; } p->pNext = pSib->pNext; p->pPrev = pSib; if( p->pNext ){ p->pNext->pPrev = p; } |
︙ | ︙ | |||
4864 4865 4866 4867 4868 4869 4870 | getCellInfo(pCur); aPayload = pCur->info.pPayload; #ifdef SQLITE_DIRECT_OVERFLOW_READ bEnd = offset+amt==pCur->info.nPayload; #endif assert( offset+amt <= pCur->info.nPayload ); | | > | > > > > | 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 | getCellInfo(pCur); aPayload = pCur->info.pPayload; #ifdef SQLITE_DIRECT_OVERFLOW_READ bEnd = offset+amt==pCur->info.nPayload; #endif assert( offset+amt <= pCur->info.nPayload ); assert( aPayload > pPage->aData ); if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){ /* Trying to read or write past the end of the data is an error. The ** conditional above is really: ** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ** but is recast into its current form to avoid integer overflow problems */ return SQLITE_CORRUPT_BKPT; } /* Check if data must be read/written to/from the btree page itself. */ if( offset<pCur->info.nLocal ){ int a = amt; if( a+offset>pCur->info.nLocal ){ |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
1052 1053 1054 1055 1056 1057 1058 | } #endif z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2); if( z==0 ) return; memcpy(z, pName->z, pName->n); z[pName->n] = 0; sqlite3Dequote(z); | < < < | 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 | } #endif z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2); if( z==0 ) return; memcpy(z, pName->z, pName->n); z[pName->n] = 0; sqlite3Dequote(z); for(i=0; i<p->nCol; i++){ if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); sqlite3DbFree(db, z); return; } } |
︙ | ︙ | |||
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 | if( pType->n==0 ){ /* If there is no type specified, columns have the default affinity ** 'BLOB'. */ pCol->affinity = SQLITE_AFF_BLOB; pCol->szEst = 1; }else{ pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst); } p->nCol++; pParse->constraintName.n = 0; } /* ** This routine is called by the parser while in the middle of | > > > > | 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 | if( pType->n==0 ){ /* If there is no type specified, columns have the default affinity ** 'BLOB'. */ pCol->affinity = SQLITE_AFF_BLOB; pCol->szEst = 1; }else{ zType = z + sqlite3Strlen30(z) + 1; memcpy(zType, pType->z, pType->n); zType[pType->n] = 0; pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst); pCol->colFlags |= COLFLAG_HASTYPE; } p->nCol++; pParse->constraintName.n = 0; } /* ** This routine is called by the parser while in the middle of |
︙ | ︙ | |||
1278 1279 1280 1281 1282 1283 1284 | Parse *pParse, /* Parsing context */ ExprList *pList, /* List of field names to be indexed */ int onError, /* What to do with a uniqueness conflict */ int autoInc, /* True if the AUTOINCREMENT keyword is present */ int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */ ){ Table *pTab = pParse->pNewTable; | | > | < > | < | | | 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 | Parse *pParse, /* Parsing context */ ExprList *pList, /* List of field names to be indexed */ int onError, /* What to do with a uniqueness conflict */ int autoInc, /* True if the AUTOINCREMENT keyword is present */ int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */ ){ Table *pTab = pParse->pNewTable; Column *pCol = 0; int iCol = -1, i; int nTerm; if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit; if( pTab->tabFlags & TF_HasPrimaryKey ){ sqlite3ErrorMsg(pParse, "table \"%s\" has more than one primary key", pTab->zName); goto primary_key_exit; } pTab->tabFlags |= TF_HasPrimaryKey; if( pList==0 ){ iCol = pTab->nCol - 1; pCol = &pTab->aCol[iCol]; pCol->colFlags |= COLFLAG_PRIMKEY; nTerm = 1; }else{ nTerm = pList->nExpr; for(i=0; i<nTerm; i++){ Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr); assert( pCExpr!=0 ); sqlite3StringToId(pCExpr); if( pCExpr->op==TK_ID ){ const char *zCName = pCExpr->u.zToken; for(iCol=0; iCol<pTab->nCol; iCol++){ if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){ pCol = &pTab->aCol[iCol]; pCol->colFlags |= COLFLAG_PRIMKEY; break; } } } } } if( nTerm==1 && pCol && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0 && sortOrder!=SQLITE_SO_DESC ){ pTab->iPKey = iCol; pTab->keyConf = (u8)onError; assert( autoInc==0 || autoInc==1 ); pTab->tabFlags |= autoInc*TF_Autoincrement; if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder; |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
3339 3340 3341 3342 3343 3344 3345 | ** 1. The specified column name was rowid", "oid" or "_rowid_" ** and there is no explicitly declared IPK column. ** ** 2. The table is not a view and the column name identified an ** explicitly declared column. Copy meta information from *pCol. */ if( pCol ){ | | < | 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 | ** 1. The specified column name was rowid", "oid" or "_rowid_" ** and there is no explicitly declared IPK column. ** ** 2. The table is not a view and the column name identified an ** explicitly declared column. Copy meta information from *pCol. */ if( pCol ){ zDataType = sqlite3ColumnType(pCol,0); zCollSeq = pCol->zColl; notnull = pCol->notNull!=0; primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0; }else{ zDataType = "INTEGER"; primarykey = 1; |
︙ | ︙ |
Changes to src/memjournal.c.
︙ | ︙ | |||
399 400 401 402 403 404 405 | } /* ** Return the number of bytes required to store a JournalFile that uses vfs ** pVfs to create the underlying on-disk files. */ int sqlite3JournalSize(sqlite3_vfs *pVfs){ | | | 399 400 401 402 403 404 405 406 407 | } /* ** Return the number of bytes required to store a JournalFile that uses vfs ** pVfs to create the underlying on-disk files. */ int sqlite3JournalSize(sqlite3_vfs *pVfs){ return MAX(pVfs->szOsFile, (int)sizeof(MemJournal)); } |
Changes to src/os_unix.c.
︙ | ︙ | |||
1362 1363 1364 1365 1366 1367 1368 | if( pFile->ctrlFlags & UNIXFILE_NOLOCK ) return; rc = osFstat(pFile->h, &buf); if( rc!=0 ){ sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); return; } | | | 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 | if( pFile->ctrlFlags & UNIXFILE_NOLOCK ) return; rc = osFstat(pFile->h, &buf); if( rc!=0 ){ sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); return; } if( buf.st_nlink==0 ){ sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); return; } if( buf.st_nlink>1 ){ sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); return; } |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
340 341 342 343 344 345 346 347 348 349 350 | * data will almost certainly result in an immediate access violation. ****************************************************************************** */ #ifndef SQLITE_WIN32_HEAP_CREATE # define SQLITE_WIN32_HEAP_CREATE (TRUE) #endif /* * The initial size of the Win32-specific heap. This value may be zero. */ #ifndef SQLITE_WIN32_HEAP_INIT_SIZE | > > > > > > > > > > > > | | 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 | * data will almost certainly result in an immediate access violation. ****************************************************************************** */ #ifndef SQLITE_WIN32_HEAP_CREATE # define SQLITE_WIN32_HEAP_CREATE (TRUE) #endif /* * This is cache size used in the calculation of the initial size of the * Win32-specific heap. It cannot be negative. */ #ifndef SQLITE_WIN32_CACHE_SIZE # if SQLITE_DEFAULT_CACHE_SIZE>=0 # define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE) # else # define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE)) # endif #endif /* * The initial size of the Win32-specific heap. This value may be zero. */ #ifndef SQLITE_WIN32_HEAP_INIT_SIZE # define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \ (SQLITE_DEFAULT_PAGE_SIZE) + 4194304) #endif /* * The maximum size of the Win32-specific heap. This value may be zero. */ #ifndef SQLITE_WIN32_HEAP_MAX_SIZE |
︙ | ︙ | |||
5420 5421 5422 5423 5424 5425 5426 | UNUSED_PARAMETER(pVfs); memset(zBuf, 0, nBuf); return nBuf; #else EntropyGatherer e; UNUSED_PARAMETER(pVfs); memset(zBuf, 0, nBuf); | | | | 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 | UNUSED_PARAMETER(pVfs); memset(zBuf, 0, nBuf); return nBuf; #else EntropyGatherer e; UNUSED_PARAMETER(pVfs); memset(zBuf, 0, nBuf); #if defined(_MSC_VER) && _MSC_VER>=1400 && !SQLITE_OS_WINCE rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */ #endif /* defined(_MSC_VER) && _MSC_VER>=1400 */ e.a = (unsigned char*)zBuf; e.na = nBuf; e.nXor = 0; e.i = 0; { SYSTEMTIME x; |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
1062 1063 1064 1065 1066 1067 1068 | Column *pCol; Index *pPk = sqlite3PrimaryKeyIndex(pTab); pParse->nMem = 6; sqlite3CodeVerifySchema(pParse, iDb); setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) ); sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ | < < | | | 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 | Column *pCol; Index *pPk = sqlite3PrimaryKeyIndex(pTab); pParse->nMem = 6; sqlite3CodeVerifySchema(pParse, iDb); setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) ); sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ if( IsHiddenColumn(pCol) ){ nHidden++; continue; } if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){ k = 0; }else if( pPk==0 ){ k = 1; }else{ for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} } assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN ); sqlite3VdbeMultiLoad(v, 1, "issisi", i-nHidden, pCol->zName, sqlite3ColumnType(pCol,""), pCol->notNull ? 1 : 0, pCol->pDflt ? pCol->pDflt->u.zToken : 0, k); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); } } } |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
1426 1427 1428 1429 1430 1431 1432 | assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) ); #ifdef SQLITE_ENABLE_COLUMN_METADATA if( iCol<0 ){ zType = "INTEGER"; zOrigCol = "rowid"; }else{ zOrigCol = pTab->aCol[iCol].zName; | | | | 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 | assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) ); #ifdef SQLITE_ENABLE_COLUMN_METADATA if( iCol<0 ){ zType = "INTEGER"; zOrigCol = "rowid"; }else{ zOrigCol = pTab->aCol[iCol].zName; zType = sqlite3ColumnType(&pTab->aCol[iCol],0); estWidth = pTab->aCol[iCol].szEst; } zOrigTab = pTab->zName; if( pNC->pParse ){ int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); zOrigDb = pNC->pParse->db->aDb[iDb].zName; } #else if( iCol<0 ){ zType = "INTEGER"; }else{ zType = sqlite3ColumnType(&pTab->aCol[iCol],0); estWidth = pTab->aCol[iCol].szEst; } #endif } break; } #ifndef SQLITE_OMIT_SUBQUERY |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
177 178 179 180 181 182 183 | # define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X)) #else /* Generates a warning - but it always works */ # define SQLITE_INT_TO_PTR(X) ((void*)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(X)) #endif | < < < < < < < < < < < < < < < | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | # define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X)) #else /* Generates a warning - but it always works */ # define SQLITE_INT_TO_PTR(X) ((void*)(X)) # define SQLITE_PTR_TO_INT(X) ((int)(X)) #endif /* ** A macro to hint to the compiler that a function should not be ** inlined. */ #if defined(__GNUC__) # define SQLITE_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) && _MSC_VER>=1310 |
︙ | ︙ | |||
579 580 581 582 583 584 585 | #ifndef offsetof #define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) #endif /* ** Macros to compute minimum and maximum of two numbers. */ | > | > > | > | 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 | #ifndef offsetof #define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) #endif /* ** Macros to compute minimum and maximum of two numbers. */ #ifndef MIN # define MIN(A,B) ((A)<(B)?(A):(B)) #endif #ifndef MAX # define MAX(A,B) ((A)>(B)?(A):(B)) #endif /* ** Swap two objects of type TYPE. */ #define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;} /* |
︙ | ︙ | |||
708 709 710 711 712 713 714 715 716 717 718 719 720 721 | # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(_M_ARM) || defined(__arm__) || defined(__x86) # define SQLITE_PTRSIZE 4 # else # define SQLITE_PTRSIZE 8 # endif #endif /* ** Macros to determine whether the machine is big or little endian, ** and whether or not that determination is run-time or compile-time. ** ** For best performance, an attempt is made to guess at the byte-order ** using C-preprocessor macros. If that is unsuccessful, or if | > > > > > > > > > > > > > > > > > > > > > | 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(_M_ARM) || defined(__arm__) || defined(__x86) # define SQLITE_PTRSIZE 4 # else # define SQLITE_PTRSIZE 8 # endif #endif /* The uptr type is an unsigned integer large enough to hold a pointer */ #if defined(HAVE_STDINT_H) typedef uintptr_t uptr; #elif SQLITE_PTRSIZE==4 typedef u32 uptr; #else typedef u64 uptr; #endif /* ** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to ** something between S (inclusive) and E (exclusive). ** ** In other words, S is a buffer and E is a pointer to the first byte after ** the end of buffer S. This macro returns true if P points to something ** contained within the buffer S. */ #define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E))) /* ** Macros to determine whether the machine is big or little endian, ** and whether or not that determination is run-time or compile-time. ** ** For best performance, an attempt is made to guess at the byte-order ** using C-preprocessor macros. If that is unsuccessful, or if |
︙ | ︙ | |||
1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 | u8 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; /* Allowed values for Column.colFlags: */ #define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ #define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ /* ** A "Collating Sequence" is defined by an instance of the following ** structure. Conceptually, a collating sequence consists of a name and ** a comparison routine that defines the order of that sequence. ** ** If CollSeq.xCmp is NULL, it means that the | > | 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 | u8 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; /* Allowed values for Column.colFlags: */ #define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ #define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ #define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */ /* ** A "Collating Sequence" is defined by an instance of the following ** structure. Conceptually, a collating sequence consists of a name and ** a comparison routine that defines the order of that sequence. ** ** If CollSeq.xCmp is NULL, it means that the |
︙ | ︙ | |||
3294 3295 3296 3297 3298 3299 3300 | #endif /* ** Internal function prototypes */ int sqlite3StrICmp(const char*,const char*); int sqlite3Strlen30(const char*); | | | 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 | #endif /* ** Internal function prototypes */ int sqlite3StrICmp(const char*,const char*); int sqlite3Strlen30(const char*); char *sqlite3ColumnType(Column*,char*); #define sqlite3StrNICmp sqlite3_strnicmp int sqlite3MallocInit(void); void sqlite3MallocEnd(void); void *sqlite3Malloc(u64); void *sqlite3MallocZero(u64); void *sqlite3DbMallocZero(sqlite3*, u64); |
︙ | ︙ |
Changes to src/sqliteLimit.h.
︙ | ︙ | |||
97 98 99 100 101 102 103 | # define SQLITE_MAX_FUNCTION_ARG 127 #endif /* ** The suggested maximum number of in-memory pages to use for ** the main database table and for temporary tables. ** | | | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | # define SQLITE_MAX_FUNCTION_ARG 127 #endif /* ** The suggested maximum number of in-memory pages to use for ** the main database table and for temporary tables. ** ** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000, ** which means the cache size is limited to 2048000 bytes of memory. ** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be ** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options. */ #ifndef SQLITE_DEFAULT_CACHE_SIZE # define SQLITE_DEFAULT_CACHE_SIZE -2000 #endif |
︙ | ︙ |
Changes to src/test_multiplex.c.
︙ | ︙ | |||
713 714 715 716 717 718 719 | static int multiplexSleep(sqlite3_vfs *a, int b){ return gMultiplex.pOrigVfs->xSleep(gMultiplex.pOrigVfs, b); } static int multiplexCurrentTime(sqlite3_vfs *a, double *b){ return gMultiplex.pOrigVfs->xCurrentTime(gMultiplex.pOrigVfs, b); } static int multiplexGetLastError(sqlite3_vfs *a, int b, char *c){ | > | > > > | 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | static int multiplexSleep(sqlite3_vfs *a, int b){ return gMultiplex.pOrigVfs->xSleep(gMultiplex.pOrigVfs, b); } static int multiplexCurrentTime(sqlite3_vfs *a, double *b){ return gMultiplex.pOrigVfs->xCurrentTime(gMultiplex.pOrigVfs, b); } static int multiplexGetLastError(sqlite3_vfs *a, int b, char *c){ if( gMultiplex.pOrigVfs->xGetLastError ){ return gMultiplex.pOrigVfs->xGetLastError(gMultiplex.pOrigVfs, b, c); }else{ return 0; } } static int multiplexCurrentTimeInt64(sqlite3_vfs *a, sqlite3_int64 *b){ return gMultiplex.pOrigVfs->xCurrentTimeInt64(gMultiplex.pOrigVfs, b); } /************************ I/O Method Wrappers *******************************/ |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
106 107 108 109 110 111 112 | */ int sqlite3Strlen30(const char *z){ if( z==0 ) return 0; return 0x3fffffff & (int)strlen(z); } /* | | > | > > | > | | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | */ int sqlite3Strlen30(const char *z){ if( z==0 ) return 0; return 0x3fffffff & (int)strlen(z); } /* ** Return the declared type of a column. Or return zDflt if the column ** has no declared type. ** ** The column type is an extra string stored after the zero-terminator on ** the column name if and only if the COLFLAG_HASTYPE flag is set. */ char *sqlite3ColumnType(Column *pCol, char *zDflt){ if( (pCol->colFlags & COLFLAG_HASTYPE)==0 ) return zDflt; return pCol->zName + strlen(pCol->zName) + 1; } /* ** Helper function for sqlite3Error() - called rarely. Broken out into ** a separate routine to avoid unnecessary register saves on entry to ** sqlite3Error(). */ |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
2520 2521 2522 2523 2524 2525 2526 | offset64 += sqlite3VdbeSerialTypeLen(t); } pC->aType[i++] = t; aOffset[i] = (u32)(offset64 & 0xffffffff); }while( i<=p2 && zHdr<zEndHdr ); pC->nHdrParsed = i; pC->iHdrOffset = (u32)(zHdr - zData); | < > > > | 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 | offset64 += sqlite3VdbeSerialTypeLen(t); } pC->aType[i++] = t; aOffset[i] = (u32)(offset64 & 0xffffffff); }while( i<=p2 && zHdr<zEndHdr ); pC->nHdrParsed = i; pC->iHdrOffset = (u32)(zHdr - zData); /* The record is corrupt if any of the following are true: ** (1) the bytes of the header extend past the declared header size ** (2) the entire header was used but not all data was used ** (3) the end of the data extends beyond the end of the record. */ if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize)) || (offset64 > pC->payloadSize) ){ if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); }else{ t = 0; } /* If after trying to extract new entries from the header, nHdrParsed is ** still not up to p2, that means that the record has fewer than p2 ** columns. So the result will be either the default value or a NULL. |
︙ | ︙ |
Changes to src/vtab.c.
︙ | ︙ | |||
560 561 562 563 564 565 566 | ** columns of the table to see if any of them contain the token "hidden". ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from ** the type string. */ pVTable->pNext = pTab->pVTable; pTab->pVTable = pVTable; for(iCol=0; iCol<pTab->nCol; iCol++){ | | < < < < < | | > | | < | < | 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 | ** columns of the table to see if any of them contain the token "hidden". ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from ** the type string. */ pVTable->pNext = pTab->pVTable; pTab->pVTable = pVTable; for(iCol=0; iCol<pTab->nCol; iCol++){ char *zType = sqlite3ColumnType(&pTab->aCol[iCol], ""); int nType; int i = 0; nType = sqlite3Strlen30(zType); for(i=0; i<nType; i++){ if( 0==sqlite3StrNICmp("hidden", &zType[i], 6) && (i==0 || zType[i-1]==' ') && (zType[i+6]=='\0' || zType[i+6]==' ') ){ break; } } if( i<nType ){ int j; int nDel = 6 + (zType[i+6] ? 1 : 0); for(j=i; (j+nDel)<=nType; j++){ zType[j] = zType[j+nDel]; |
︙ | ︙ |
Changes to test/capi3.test.
︙ | ︙ | |||
925 926 927 928 929 930 931 | } 1 do_test capi3-11.10 { sqlite3_step $STMT } {SQLITE_ROW} do_test capi3-11.11 { sqlite3_step $STMT } {SQLITE_DONE} | | | 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 | } 1 do_test capi3-11.10 { sqlite3_step $STMT } {SQLITE_ROW} do_test capi3-11.11 { sqlite3_step $STMT } {SQLITE_DONE} ifcapable !autoreset { do_test capi3-11.12armor { sqlite3_step $STMT sqlite3_step $STMT } {SQLITE_MISUSE} } else { do_test capi3-11.12 { sqlite3_step $STMT |
︙ | ︙ |
Changes to test/capi3c.test.
︙ | ︙ | |||
864 865 866 867 868 869 870 | } 1 do_test capi3c-11.10 { sqlite3_step $STMT } {SQLITE_ROW} do_test capi3c-11.11 { sqlite3_step $STMT } {SQLITE_DONE} | | | 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 | } 1 do_test capi3c-11.10 { sqlite3_step $STMT } {SQLITE_ROW} do_test capi3c-11.11 { sqlite3_step $STMT } {SQLITE_DONE} ifcapable !autoreset { do_test capi3c-11.12armor { sqlite3_step $STMT sqlite3_step $STMT } {SQLITE_MISUSE} } else { do_test capi3c-11.12 { sqlite3_step $STMT |
︙ | ︙ |
Changes to test/fuzzcheck.c.
︙ | ︙ | |||
185 186 187 188 189 190 191 | } #endif /* ** Reallocate memory. Show and error and quit if unable. */ static void *safe_realloc(void *pOld, int szNew){ | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | } #endif /* ** Reallocate memory. Show and error and quit if unable. */ static void *safe_realloc(void *pOld, int szNew){ void *pNew = realloc(pOld, szNew<=0 ? 1 : szNew); if( pNew==0 ) fatalError("unable to realloc for %d bytes", szNew); return pNew; } /* ** Initialize the virtual file system. */ |
︙ | ︙ |
Changes to test/memsubsys1.test.
︙ | ︙ | |||
253 254 255 256 257 258 259 | expr {$pg_used<24} } 1 do_test memsubsys1-7.4 { set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2] } 0 do_test memsubsys1-7.5 { set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2] | | | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | expr {$pg_used<24} } 1 do_test memsubsys1-7.4 { set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2] } 0 do_test memsubsys1-7.5 { set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2] expr {$maxreq<(4100 + 8200*[nonzero_reserved_bytes])} } 1 do_test memsubsys1-7.6 { set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] } 1 do_test memsubsys1-7.7 { set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2] } 0 |
︙ | ︙ |
Changes to test/nolock.test.
︙ | ︙ | |||
179 180 181 182 183 184 185 | xAccess $::tvfs_calls(xAccess) } {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} db2 close db close tvfs delete | > | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | xAccess $::tvfs_calls(xAccess) } {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0} db2 close db close tvfs delete if {[permutation]!="inmemory_journal"} { # 2016-03-11: Make sure all works when transitioning to WAL mode # under nolock. # do_test nolock-4.1 { forcedelete test.db sqlite3 db file:test.db?nolock=1 -uri 1 db eval { PRAGMA journal_mode=WAL; CREATE TABLE t1(x); INSERT INTO t1 VALUES('youngling'); SELECT * FROM t1; } } {delete youngling} db close do_test nolock-4.2 { forcedelete test.db sqlite3 db test.db db eval { PRAGMA journal_mode=WAL; CREATE TABLE t1(x); INSERT INTO t1 VALUES('catbird'); SELECT * FROM t1; } } {wal catbird} do_test nolock-4.3 { db close sqlite3 db file:test.db?nolock=1 -uri 1 set rc [catch {db eval {SELECT * FROM t1}} msg] lappend rc $msg } {1 {unable to open database file}} } finish_test |
Changes to test/shell1.test.
︙ | ︙ | |||
41 42 43 44 45 46 47 | set res [catchcmd "test.db -bad" ""] set rc [lindex $res 0] list $rc \ [regexp {Error: unknown option: -bad} $res] } {1 1} # error on extra options do_test shell1-1.1.2 { | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | set res [catchcmd "test.db -bad" ""] set rc [lindex $res 0] list $rc \ [regexp {Error: unknown option: -bad} $res] } {1 1} # error on extra options do_test shell1-1.1.2 { catchcmd "test.db \"select+3\" \"select+4\"" "" } {0 {3 4}} # error on extra options do_test shell1-1.1.3 { catchcmd "test.db FOO test.db BAD" ".quit" } {1 {Error: near "FOO": syntax error}} |
︙ | ︙ | |||
272 273 274 275 276 277 278 | # too many arguments catchcmd "test.db" ".bail OFF BAD" } {1 {Usage: .bail on|off}} # .databases List names and files of attached databases do_test shell1-3.3.1 { catchcmd "-csv test.db" ".databases" | | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | # too many arguments catchcmd "test.db" ".bail OFF BAD" } {1 {Usage: .bail on|off}} # .databases List names and files of attached databases do_test shell1-3.3.1 { catchcmd "-csv test.db" ".databases" } "/0.+main.+[string map {/ ".{1,2}"} [string range [get_pwd] 0 10]].*/" do_test shell1-3.3.2 { # extra arguments ignored catchcmd "test.db" ".databases BAD" } "/0.+main.+[string map {/ ".{1,2}"} [string range [get_pwd] 0 10]].*/" # .dump ?TABLE? ... Dump the database in an SQL text format # If TABLE specified, only dump tables matching # LIKE pattern TABLE. do_test shell1-3.4.1 { set res [catchcmd "test.db" ".dump"] list [regexp {BEGIN TRANSACTION;} $res] \ |
︙ | ︙ |
Changes to test/shell2.test.
︙ | ︙ | |||
39 40 41 42 43 44 45 | set fexist [file exist foo.db] list $rc $fexist } {{0 {}} 1} # Shell silently ignores extra parameters. # Ticket [f5cb008a65]. do_test shell2-1.2.1 { | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | set fexist [file exist foo.db] list $rc $fexist } {{0 {}} 1} # Shell silently ignores extra parameters. # Ticket [f5cb008a65]. do_test shell2-1.2.1 { set rc [catch { eval exec $CLI \":memory:\" \"select+3\" \"select+4\" } msg] list $rc $msg } {0 {3 4}} # Test a problem reported on the mailing list. The shell was at one point # returning the generic SQLITE_ERROR message ("SQL error or missing database") # instead of the "too many levels..." message in the test below. |
︙ | ︙ |
Changes to test/shell3.test.
︙ | ︙ | |||
21 22 23 24 25 26 27 28 29 30 31 32 33 34 | # set testdir [file dirname $argv0] source $testdir/tester.tcl set CLI [test_find_cli] db close forcedelete test.db test.db-journal test.db-wal sqlite3 db test.db #---------------------------------------------------------------------------- # shell3-1.*: Basic tests for running SQL statments from command line. # # Run SQL statement from command line do_test shell3-1.1 { | > > > > > > > > > > > > | 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 | # set testdir [file dirname $argv0] source $testdir/tester.tcl set CLI [test_find_cli] db close forcedelete test.db test.db-journal test.db-wal sqlite3 db test.db # There are inconsistencies in command-line argument quoting on Windows. # In particular, individual applications are responsible for command-line # parsing in Windows, not the shell. Depending on whether the sqlite3.exe # program is compiled with MinGW or MSVC, the command-line parsing is # different. This causes problems for the tests below. To avoid # issues, these tests are disabled for windows. # if {$::tcl_platform(platform)=="windows"} { finish_test return } #---------------------------------------------------------------------------- # shell3-1.*: Basic tests for running SQL statments from command line. # # Run SQL statement from command line do_test shell3-1.1 { |
︙ | ︙ |
Changes to test/snapshot.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # of this file is the sqlite3_snapshot_xxx() APIs. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !snapshot {finish_test; return} set testprefix snapshot #------------------------------------------------------------------------- # Check some error conditions in snapshot_get(). It is an error if: # # 1) snapshot_get() is called on a non-WAL database, or # 2) there is an open write transaction on the database. # | > > > > > > > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | # of this file is the sqlite3_snapshot_xxx() APIs. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !snapshot {finish_test; return} set testprefix snapshot # This test does not work with the inmemory_journal permutation. The reason # is that each connection opened as part of this permutation executes # "PRAGMA journal_mode=memory", which fails if the database is in wal mode # and there are one or more existing connections. if {[permutation]=="inmemory_journal"} { finish_test return } #------------------------------------------------------------------------- # Check some error conditions in snapshot_get(). It is an error if: # # 1) snapshot_get() is called on a non-WAL database, or # 2) there is an open write transaction on the database. # |
︙ | ︙ |
Changes to test/snapshot_fault.test.
︙ | ︙ | |||
142 143 144 145 146 147 148 | BEGIN; } } -body { if { [catch { sqlite3_snapshot_open db main $::snapshot } msg] } { error $msg } } -test { | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | BEGIN; } } -body { if { [catch { sqlite3_snapshot_open db main $::snapshot } msg] } { error $msg } } -test { faultsim_test_result {0 {}} {1 SQLITE_IOERR} {1 SQLITE_NOMEM} \ {1 SQLITE_IOERR_NOMEM} {1 SQLITE_IOERR_READ} if {$testrc==0} { set res [db eval { SELECT a FROM t1; PRAGMA integrity_check; }] if {$res != "1 2 3 ok"} { error "res is $res" } |
︙ | ︙ |