mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Merge in minor bug fixes and performance tweaks from trunk leading up to
the version 3.8.0 release. FossilOrigin-Name: 831492dca8bcfb1a1f83a8bb15de9cc94f29f07e
This commit is contained in:
@@ -5135,11 +5135,11 @@ int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){
|
||||
if( pTC ) pModule->xClose(pTC);
|
||||
if( rc==SQLITE_DONE ) rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
|
||||
if( pDef->pList ){
|
||||
rc = fts3PendingListAppendVarint(&pDef->pList, 0);
|
||||
}
|
||||
for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
|
||||
if( pDef->pList ){
|
||||
rc = fts3PendingListAppendVarint(&pDef->pList, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
60
manifest
60
manifest
@@ -1,5 +1,5 @@
|
||||
C Merge\sperformance\senhancements\sand\scompiler\swarning\sfixes\sfrom\strunk.
|
||||
D 2013-08-20T13:02:16.832
|
||||
C Merge\sin\sminor\sbug\sfixes\sand\sperformance\stweaks\sfrom\strunk\sleading\sup\sto\nthe\sversion\s3.8.0\srelease.
|
||||
D 2013-08-22T15:07:08.266
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in aff38bc64c582dd147f18739532198372587b0f0
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -96,7 +96,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c 92391b4b4fb043564c6539ea9b8661e3bcba47b9
|
||||
F ext/fts3/fts3_unicode2.c 0113d3acf13429e6dc38e0647d1bc71211c31a4d
|
||||
F ext/fts3/fts3_write.c edf39aea5d45080195f6b38aa5efee3804716dd0
|
||||
F ext/fts3/fts3_write.c ce45c3ea578464f26b0293ea8e54a39694f18b64
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
|
||||
@@ -173,10 +173,10 @@ F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168
|
||||
F src/analyze.c a33fcb0b3a399d966951feb9f32115106b3ecc2e
|
||||
F src/attach.c 5df737912f668fd160ec1d560755f85fdccbe5b7
|
||||
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165
|
||||
F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c adea13e65d6c7b969bcd74cea6ae79b2d3c393fa
|
||||
F src/btree.c b7cbb0bcc61cbf1e0ed3cfcc79ee12ffcf4f469e
|
||||
F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf
|
||||
F src/btreeInt.h 51cf220a9b9223354770883e93a859dc377aa27f
|
||||
F src/build.c f99a715ff9290996b579d5e1ec8e94239dc9ae5e
|
||||
@@ -185,10 +185,10 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267
|
||||
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
||||
F src/delete.c 30ed4bc76a1a32c55bf17ac1528c5867aa5502c0
|
||||
F src/expr.c 42d8235af422661ab80be097bebca485b33e2e14
|
||||
F src/expr.c 6bab61c757c4c4c94a92e98d507025d5d18afd3c
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb
|
||||
F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef
|
||||
F src/func.c d7be77897c91d5b9887beb372f1e6deb515c92af
|
||||
F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759
|
||||
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
|
||||
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
||||
@@ -217,16 +217,16 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847
|
||||
F src/os_win.c 1d84f2079d9b91f91a4b5dbfa5e08f1b1a0ed0ff
|
||||
F src/pager.c 7c999137cb940133f7fc7609ccfa66f17eec4ab4
|
||||
F src/pager.h 66e42d6942a445d4c25651733ab2079dbebc7ca9
|
||||
F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8
|
||||
F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c
|
||||
F src/parse.y 27c6b4138497d6f8360ba7847da6ed48033f957f
|
||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
||||
F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63
|
||||
F src/pragma.c 1d96ba749253b49bc229c6294f9c2e5ef3dca85c
|
||||
F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f
|
||||
F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b
|
||||
F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
|
||||
F src/resolve.c 9d53899cc6e1f4ec0b4632d07e97d57827bf63b9
|
||||
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
||||
F src/select.c 8b148eb851f384412aea57091659d14b369918ca
|
||||
@@ -234,7 +234,7 @@ F src/shell.c 1c317a4c96d61d8d9fdad9fd1811d9b10b8c7f57
|
||||
F src/sqlite.h.in dcca940021f8f6643630fb7711bfd4e3fa002566
|
||||
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
|
||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||
F src/sqliteInt.h a24a7f54dd59e8f59d67f7ab0682b5c22f554855
|
||||
F src/sqliteInt.h 93fe5b4c6234942cb9ca14fc25ad634d0e2ff775
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
@@ -290,20 +290,20 @@ F src/update.c e3668141dd9701023681239265e001388f182236
|
||||
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
|
||||
F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
|
||||
F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8
|
||||
F src/vdbe.c 76502f0813c3ecf1a54611fc5262c8bc77a54fb7
|
||||
F src/vdbe.c 08a46d04e5bdfd95884664eeeb8fbe5e4de426ee
|
||||
F src/vdbe.h 7aa3ab6210a68471c8490dedfc9aa4ef5684b9a0
|
||||
F src/vdbeInt.h 9bf236dc477fb8f1f54b078cf80064663f8a409a
|
||||
F src/vdbeapi.c ae87d198eb3ce67c02886601baee0fd478092076
|
||||
F src/vdbeaux.c 6549864e5fffa3d04941551610e4800de72e1be9
|
||||
F src/vdbeaux.c 20ec92cdc43374b6537fbd7bc2cf7a28967bbe44
|
||||
F src/vdbeblob.c 1268e0bcb8e21fa32520b0fc376e1bcdfaa0c642
|
||||
F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
|
||||
F src/vdbemem.c 61d5ddb8e4d4e14f625062bf5bcc7ce08bb20af3
|
||||
F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
|
||||
F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc
|
||||
F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624
|
||||
F src/vtab.c 165ce0e797c2cd23badb104c9f2ae9042d6d942c
|
||||
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
|
||||
F src/where.c 03a50ecb2f4f02b5492d669a84875947b56b8906
|
||||
F src/where.c 8596edcfbffc6d26a9a4f8e4a41d09f058dd7037
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||
@@ -380,7 +380,7 @@ F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815
|
||||
F test/closure01.test dbb28f1ea9eeaf0a53ec5bc0fed352e479def8c7
|
||||
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
|
||||
F test/collate1.test b709989e6e6ff6e1d2bd64231c2c1d8146846c9e
|
||||
F test/collate2.test 285cef1b58ce2b3cf074a386f763ce753c81c97f
|
||||
F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621
|
||||
F test/collate3.test 79558a286362cb9ed603c6fa543f1cda7f563f0f
|
||||
F test/collate4.test 031f7265c13308b724ba3c49f41cc04612bd92b1
|
||||
F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6
|
||||
@@ -408,7 +408,7 @@ F test/corruptC.test 62a767fe64acb1975f58cc6171192839c783edbb
|
||||
F test/corruptD.test 3b09903a2e2fe07ecafe775fea94177f8a4bb34f
|
||||
F test/corruptE.test d3a3d7e864a95978195741744dda4abfd8286018
|
||||
F test/corruptF.test 1c7b6f77cf3f237fb7fbb5b61d6c921fd4c7b993
|
||||
F test/corruptG.test d18ee5169e10a76bccb7b115e551bc31087a525e
|
||||
F test/corruptG.test c67fd860e9e3943bc90b856a3049c9a28827167e
|
||||
F test/count.test 454e1ce985c94d13efeac405ce54439f49336163
|
||||
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
|
||||
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
|
||||
@@ -603,8 +603,8 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
|
||||
F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7
|
||||
F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026
|
||||
F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33
|
||||
F test/index6.test f53a788b813eb6937346867bae9e587c434dd9a1
|
||||
F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c
|
||||
F test/index6.test 6a754747f444fecb7f4ae50ce4ac7a0d269e090d
|
||||
F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 489aa12a027c83d291f5034a83c8c32e6be1dca2
|
||||
@@ -657,7 +657,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
|
||||
F test/malloc.test fd368e31fe98d4779ed80442f311ed9f03bcd1f7
|
||||
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
|
||||
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
|
||||
F test/malloc5.test a577cbbcc1594c7763b9b3515b3633555751c7f0
|
||||
F test/malloc5.test fafce0aa9157060445cd1a56ad50fc79d82f28c3
|
||||
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
|
||||
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
|
||||
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
|
||||
@@ -674,7 +674,7 @@ F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb
|
||||
F test/mallocI.test a88c2b9627c8506bf4703d8397420043a786cdb6
|
||||
F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
|
||||
F test/mallocK.test d79968641d1b70d88f6c01bdb9a7eb4a55582cc9
|
||||
F test/malloc_common.tcl 9a98856549bfb3fab205edbc1317216edc52e70d
|
||||
F test/malloc_common.tcl 58e54229c4132ef882a11fab6419ec4cd3073589
|
||||
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test db5260330676de007be8530d6ecc7c9ab2b06ad3
|
||||
@@ -731,7 +731,7 @@ F test/permutations.test 742b8005bb3c782797a20beccdbe213ef52531fb
|
||||
F test/pragma.test 5e7de6c32a5d764f09437d2025f07e4917b9e178
|
||||
F test/pragma2.test 224f0381f9411a78ae685cac24c13656a62021b7
|
||||
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
|
||||
F test/progress.test 552dc1edc37333a8d3098b8c26a2b7f06f5799d7
|
||||
F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
|
||||
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
||||
@@ -1053,8 +1053,8 @@ F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
|
||||
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
|
||||
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
|
||||
F test/where.test da54153a4c1571ea1b95659e5bec8119edf786aa
|
||||
F test/where2.test b1830f762f837153a4c9743adaab90a5761f73e7
|
||||
F test/where3.test a0682ba3dc8c8f46ffcc95a3d9f58c4327fc129f
|
||||
F test/where2.test 76d5346f7edb2a6a0442dcf3e9d088ac6903e0b5
|
||||
F test/where3.test d28c51f257e60be30f74308fa385ceeddfb54a6e
|
||||
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
|
||||
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
|
||||
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
||||
@@ -1062,7 +1062,7 @@ F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
|
||||
F test/where8.test 6f95896633cf2d307b5263145b942b7d33e837c6
|
||||
F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
|
||||
F test/where9.test 9a7fda4a4512abc26a855e8b2b6572b200f6019b
|
||||
F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a
|
||||
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
|
||||
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
|
||||
F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a
|
||||
F test/whereD.test 6c2feb79ef1f68381b07f39017fe5f9b96da8d62
|
||||
@@ -1119,7 +1119,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
|
||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||
P 67587a3348b84424b2ab1f2df1ea923a5168e2e4 7f72fc4f47445a2c01910b268335873de9f75059
|
||||
R 38645eeb23d643e57952026ace84c002
|
||||
P 3e4033285deb417bd72c008917729dbf3bf4e90d 0775501acf152dcbf4dd039f4511f3d8c4330d85
|
||||
R f6e422c39c44105817eb40d9d54618de
|
||||
U drh
|
||||
Z 8d51de2c92073e757664e09f591c4bfa
|
||||
Z f9597afebde4efa08f5ab31e24bede7f
|
||||
|
@@ -1 +1 @@
|
||||
3e4033285deb417bd72c008917729dbf3bf4e90d
|
||||
831492dca8bcfb1a1f83a8bb15de9cc94f29f07e
|
@@ -392,7 +392,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
|
||||
DbPage *pSrcPg; /* Source page object */
|
||||
rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
|
||||
PAGER_ACQUIRE_READONLY);
|
||||
PAGER_GET_READONLY);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
|
||||
sqlite3PagerUnref(pSrcPg);
|
||||
|
67
src/btree.c
67
src/btree.c
@@ -940,7 +940,8 @@ static void btreeParseCellPtr(
|
||||
assert( n==4-4*pPage->leaf );
|
||||
if( pPage->intKey ){
|
||||
if( pPage->hasData ){
|
||||
n += getVarint32(&pCell[n], nPayload);
|
||||
assert( n==0 );
|
||||
n = getVarint32(pCell, nPayload);
|
||||
}else{
|
||||
nPayload = 0;
|
||||
}
|
||||
@@ -1584,15 +1585,12 @@ static int btreeGetPage(
|
||||
BtShared *pBt, /* The btree */
|
||||
Pgno pgno, /* Number of the page to fetch */
|
||||
MemPage **ppPage, /* Return the page in this parameter */
|
||||
int noContent, /* Do not load page content if true */
|
||||
int bReadonly /* True if a read-only (mmap) page is ok */
|
||||
int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */
|
||||
){
|
||||
int rc;
|
||||
DbPage *pDbPage;
|
||||
int flags = (noContent ? PAGER_ACQUIRE_NOCONTENT : 0)
|
||||
| (bReadonly ? PAGER_ACQUIRE_READONLY : 0);
|
||||
|
||||
assert( noContent==0 || bReadonly==0 );
|
||||
assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY );
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
|
||||
if( rc ) return rc;
|
||||
@@ -1640,15 +1638,16 @@ static int getAndInitPage(
|
||||
BtShared *pBt, /* The database file */
|
||||
Pgno pgno, /* Number of the page to get */
|
||||
MemPage **ppPage, /* Write the page pointer here */
|
||||
int bReadonly /* True if a read-only (mmap) page is ok */
|
||||
int bReadonly /* PAGER_GET_READONLY or 0 */
|
||||
){
|
||||
int rc;
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
assert( bReadonly==PAGER_GET_READONLY || bReadonly==0 );
|
||||
|
||||
if( pgno>btreePagecount(pBt) ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
rc = btreeGetPage(pBt, pgno, ppPage, 0, bReadonly);
|
||||
rc = btreeGetPage(pBt, pgno, ppPage, bReadonly);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = btreeInitPage(*ppPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -2381,7 +2380,7 @@ static int lockBtree(BtShared *pBt){
|
||||
assert( pBt->pPage1==0 );
|
||||
rc = sqlite3PagerSharedLock(pBt->pPager);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
rc = btreeGetPage(pBt, 1, &pPage1, 0, 0);
|
||||
rc = btreeGetPage(pBt, 1, &pPage1, 0);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
|
||||
/* Do some checking to help insure the file we opened really is
|
||||
@@ -2963,7 +2962,7 @@ static int relocatePage(
|
||||
** iPtrPage.
|
||||
*/
|
||||
if( eType!=PTRMAP_ROOTPAGE ){
|
||||
rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0, 0);
|
||||
rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -3047,7 +3046,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){
|
||||
u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */
|
||||
Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */
|
||||
|
||||
rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0, 0);
|
||||
rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -3446,7 +3445,7 @@ int sqlite3BtreeRollback(Btree *p, int tripCode){
|
||||
/* The rollback may have destroyed the pPage1->aData value. So
|
||||
** call btreeGetPage() on page 1 again to make
|
||||
** sure pPage1->aData is set correctly. */
|
||||
if( btreeGetPage(pBt, 1, &pPage1, 0, 0)==SQLITE_OK ){
|
||||
if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
|
||||
int nPage = get4byte(28+(u8*)pPage1->aData);
|
||||
testcase( nPage==0 );
|
||||
if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
|
||||
@@ -3881,7 +3880,7 @@ static int getOverflowPage(
|
||||
|
||||
assert( next==0 || rc==SQLITE_DONE );
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = btreeGetPage(pBt, ovfl, &pPage, 0, (ppPage==0));
|
||||
rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? PAGER_GET_READONLY : 0);
|
||||
assert( rc==SQLITE_OK || pPage==0 );
|
||||
if( rc==SQLITE_OK ){
|
||||
next = get4byte(pPage->aData);
|
||||
@@ -4103,7 +4102,7 @@ static int accessPayload(
|
||||
{
|
||||
DbPage *pDbPage;
|
||||
rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
|
||||
(eOp==0 ? PAGER_ACQUIRE_READONLY : 0)
|
||||
(eOp==0 ? PAGER_GET_READONLY : 0)
|
||||
);
|
||||
if( rc==SQLITE_OK ){
|
||||
aPayload = sqlite3PagerGetData(pDbPage);
|
||||
@@ -4287,7 +4286,8 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
|
||||
if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
rc = getAndInitPage(pBt, newPgno, &pNewPage, (pCur->wrFlag==0));
|
||||
rc = getAndInitPage(pBt, newPgno, &pNewPage,
|
||||
pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
|
||||
if( rc ) return rc;
|
||||
pCur->apPage[i+1] = pNewPage;
|
||||
pCur->aiIdx[i+1] = 0;
|
||||
@@ -4404,7 +4404,8 @@ static int moveToRoot(BtCursor *pCur){
|
||||
pCur->eState = CURSOR_INVALID;
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], pCur->wrFlag==0);
|
||||
rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0],
|
||||
pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
pCur->eState = CURSOR_INVALID;
|
||||
return rc;
|
||||
@@ -5041,7 +5042,7 @@ static int allocateBtreePage(
|
||||
if( iTrunk>mxPage ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
|
||||
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
|
||||
}
|
||||
if( rc ){
|
||||
pTrunk = 0;
|
||||
@@ -5105,7 +5106,7 @@ static int allocateBtreePage(
|
||||
goto end_allocate_page;
|
||||
}
|
||||
testcase( iNewTrunk==mxPage );
|
||||
rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0, 0);
|
||||
rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto end_allocate_page;
|
||||
}
|
||||
@@ -5184,8 +5185,8 @@ static int allocateBtreePage(
|
||||
memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
|
||||
}
|
||||
put4byte(&aData[4], k-1);
|
||||
noContent = !btreeGetHasContent(pBt, *pPgno);
|
||||
rc = btreeGetPage(pBt, *pPgno, ppPage, noContent, 0);
|
||||
noContent = !btreeGetHasContent(pBt, *pPgno) ? PAGER_GET_NOCONTENT : 0;
|
||||
rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -5217,7 +5218,7 @@ static int allocateBtreePage(
|
||||
** here are confined to those pages that lie between the end of the
|
||||
** database image and the end of the database file.
|
||||
*/
|
||||
int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate));
|
||||
int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate)) ? PAGER_GET_NOCONTENT : 0;
|
||||
|
||||
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
|
||||
if( rc ) return rc;
|
||||
@@ -5233,7 +5234,7 @@ static int allocateBtreePage(
|
||||
MemPage *pPg = 0;
|
||||
TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
|
||||
assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
|
||||
rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent, 0);
|
||||
rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerWrite(pPg->pDbPage);
|
||||
releasePage(pPg);
|
||||
@@ -5247,7 +5248,7 @@ static int allocateBtreePage(
|
||||
*pPgno = pBt->nPage;
|
||||
|
||||
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
|
||||
rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent, 0);
|
||||
rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
|
||||
if( rc ) return rc;
|
||||
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -5315,7 +5316,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
/* If the secure_delete option is enabled, then
|
||||
** always fully overwrite deleted information with zeros.
|
||||
*/
|
||||
if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0, 0))!=0) )
|
||||
if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) )
|
||||
|| ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
|
||||
){
|
||||
goto freepage_out;
|
||||
@@ -5342,7 +5343,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
u32 nLeaf; /* Initial number of leaf cells on trunk page */
|
||||
|
||||
iTrunk = get4byte(&pPage1->aData[32]);
|
||||
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
|
||||
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto freepage_out;
|
||||
}
|
||||
@@ -5388,7 +5389,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
** first trunk in the free-list is full. Either way, the page being freed
|
||||
** will become the new first trunk page in the free-list.
|
||||
*/
|
||||
if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0, 0)) ){
|
||||
if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){
|
||||
goto freepage_out;
|
||||
}
|
||||
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||
@@ -7287,7 +7288,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
|
||||
}
|
||||
|
||||
/* Move the page currently at pgnoRoot to pgnoMove. */
|
||||
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
|
||||
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -7308,7 +7309,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
|
||||
rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -7486,7 +7487,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
|
||||
return SQLITE_LOCKED_SHAREDCACHE;
|
||||
}
|
||||
|
||||
rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0, 0);
|
||||
rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
|
||||
if( rc ) return rc;
|
||||
rc = sqlite3BtreeClearTable(p, iTable, 0);
|
||||
if( rc ){
|
||||
@@ -7521,7 +7522,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
|
||||
*/
|
||||
MemPage *pMove;
|
||||
releasePage(pPage);
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -7531,7 +7532,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
|
||||
return rc;
|
||||
}
|
||||
pMove = 0;
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
|
||||
rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
|
||||
freePage(pMove, &rc);
|
||||
releasePage(pMove);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -7746,7 +7747,7 @@ static void checkAppendMsg(
|
||||
}
|
||||
sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
|
||||
va_end(ap);
|
||||
if( pCheck->errMsg.mallocFailed ){
|
||||
if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
|
||||
pCheck->mallocFailed = 1;
|
||||
}
|
||||
}
|
||||
@@ -7943,7 +7944,7 @@ static int checkTreePage(
|
||||
usableSize = pBt->usableSize;
|
||||
if( iPage==0 ) return 0;
|
||||
if( checkRef(pCheck, iPage, zParentContext) ) return 0;
|
||||
if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0, 0))!=0 ){
|
||||
if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
|
||||
checkAppendMsg(pCheck, zContext,
|
||||
"unable to get the page. error code=%d", rc);
|
||||
return 0;
|
||||
|
@@ -114,8 +114,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
|
||||
p = p->pLeft;
|
||||
continue;
|
||||
}
|
||||
assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
|
||||
if( op==TK_COLLATE ){
|
||||
if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
|
||||
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
|
||||
break;
|
||||
}
|
||||
@@ -3505,6 +3504,7 @@ static void exprCodeBetween(
|
||||
compRight.pLeft = &exprX;
|
||||
compRight.pRight = pExpr->x.pList->a[1].pExpr;
|
||||
exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, ®Free1);
|
||||
exprX.op2 = exprX.op;
|
||||
exprX.op = TK_REGISTER;
|
||||
if( jumpIfTrue ){
|
||||
sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
|
||||
|
@@ -1522,9 +1522,9 @@ static void groupConcatFinalize(sqlite3_context *context){
|
||||
StrAccum *pAccum;
|
||||
pAccum = sqlite3_aggregate_context(context, 0);
|
||||
if( pAccum ){
|
||||
if( pAccum->tooBig ){
|
||||
if( pAccum->accError==STRACCUM_TOOBIG ){
|
||||
sqlite3_result_error_toobig(context);
|
||||
}else if( pAccum->mallocFailed ){
|
||||
}else if( pAccum->accError==STRACCUM_NOMEM ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
}else{
|
||||
sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,
|
||||
|
26
src/pager.c
26
src/pager.c
@@ -1022,13 +1022,17 @@ static char *print_pager_state(Pager *p){
|
||||
** PagerSavepoint.pInSavepoint.
|
||||
*/
|
||||
static int subjRequiresPage(PgHdr *pPg){
|
||||
Pgno pgno = pPg->pgno;
|
||||
Pager *pPager = pPg->pPager;
|
||||
PagerSavepoint *p;
|
||||
Pgno pgno;
|
||||
int i;
|
||||
for(i=0; i<pPager->nSavepoint; i++){
|
||||
PagerSavepoint *p = &pPager->aSavepoint[i];
|
||||
if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
|
||||
return 1;
|
||||
if( pPager->nSavepoint ){
|
||||
pgno = pPg->pgno;
|
||||
for(i=0; i<pPager->nSavepoint; i++){
|
||||
p = &pPager->aSavepoint[i];
|
||||
if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -2874,12 +2878,6 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
|
||||
assert( pPager->eState>=PAGER_READER && !MEMDB );
|
||||
assert( isOpen(pPager->fd) );
|
||||
|
||||
if( NEVER(!isOpen(pPager->fd)) ){
|
||||
assert( pPager->tempFile );
|
||||
memset(pPg->pData, 0, pPager->pageSize);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
if( iFrame ){
|
||||
/* Try to pull the page from the write-ahead log. */
|
||||
@@ -5233,19 +5231,19 @@ int sqlite3PagerAcquire(
|
||||
Pager *pPager, /* The pager open on the database file */
|
||||
Pgno pgno, /* Page number to fetch */
|
||||
DbPage **ppPage, /* Write a pointer to the page here */
|
||||
int flags /* PAGER_ACQUIRE_XXX flags */
|
||||
int flags /* PAGER_GET_XXX flags */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
PgHdr *pPg = 0;
|
||||
u32 iFrame = 0; /* Frame to read from WAL file */
|
||||
const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT);
|
||||
const int noContent = (flags & PAGER_GET_NOCONTENT);
|
||||
|
||||
/* It is acceptable to use a read-only (mmap) page for any page except
|
||||
** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
|
||||
** flag was specified by the caller. And so long as the db is not a
|
||||
** temporary or in-memory database. */
|
||||
const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
|
||||
&& (pPager->eState==PAGER_READER || (flags & PAGER_ACQUIRE_READONLY))
|
||||
&& (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
&& pPager->xCodec==0
|
||||
#endif
|
||||
|
@@ -81,8 +81,8 @@ typedef struct PgHdr DbPage;
|
||||
/*
|
||||
** Flags that make up the mask passed to sqlite3PagerAcquire().
|
||||
*/
|
||||
#define PAGER_ACQUIRE_NOCONTENT 0x01 /* Do not load data from disk */
|
||||
#define PAGER_ACQUIRE_READONLY 0x02 /* Read-only page is acceptable */
|
||||
#define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */
|
||||
#define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */
|
||||
|
||||
/*
|
||||
** Flags for sqlite3PagerSetFlags()
|
||||
|
31
src/printf.c
31
src/printf.c
@@ -359,7 +359,7 @@ void sqlite3VXPrintf(
|
||||
nOut = precision + 10;
|
||||
zOut = zExtra = sqlite3Malloc( nOut );
|
||||
if( zOut==0 ){
|
||||
pAccum->mallocFailed = 1;
|
||||
pAccum->accError = STRACCUM_NOMEM;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -471,7 +471,7 @@ void sqlite3VXPrintf(
|
||||
if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
|
||||
bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
|
||||
if( bufpt==0 ){
|
||||
pAccum->mallocFailed = 1;
|
||||
pAccum->accError = STRACCUM_NOMEM;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -606,7 +606,7 @@ void sqlite3VXPrintf(
|
||||
if( n>etBUFSIZE ){
|
||||
bufpt = zExtra = sqlite3Malloc( n );
|
||||
if( bufpt==0 ){
|
||||
pAccum->mallocFailed = 1;
|
||||
pAccum->accError = STRACCUM_NOMEM;
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
@@ -684,22 +684,20 @@ void sqlite3VXPrintf(
|
||||
*/
|
||||
void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
|
||||
assert( z!=0 || N==0 );
|
||||
if( p->tooBig | p->mallocFailed ){
|
||||
testcase(p->tooBig);
|
||||
testcase(p->mallocFailed);
|
||||
if( p->accError ){
|
||||
testcase(p->accError==STRACCUM_TOOBIG);
|
||||
testcase(p->accError==STRACCUM_NOMEM);
|
||||
return;
|
||||
}
|
||||
assert( p->zText!=0 || p->nChar==0 );
|
||||
if( N<0 ){
|
||||
if( N<=0 ){
|
||||
if( N==0 || z[0]==0 ) return;
|
||||
N = sqlite3Strlen30(z);
|
||||
}
|
||||
if( N==0 || NEVER(z==0) ){
|
||||
return;
|
||||
}
|
||||
if( p->nChar+N >= p->nAlloc ){
|
||||
char *zNew;
|
||||
if( !p->useMalloc ){
|
||||
p->tooBig = 1;
|
||||
p->accError = STRACCUM_TOOBIG;
|
||||
N = p->nAlloc - p->nChar - 1;
|
||||
if( N<=0 ){
|
||||
return;
|
||||
@@ -710,7 +708,7 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
|
||||
szNew += N + 1;
|
||||
if( szNew > p->mxAlloc ){
|
||||
sqlite3StrAccumReset(p);
|
||||
p->tooBig = 1;
|
||||
p->accError = STRACCUM_TOOBIG;
|
||||
return;
|
||||
}else{
|
||||
p->nAlloc = (int)szNew;
|
||||
@@ -724,7 +722,7 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
|
||||
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
|
||||
p->zText = zNew;
|
||||
}else{
|
||||
p->mallocFailed = 1;
|
||||
p->accError = STRACCUM_NOMEM;
|
||||
sqlite3StrAccumReset(p);
|
||||
return;
|
||||
}
|
||||
@@ -752,7 +750,7 @@ char *sqlite3StrAccumFinish(StrAccum *p){
|
||||
if( p->zText ){
|
||||
memcpy(p->zText, p->zBase, p->nChar+1);
|
||||
}else{
|
||||
p->mallocFailed = 1;
|
||||
p->accError = STRACCUM_NOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -783,8 +781,7 @@ void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
|
||||
p->nAlloc = n;
|
||||
p->mxAlloc = mx;
|
||||
p->useMalloc = 1;
|
||||
p->tooBig = 0;
|
||||
p->mallocFailed = 0;
|
||||
p->accError = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -801,7 +798,7 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
|
||||
acc.db = db;
|
||||
sqlite3VXPrintf(&acc, 1, zFormat, ap);
|
||||
z = sqlite3StrAccumFinish(&acc);
|
||||
if( acc.mallocFailed ){
|
||||
if( acc.accError==STRACCUM_NOMEM ){
|
||||
db->mallocFailed = 1;
|
||||
}
|
||||
return z;
|
||||
|
51
src/random.c
51
src/random.c
@@ -28,24 +28,11 @@ static SQLITE_WSD struct sqlite3PrngType {
|
||||
} sqlite3Prng;
|
||||
|
||||
/*
|
||||
** Get a single 8-bit random value from the RC4 PRNG. The Mutex
|
||||
** must be held while executing this routine.
|
||||
**
|
||||
** Why not just use a library random generator like lrand48() for this?
|
||||
** Because the OP_NewRowid opcode in the VDBE depends on having a very
|
||||
** good source of random numbers. The lrand48() library function may
|
||||
** well be good enough. But maybe not. Or maybe lrand48() has some
|
||||
** subtle problems on some systems that could cause problems. It is hard
|
||||
** to know. To minimize the risk of problems due to bad lrand48()
|
||||
** implementations, SQLite uses this random number generator based
|
||||
** on RC4, which we know works very well.
|
||||
**
|
||||
** (Later): Actually, OP_NewRowid does not depend on a good source of
|
||||
** randomness any more. But we will leave this code in all the same.
|
||||
** Return N random bytes.
|
||||
*/
|
||||
static u8 randomByte(void){
|
||||
void sqlite3_randomness(int N, void *pBuf){
|
||||
unsigned char t;
|
||||
|
||||
unsigned char *zBuf = pBuf;
|
||||
|
||||
/* The "wsdPrng" macro will resolve to the pseudo-random number generator
|
||||
** state vector. If writable static data is unsupported on the target,
|
||||
@@ -60,6 +47,10 @@ static u8 randomByte(void){
|
||||
# define wsdPrng sqlite3Prng
|
||||
#endif
|
||||
|
||||
#if SQLITE_THREADSAFE
|
||||
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
|
||||
sqlite3_mutex_enter(mutex);
|
||||
#endif
|
||||
|
||||
/* Initialize the state of the random number generator once,
|
||||
** the first time this routine is called. The seed value does
|
||||
@@ -88,28 +79,14 @@ static u8 randomByte(void){
|
||||
wsdPrng.isInit = 1;
|
||||
}
|
||||
|
||||
/* Generate and return single random byte
|
||||
*/
|
||||
wsdPrng.i++;
|
||||
t = wsdPrng.s[wsdPrng.i];
|
||||
wsdPrng.j += t;
|
||||
wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
|
||||
wsdPrng.s[wsdPrng.j] = t;
|
||||
t += wsdPrng.s[wsdPrng.i];
|
||||
return wsdPrng.s[t];
|
||||
}
|
||||
|
||||
/*
|
||||
** Return N random bytes.
|
||||
*/
|
||||
void sqlite3_randomness(int N, void *pBuf){
|
||||
unsigned char *zBuf = pBuf;
|
||||
#if SQLITE_THREADSAFE
|
||||
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
|
||||
#endif
|
||||
sqlite3_mutex_enter(mutex);
|
||||
while( N-- ){
|
||||
*(zBuf++) = randomByte();
|
||||
wsdPrng.i++;
|
||||
t = wsdPrng.s[wsdPrng.i];
|
||||
wsdPrng.j += t;
|
||||
wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
|
||||
wsdPrng.s[wsdPrng.j] = t;
|
||||
t += wsdPrng.s[wsdPrng.i];
|
||||
*(zBuf++) = wsdPrng.s[t];
|
||||
}
|
||||
sqlite3_mutex_leave(mutex);
|
||||
}
|
||||
|
@@ -2437,10 +2437,11 @@ struct StrAccum {
|
||||
int nChar; /* Length of the string so far */
|
||||
int nAlloc; /* Amount of space allocated in zText */
|
||||
int mxAlloc; /* Maximum allowed string length */
|
||||
u8 mallocFailed; /* Becomes true if any memory allocation fails */
|
||||
u8 useMalloc; /* 0: none, 1: sqlite3DbMalloc, 2: sqlite3_malloc */
|
||||
u8 tooBig; /* Becomes true if string size exceeds limits */
|
||||
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
|
||||
};
|
||||
#define STRACCUM_NOMEM 1
|
||||
#define STRACCUM_TOOBIG 2
|
||||
|
||||
/*
|
||||
** A pointer to this structure is used to communicate information
|
||||
@@ -3165,13 +3166,14 @@ void sqlite3AutoLoadExtensions(sqlite3*);
|
||||
#else
|
||||
void sqlite3VtabClear(sqlite3 *db, Table*);
|
||||
void sqlite3VtabDisconnect(sqlite3 *db, Table *p);
|
||||
int sqlite3VtabSync(sqlite3 *db, char **);
|
||||
int sqlite3VtabSync(sqlite3 *db, Vdbe*);
|
||||
int sqlite3VtabRollback(sqlite3 *db);
|
||||
int sqlite3VtabCommit(sqlite3 *db);
|
||||
void sqlite3VtabLock(VTable *);
|
||||
void sqlite3VtabUnlock(VTable *);
|
||||
void sqlite3VtabUnlockList(sqlite3*);
|
||||
int sqlite3VtabSavepoint(sqlite3 *, int, int);
|
||||
void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
|
||||
VTable *sqlite3GetVTable(sqlite3*, Table*);
|
||||
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
|
||||
#endif
|
||||
|
29
src/vdbe.c
29
src/vdbe.c
@@ -507,19 +507,6 @@ static int checkSavepointCount(sqlite3 *db){
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
|
||||
** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
|
||||
** in memory obtained from sqlite3DbMalloc).
|
||||
*/
|
||||
static void importVtabErrMsg(Vdbe *p, sqlite3_vtab *pVtab){
|
||||
sqlite3 *db = p->db;
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
|
||||
sqlite3_free(pVtab->zErrMsg);
|
||||
pVtab->zErrMsg = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Execute as much of a VDBE program as we can then return.
|
||||
@@ -4402,7 +4389,7 @@ case OP_Rowid: { /* out2-prerelease */
|
||||
pModule = pVtab->pModule;
|
||||
assert( pModule->xRowid );
|
||||
rc = pModule->xRowid(pC->pVtabCursor, &v);
|
||||
importVtabErrMsg(p, pVtab);
|
||||
sqlite3VtabImportErrmsg(p, pVtab);
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
}else{
|
||||
assert( pC->pCursor!=0 );
|
||||
@@ -5795,7 +5782,7 @@ case OP_VBegin: {
|
||||
VTable *pVTab;
|
||||
pVTab = pOp->p4.pVtab;
|
||||
rc = sqlite3VtabBegin(db, pVTab);
|
||||
if( pVTab ) importVtabErrMsg(p, pVTab->pVtab);
|
||||
if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
|
||||
break;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
@@ -5846,7 +5833,7 @@ case OP_VOpen: {
|
||||
pModule = (sqlite3_module *)pVtab->pModule;
|
||||
assert(pVtab && pModule);
|
||||
rc = pModule->xOpen(pVtab, &pVtabCursor);
|
||||
importVtabErrMsg(p, pVtab);
|
||||
sqlite3VtabImportErrmsg(p, pVtab);
|
||||
if( SQLITE_OK==rc ){
|
||||
/* Initialize sqlite3_vtab_cursor base class */
|
||||
pVtabCursor->pVtab = pVtab;
|
||||
@@ -5924,7 +5911,7 @@ case OP_VFilter: { /* jump */
|
||||
p->inVtabMethod = 1;
|
||||
rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
|
||||
p->inVtabMethod = 0;
|
||||
importVtabErrMsg(p, pVtab);
|
||||
sqlite3VtabImportErrmsg(p, pVtab);
|
||||
if( rc==SQLITE_OK ){
|
||||
res = pModule->xEof(pVtabCursor);
|
||||
}
|
||||
@@ -5975,7 +5962,7 @@ case OP_VColumn: {
|
||||
MemSetTypeFlag(&sContext.s, MEM_Null);
|
||||
|
||||
rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
|
||||
importVtabErrMsg(p, pVtab);
|
||||
sqlite3VtabImportErrmsg(p, pVtab);
|
||||
if( sContext.isError ){
|
||||
rc = sContext.isError;
|
||||
}
|
||||
@@ -6028,7 +6015,7 @@ case OP_VNext: { /* jump */
|
||||
p->inVtabMethod = 1;
|
||||
rc = pModule->xNext(pCur->pVtabCursor);
|
||||
p->inVtabMethod = 0;
|
||||
importVtabErrMsg(p, pVtab);
|
||||
sqlite3VtabImportErrmsg(p, pVtab);
|
||||
if( rc==SQLITE_OK ){
|
||||
res = pModule->xEof(pCur->pVtabCursor);
|
||||
}
|
||||
@@ -6065,7 +6052,7 @@ case OP_VRename: {
|
||||
rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = pVtab->pModule->xRename(pVtab, pName->z);
|
||||
importVtabErrMsg(p, pVtab);
|
||||
sqlite3VtabImportErrmsg(p, pVtab);
|
||||
p->expired = 0;
|
||||
}
|
||||
break;
|
||||
@@ -6127,7 +6114,7 @@ case OP_VUpdate: {
|
||||
db->vtabOnConflict = pOp->p5;
|
||||
rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
|
||||
db->vtabOnConflict = vtabOnConflict;
|
||||
importVtabErrMsg(p, pVtab);
|
||||
sqlite3VtabImportErrmsg(p, pVtab);
|
||||
if( rc==SQLITE_OK && pOp->p1 ){
|
||||
assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
|
||||
db->lastRowid = lastRowid = rowid;
|
||||
|
@@ -1766,7 +1766,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
|
||||
** required, as an xSync() callback may add an attached database
|
||||
** to the transaction.
|
||||
*/
|
||||
rc = sqlite3VtabSync(db, &p->zErrMsg);
|
||||
rc = sqlite3VtabSync(db, p);
|
||||
|
||||
/* This loop determines (a) if the commit hook should be invoked and
|
||||
** (b) how many database files have open write transactions, not
|
||||
@@ -3307,6 +3307,21 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/*
|
||||
** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
|
||||
** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
|
||||
** in memory obtained from sqlite3DbMalloc).
|
||||
*/
|
||||
void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){
|
||||
sqlite3 *db = p->db;
|
||||
sqlite3DbFree(db, p->zErrMsg);
|
||||
p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
|
||||
sqlite3_free(pVtab->zErrMsg);
|
||||
pVtab->zErrMsg = 0;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
|
||||
/*
|
||||
|
@@ -799,34 +799,29 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
|
||||
** if both values are integers.
|
||||
*/
|
||||
if( combined_flags&(MEM_Int|MEM_Real) ){
|
||||
if( !(f1&(MEM_Int|MEM_Real)) ){
|
||||
return 1;
|
||||
}
|
||||
if( !(f2&(MEM_Int|MEM_Real)) ){
|
||||
return -1;
|
||||
}
|
||||
if( (f1 & f2 & MEM_Int)==0 ){
|
||||
double r1, r2;
|
||||
if( (f1&MEM_Real)==0 ){
|
||||
r1 = (double)pMem1->u.i;
|
||||
}else{
|
||||
r1 = pMem1->r;
|
||||
}
|
||||
if( (f2&MEM_Real)==0 ){
|
||||
r2 = (double)pMem2->u.i;
|
||||
}else{
|
||||
r2 = pMem2->r;
|
||||
}
|
||||
if( r1<r2 ) return -1;
|
||||
if( r1>r2 ) return 1;
|
||||
return 0;
|
||||
}else{
|
||||
assert( f1&MEM_Int );
|
||||
assert( f2&MEM_Int );
|
||||
double r1, r2;
|
||||
if( (f1 & f2 & MEM_Int)!=0 ){
|
||||
if( pMem1->u.i < pMem2->u.i ) return -1;
|
||||
if( pMem1->u.i > pMem2->u.i ) return 1;
|
||||
return 0;
|
||||
}
|
||||
if( (f1&MEM_Real)!=0 ){
|
||||
r1 = pMem1->r;
|
||||
}else if( (f1&MEM_Int)!=0 ){
|
||||
r1 = (double)pMem1->u.i;
|
||||
}else{
|
||||
return 1;
|
||||
}
|
||||
if( (f2&MEM_Real)!=0 ){
|
||||
r2 = pMem2->r;
|
||||
}else if( (f2&MEM_Int)!=0 ){
|
||||
r2 = (double)pMem2->u.i;
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
if( r1<r2 ) return -1;
|
||||
if( r1>r2 ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If one value is a string and the other is a blob, the string is less.
|
||||
|
@@ -810,10 +810,9 @@ static void callFinaliser(sqlite3 *db, int offset){
|
||||
** array. Return the error code for the first error that occurs, or
|
||||
** SQLITE_OK if all xSync operations are successful.
|
||||
**
|
||||
** Set *pzErrmsg to point to a buffer that should be released using
|
||||
** sqlite3DbFree() containing an error message, if one is available.
|
||||
** If an error message is available, leave it in p->zErrMsg.
|
||||
*/
|
||||
int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
|
||||
int sqlite3VtabSync(sqlite3 *db, Vdbe *p){
|
||||
int i;
|
||||
int rc = SQLITE_OK;
|
||||
VTable **aVTrans = db->aVTrans;
|
||||
@@ -824,9 +823,7 @@ int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
|
||||
sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
|
||||
if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
|
||||
rc = x(pVtab);
|
||||
sqlite3DbFree(db, *pzErrmsg);
|
||||
*pzErrmsg = pVtab->zErrMsg;
|
||||
pVtab->zErrMsg = 0;
|
||||
sqlite3VtabImportErrmsg(p, pVtab);
|
||||
}
|
||||
}
|
||||
db->aVTrans = aVTrans;
|
||||
|
30
src/where.c
30
src/where.c
@@ -90,6 +90,7 @@ struct WhereLevel {
|
||||
int addrNxt; /* Jump here to start the next IN combination */
|
||||
int addrCont; /* Jump here to continue with the next loop cycle */
|
||||
int addrFirst; /* First instruction of interior of the loop */
|
||||
int addrBody; /* Beginning of the body of this loop */
|
||||
u8 iFrom; /* Which entry in the FROM clause */
|
||||
u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */
|
||||
int p1, p2; /* Operands of the opcode used to ends the loop */
|
||||
@@ -3029,7 +3030,7 @@ static int codeAllEqualityTerms(
|
||||
|
||||
/* Evaluate the equality constraints
|
||||
*/
|
||||
assert( pIdx->nColumn>=nEq );
|
||||
assert( zAff==0 || strlen(zAff)>=nEq );
|
||||
for(j=0; j<nEq; j++){
|
||||
int r1;
|
||||
pTerm = pLoop->aLTerm[j];
|
||||
@@ -3121,7 +3122,8 @@ static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
|
||||
txt.db = db;
|
||||
sqlite3StrAccumAppend(&txt, " (", 2);
|
||||
for(i=0; i<nEq; i++){
|
||||
explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "=");
|
||||
char *z = (i==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[i]].zName;
|
||||
explainAppendTerm(&txt, i, z, "=");
|
||||
}
|
||||
|
||||
j = i;
|
||||
@@ -4336,13 +4338,11 @@ static int whereLoopAddBtreeIndex(
|
||||
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
|
||||
int nIn = 0;
|
||||
if( pTerm->prereqRight & pNew->maskSelf ) continue;
|
||||
#ifdef SQLITE_ENABLE_STAT3
|
||||
if( (pTerm->wtFlags & TERM_VNULL)!=0
|
||||
if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
|
||||
&& (iCol<0 || pSrc->pTab->aCol[iCol].notNull)
|
||||
){
|
||||
continue; /* skip IS NOT NULL constraints on a NOT NULL column */
|
||||
continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */
|
||||
}
|
||||
#endif
|
||||
pNew->wsFlags = saved_wsFlags;
|
||||
pNew->u.btree.nEq = saved_nEq;
|
||||
pNew->nLTerm = saved_nLTerm;
|
||||
@@ -5985,11 +5985,6 @@ WhereInfo *sqlite3WhereBegin(
|
||||
}else{
|
||||
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
|
||||
if( (pLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
|
||||
constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel);
|
||||
}else
|
||||
#endif
|
||||
if( pLoop->wsFlags & WHERE_INDEXED ){
|
||||
Index *pIx = pLoop->u.btree.pIndex;
|
||||
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
|
||||
@@ -6014,7 +6009,15 @@ WhereInfo *sqlite3WhereBegin(
|
||||
notReady = ~(Bitmask)0;
|
||||
for(ii=0; ii<nTabList; ii++){
|
||||
pLevel = &pWInfo->a[ii];
|
||||
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
|
||||
if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
|
||||
constructAutomaticIndex(pParse, &pWInfo->sWC,
|
||||
&pTabList->a[pLevel->iFrom], notReady, pLevel);
|
||||
if( db->mallocFailed ) goto whereBeginError;
|
||||
}
|
||||
#endif
|
||||
explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
|
||||
pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
|
||||
notReady = codeOneLoopStart(pWInfo, ii, notReady);
|
||||
pWInfo->iContinue = pLevel->addrCont;
|
||||
}
|
||||
@@ -6134,9 +6137,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
int k, j, last;
|
||||
VdbeOp *pOp;
|
||||
|
||||
pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
|
||||
last = sqlite3VdbeCurrentAddr(v);
|
||||
for(k=pWInfo->iTop; k<last; k++, pOp++){
|
||||
k = pLevel->addrBody;
|
||||
pOp = sqlite3VdbeGetOp(v, k);
|
||||
for(; k<last; k++, pOp++){
|
||||
if( pOp->p1!=pLevel->iTabCur ) continue;
|
||||
if( pOp->opcode==OP_Column ){
|
||||
for(j=0; j<pIdx->nColumn; j++){
|
||||
|
@@ -17,6 +17,8 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
set ::testprefix collate2
|
||||
|
||||
#
|
||||
# Tests are organised as follows:
|
||||
#
|
||||
@@ -693,4 +695,30 @@ do_test collate2-5.5 {
|
||||
}
|
||||
} {aa aa}
|
||||
|
||||
do_execsql_test 6.1 {
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES('b');
|
||||
INSERT INTO t1 VALUES('B');
|
||||
}
|
||||
do_execsql_test 6.2 {
|
||||
SELECT * FROM t1 WHERE x COLLATE nocase BETWEEN 'a' AND 'c';
|
||||
} {b B}
|
||||
do_execsql_test 6.3 {
|
||||
SELECT * FROM t1 WHERE x BETWEEN 'a' COLLATE nocase AND 'c' COLLATE nocase;
|
||||
} {b B}
|
||||
do_execsql_test 6.4 {
|
||||
SELECT * FROM t1
|
||||
WHERE x COLLATE nocase BETWEEN 'a' COLLATE nocase AND 'c' COLLATE nocase;
|
||||
} {b B}
|
||||
do_execsql_test 6.5 {
|
||||
SELECT * FROM t1 WHERE +x COLLATE nocase BETWEEN 'a' AND 'c';
|
||||
} {b B}
|
||||
do_execsql_test 6.6 {
|
||||
SELECT * FROM t1 WHERE +x BETWEEN 'a' COLLATE nocase AND 'c' COLLATE nocase;
|
||||
} {b B}
|
||||
do_execsql_test 6.7 {
|
||||
SELECT * FROM t1
|
||||
WHERE +x COLLATE nocase BETWEEN 'a' COLLATE nocase AND 'c' COLLATE nocase;
|
||||
} {b B}
|
||||
|
||||
finish_test
|
||||
|
@@ -31,9 +31,11 @@ do_execsql_test 1.1 {
|
||||
CREATE INDEX t1abc ON t1(a,b,c);
|
||||
}
|
||||
|
||||
set idxroot [db one {SELECT rootpage FROM sqlite_master WHERE name = 't1abc'}]
|
||||
|
||||
# Corrupt the file
|
||||
db close
|
||||
hexio_write test.db [expr {3*512 - 15}] 888080807f
|
||||
hexio_write test.db [expr {$idxroot*512 - 15}] 888080807f
|
||||
sqlite3 db test.db
|
||||
|
||||
# Try to use the file.
|
||||
@@ -58,7 +60,7 @@ do_test 1.4 {
|
||||
# such that the payload begins in allocated space but overflows the buffer.
|
||||
#
|
||||
db close
|
||||
hexio_write test.db [expr {3*512-15}] 0513ff7f01
|
||||
hexio_write test.db [expr {$idxroot*512-15}] 0513ff7f01
|
||||
sqlite3 db test.db
|
||||
|
||||
do_test 2.1 {
|
||||
|
@@ -16,6 +16,11 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !vtab {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
load_static_extension db wholenumber;
|
||||
do_test index6-1.1 {
|
||||
# Able to parse and manage partial indices
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix indexedby
|
||||
|
||||
# Create a schema with some indexes.
|
||||
#
|
||||
@@ -274,4 +275,50 @@ do_test indexedby-10.3 {
|
||||
}
|
||||
} {1}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Ensure that the rowid at the end of each index entry may be used
|
||||
# for equality constraints in the same way as other indexed fields.
|
||||
#
|
||||
do_execsql_test 11.1 {
|
||||
CREATE TABLE x1(a, b TEXT);
|
||||
CREATE INDEX x1i ON x1(a, b);
|
||||
INSERT INTO x1 VALUES(1, 1);
|
||||
INSERT INTO x1 VALUES(1, 1);
|
||||
INSERT INTO x1 VALUES(1, 1);
|
||||
INSERT INTO x1 VALUES(1, 1);
|
||||
}
|
||||
do_execsql_test 11.2 {
|
||||
SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid=3;
|
||||
} {1 1 3}
|
||||
do_execsql_test 11.3 {
|
||||
SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid='3';
|
||||
} {1 1 3}
|
||||
do_execsql_test 11.4 {
|
||||
SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid='3.0';
|
||||
} {1 1 3}
|
||||
do_eqp_test 11.5 {
|
||||
SELECT a,b,rowid FROM x1 INDEXED BY x1i WHERE a=1 AND b=1 AND rowid='3.0';
|
||||
} {0 0 0 {SEARCH TABLE x1 USING COVERING INDEX x1i (a=? AND b=? AND rowid=?)}}
|
||||
|
||||
do_execsql_test 11.6 {
|
||||
CREATE TABLE x2(c INTEGER PRIMARY KEY, a, b TEXT);
|
||||
CREATE INDEX x2i ON x2(a, b);
|
||||
INSERT INTO x2 VALUES(1, 1, 1);
|
||||
INSERT INTO x2 VALUES(2, 1, 1);
|
||||
INSERT INTO x2 VALUES(3, 1, 1);
|
||||
INSERT INTO x2 VALUES(4, 1, 1);
|
||||
}
|
||||
do_execsql_test 11.7 {
|
||||
SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c=3;
|
||||
} {1 1 3}
|
||||
do_execsql_test 11.8 {
|
||||
SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3';
|
||||
} {1 1 3}
|
||||
do_execsql_test 11.9 {
|
||||
SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3.0';
|
||||
} {1 1 3}
|
||||
do_eqp_test 11.10 {
|
||||
SELECT a,b,c FROM x2 INDEXED BY x2i WHERE a=1 AND b=1 AND c='3.0';
|
||||
} {0 0 0 {SEARCH TABLE x2 USING COVERING INDEX x2i (a=? AND b=? AND rowid=?)}}
|
||||
|
||||
finish_test
|
||||
|
@@ -205,6 +205,7 @@ do_test malloc5-4.1 {
|
||||
execsql "INSERT INTO abc VALUES($i, $i, '[string repeat X 100]');"
|
||||
}
|
||||
execsql {COMMIT;}
|
||||
db cache flush
|
||||
sqlite3_release_memory
|
||||
sqlite3_memory_highwater 1
|
||||
execsql {SELECT * FROM abc}
|
||||
@@ -213,6 +214,7 @@ do_test malloc5-4.1 {
|
||||
expr $nMaxBytes > 1000000
|
||||
} {1}
|
||||
do_test malloc5-4.2 {
|
||||
db cache flush
|
||||
sqlite3_release_memory
|
||||
sqlite3_soft_heap_limit 100000
|
||||
sqlite3_memory_highwater 1
|
||||
|
@@ -93,6 +93,14 @@ set FAULTSIM(cantopen-persistent) [list \
|
||||
-injectuninstall cantopen_injectuninstall \
|
||||
]
|
||||
|
||||
set FAULTSIM(interrupt) [list \
|
||||
-injectinstall interrupt_injectinstall \
|
||||
-injectstart interrupt_injectstart \
|
||||
-injectstop interrupt_injectstop \
|
||||
-injecterrlist {{1 interrupted} {1 interrupt}} \
|
||||
-injectuninstall interrupt_injectuninstall \
|
||||
]
|
||||
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
@@ -113,7 +121,9 @@ set FAULTSIM(cantopen-persistent) [list \
|
||||
proc do_faultsim_test {name args} {
|
||||
global FAULTSIM
|
||||
|
||||
set DEFAULT(-faults) [array names FAULTSIM]
|
||||
foreach n [array names FAULTSIM] {
|
||||
if {$n != "interrupt"} {lappend DEFAULT(-faults) $n}
|
||||
}
|
||||
set DEFAULT(-prep) ""
|
||||
set DEFAULT(-body) ""
|
||||
set DEFAULT(-test) ""
|
||||
@@ -255,6 +265,22 @@ proc cantopen_injectstop {} {
|
||||
shmfault cantopen
|
||||
}
|
||||
|
||||
# The following procs are used as [do_one_faultsim_test] callbacks
|
||||
# when injecting SQLITE_INTERRUPT error faults into test cases.
|
||||
#
|
||||
proc interrupt_injectinstall {} {
|
||||
}
|
||||
proc interrupt_injectuninstall {} {
|
||||
}
|
||||
proc interrupt_injectstart {iFail} {
|
||||
set ::sqlite_interrupt_count $iFail
|
||||
}
|
||||
proc interrupt_injectstop {} {
|
||||
set res [expr $::sqlite_interrupt_count<=0]
|
||||
set ::sqlite_interrupt_count 0
|
||||
set res
|
||||
}
|
||||
|
||||
# This command is not called directly. It is used by the
|
||||
# [faultsim_test_result] command created by [do_faultsim_test] and used
|
||||
# by -test scripts.
|
||||
|
@@ -164,10 +164,12 @@ do_test progress-1.7 {
|
||||
}
|
||||
|
||||
set ::res [list]
|
||||
explain {SELECT a, b, c FROM abc}
|
||||
db eval {SELECT a, b, c FROM abc} {
|
||||
lappend ::res $a $b $c
|
||||
db progress 5 "expr 1"
|
||||
catch {db eval {SELECT a, b, c FROM abc} { }} msg
|
||||
db progress 5 "expr 0"
|
||||
lappend ::res $msg
|
||||
}
|
||||
|
||||
|
@@ -701,6 +701,7 @@ do_test where2-11.4 {
|
||||
|
||||
# Verify that the OR clause is used in an outer loop even when
|
||||
# the OR clause scores slightly better on an inner loop.
|
||||
if {[permutation] != "no_optimization"} {
|
||||
do_execsql_test where2-12.1 {
|
||||
CREATE TABLE t12(x INTEGER PRIMARY KEY, y);
|
||||
CREATE INDEX t12y ON t12(y);
|
||||
@@ -709,6 +710,7 @@ do_execsql_test where2-12.1 {
|
||||
FROM t12 AS a JOIN t12 AS b ON a.y=b.x
|
||||
WHERE (b.x=$abc OR b.y=$abc);
|
||||
} {/.*SEARCH TABLE t12 AS b .*SEARCH TABLE t12 AS b .*/}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
@@ -246,6 +246,12 @@ do_execsql_test where3-3.1 {
|
||||
0 0 1 {SCAN TABLE t302}
|
||||
0 1 0 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)}
|
||||
}
|
||||
do_execsql_test where3-3.2 {
|
||||
SELECT * FROM t301 WHERE c=3 AND a IS NULL;
|
||||
} {}
|
||||
do_execsql_test where3-3.3 {
|
||||
SELECT * FROM t301 WHERE c=3 AND a IS NOT NULL;
|
||||
} {1 2 3}
|
||||
|
||||
if 0 { # Query planner no longer does this
|
||||
# Verify that when there are multiple tables in a join which must be
|
||||
|
@@ -68,6 +68,12 @@ do_test whereA-1.7 {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {3 4.53 {} 2 hello world 1 2 3}
|
||||
do_execsql_test whereA-1.8 {
|
||||
SELECT * FROM t1 WHERE b=2 AND a IS NULL;
|
||||
} {}
|
||||
do_execsql_test whereA-1.9 {
|
||||
SELECT * FROM t1 WHERE b=2 AND a IS NOT NULL;
|
||||
} {1 2 3}
|
||||
|
||||
do_test whereA-2.1 {
|
||||
db eval {
|
||||
|
Reference in New Issue
Block a user