mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Merge all recent fixes and enhancements from trunk into sessions.
FossilOrigin-Name: 2617d93713d9f4cf907ab2e7baef6a0f74f7198e
This commit is contained in:
62
manifest
62
manifest
@@ -1,5 +1,5 @@
|
||||
C Merge\srecent\strunk\senhancements,\sincluding\sthe\sread-after-ROLLBACK\schange\nand\sthe\saddition\sof\ssqlite3_stmt_scanstatus()\ssupport,\sas\swell\sas\svarious\nminor\sbug\sfixes.
|
||||
D 2014-11-18T21:20:57.012
|
||||
C Merge\sall\srecent\sfixes\sand\senhancements\sfrom\strunk\sinto\ssessions.
|
||||
D 2014-12-02T16:31:01.447
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in e2007fafb7b679a39800a1d636dcc6662a840530
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -184,13 +184,13 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb
|
||||
F src/analyze.c afbcca663c3f3625340b8e30d440cd7a97ded6bc
|
||||
F src/analyze.c f7d774356ba5a14e7ad4fb637681af16875ad88f
|
||||
F src/attach.c f4e94df2d1826feda65eb0939f7f6f5f923a0ad9
|
||||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
|
||||
F src/btree.c b562da29eb370aaac8015026827c2e2fb70ae990
|
||||
F src/btree.c 44b58cd798a32579816ce274e415de262df9843d
|
||||
F src/btree.h e31a3a3ebdedb1caf9bda3ad5dbab3db9b780f6e
|
||||
F src/btreeInt.h 3363e18fd76f69a27a870b25221b2345b3fd4d21
|
||||
F src/build.c 67bb05b1077e0cdaccb2e36bfcbe7a5df9ed31e8
|
||||
@@ -199,10 +199,10 @@ F src/complete.c c4ba6e0626bb94bc77a0861735f3382fcf7cc818
|
||||
F src/ctime.c df19848891c8a553c80e6f5a035e768280952d1a
|
||||
F src/date.c 93594514aae68de117ca4a2a0d6cc63eddf26744
|
||||
F src/delete.c 20a360262b62051afacb44122b3593a8bd9be131
|
||||
F src/expr.c a3ff05db5709d628c23890db862e30f3dd9dc428
|
||||
F src/expr.c 73de4c0da2eed6b149d40a05c589dfeb2c4a87a1
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7
|
||||
F src/func.c ba47c1671ab3cfdafa6e9d6ee490939ea578adee
|
||||
F src/func.c 6d3c4ebd72aa7923ce9b110a7dc15f9b8c548430
|
||||
F src/global.c 6ded36dda9466fc1c9a3c5492ded81d79bf3977d
|
||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||
@@ -212,7 +212,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
|
||||
F src/loadext.c de741e66e5ddc1598d904d7289239696e40ed994
|
||||
F src/main.c 46e2f592797c6167fb6964a7fa953c480ec766d8
|
||||
F src/main.c e8d76c9dc47ae7aac2bb1b3d65b55cea4fdc900f
|
||||
F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f
|
||||
@@ -233,7 +233,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c fb587121840f690101336879adfa6d0b2cd0e8c7
|
||||
F src/os_win.c a9e500dd963fb1f67d7860e58b5772abe6123862
|
||||
F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21
|
||||
F src/pager.c 8d97b3633f098fef817656dcbf167ca904511d78
|
||||
F src/pager.c b8764f90c135482988268eec93d7f5cdb89d687a
|
||||
F src/pager.h d1eee3c3f741be247ce6d82752a178515fc8578b
|
||||
F src/parse.y 5dfead8aed90cb0c7c1115898ee2266804daff45
|
||||
F src/pcache.c ace1b67632deeaa84859b4c16c27711dfb7db3d4
|
||||
@@ -246,16 +246,16 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 428165951748151e87a15295b7357221433e311b
|
||||
F src/shell.c a67b1304a7d93f26ec611de7b4650307f8e074a7
|
||||
F src/sqlite.h.in 6a51d3ab98e02777b894f361a81766eb9cee7413
|
||||
F src/shell.c 81e4f2b57396db0714bc73d1f95cf3970f5dcc10
|
||||
F src/sqlite.h.in 76626596dabd96d98b3bb88495386b1bb5fa7f44
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
F src/sqliteInt.h 29e71a7464bdec315a269976b817b7add6d4edbc
|
||||
F src/sqliteInt.h 4ad823ef8e31448ca333eafa1892ab35759ae6c1
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 81712116e826b0089bb221b018929536b2b5406f
|
||||
F src/table.c f142bba7903e93ca8d113a5b8877a108ad1a27dc
|
||||
F src/tclsqlite.c 05be57620509060e85064b9495256c05d56e76b0
|
||||
F src/test1.c 6b0469b8e06c77b1de1d3e4a3834cf26edea9cc7
|
||||
F src/test1.c a0bce4f47da65b76c80e5f8bf9a5ef174603866a
|
||||
F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712
|
||||
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
|
||||
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
|
||||
@@ -308,20 +308,20 @@ F src/update.c d207deb7a031f698104bee879de0632b611e72dd
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
F src/util.c 3b627daa45c7308c1e36e3dbaa3f9ce7e5c7fa73
|
||||
F src/vacuum.c 9b30ec729337dd012ed88d4c292922c8ef9cf00c
|
||||
F src/vdbe.c ef0d4a46d2aa7f6aedb2c4c29c66e1e33d4c7168
|
||||
F src/vdbe.c 24e590213c0b5b4432db922fcc2981d918b6607d
|
||||
F src/vdbe.h b434bb75fbec973d18d49225a59833ae39ee2afc
|
||||
F src/vdbeInt.h dc69f0351bef56456fdba3e09d3387ba4f1b1520
|
||||
F src/vdbeapi.c 3d4d2a2b24055ce2cb029fa73067c56616264b51
|
||||
F src/vdbeaux.c 19ecf5fc0524346e46c31fa035c57adb90ffa49e
|
||||
F src/vdbeaux.c ccf6b7ca6c7361bdb71d12385b4cff70b395486c
|
||||
F src/vdbeblob.c cb7359c2d99df92c35cdaedc12af6d4f83854cb7
|
||||
F src/vdbemem.c 96e41193b4affd9ebc0eea2fa628879dac88c744
|
||||
F src/vdbesort.c 87f3923483113d1c95d84640becb4e4946f27d9a
|
||||
F src/vdbesort.c 42c166f7ca78cb643c7f4e4bdfa83c59d363d1a6
|
||||
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
|
||||
F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793
|
||||
F src/wal.c fa090966140602f03a621f87d82ee69e66ca63b5
|
||||
F src/vtab.c c08ec66f45919eaa726bf88aa53eb08379d607f9
|
||||
F src/wal.c 486e644b3b8aa5ad066f625bc428aa8ff7001405
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c 3862a1173ae2716bde12f1ab3fb649f1d85b05c2
|
||||
F src/where.c a0b16f9d78321cb340a977287d19f826555c7d3b
|
||||
F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@@ -363,8 +363,8 @@ F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa
|
||||
F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7
|
||||
F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
|
||||
F test/autoindex1.test 6ff78b94f43a59616c06c11c55b12935173506d7
|
||||
F test/autoindex2.test 60d2fc6f38364308ce73a9beb01b47ded38697de
|
||||
F test/autoindex3.test 8254f689c3241081fad52b7bea18ba53e07e14a2
|
||||
F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8
|
||||
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
|
||||
F test/autoindex4.test fc807f9efd158bec60f5dfdf34ebe46fb274612d
|
||||
F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74
|
||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
@@ -383,6 +383,7 @@ F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
|
||||
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
|
||||
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
|
||||
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bigsort.test 835478d0ce83bd1e5b05c90571dedd9871a09196
|
||||
F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c
|
||||
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
|
||||
F test/bitvec.test 75894a880520164d73b1305c1c3f96882615e142
|
||||
@@ -395,6 +396,7 @@ F test/boundary3.tcl 23361e108a125dca9c4080c2feb884fe54d69243
|
||||
F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45
|
||||
F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983
|
||||
F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
|
||||
F test/btree01.test e08b3613540145b353f20c81cb18ead54ff12e0f
|
||||
F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
|
||||
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
||||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
@@ -793,8 +795,8 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
|
||||
F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
|
||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
|
||||
F test/permutations.test a33230010a3d4ce0c57d586672ccef10a7d1af29
|
||||
F test/pragma.test 19d0241a007bcdd77fc2606ec60fc60357e7fc8b
|
||||
F test/permutations.test 5e60eb6ca8429453ab20525dc6ac93d9c41dac6e
|
||||
F test/pragma.test 49ac8a73c0daa574824538fed28727d1259fe735
|
||||
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
|
||||
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
|
||||
F test/printf2.test b4acd4bf8734243257f01ddefa17c4fb090acc8a
|
||||
@@ -828,7 +830,7 @@ F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0
|
||||
F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
|
||||
F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
|
||||
F test/savepoint7.test db3db281486c925095f305aad09fe806e5188ff3
|
||||
F test/scanstatus.test a6dd739bc4d9638e8f5c2493b518057f2b681655
|
||||
F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285
|
||||
F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
|
||||
F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
|
||||
F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
|
||||
@@ -864,8 +866,8 @@ F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
|
||||
F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
|
||||
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test d60946b5fde4d85fe06db7331dfe89011f564350
|
||||
F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3
|
||||
F test/shell1.test ab6025d941f9c84c5b83412c6b4d8b57f78dfa3a
|
||||
F test/shell2.test 12b8bf901b0e3a8ac58cf5c0c63a0a388d4d1862
|
||||
F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
|
||||
F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5
|
||||
F test/shell5.test 15a419cc1df21c892ed64f5596ae7a501f2816f2
|
||||
@@ -873,7 +875,7 @@ F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
|
||||
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
|
||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||
F test/skipscan1.test 7e15e1cc524524e7b2c4595ec85c75501d22f4ff
|
||||
F test/skipscan1.test 2ddfe5d168462170c4487f534e2a99fb006b2076
|
||||
F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
|
||||
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
|
||||
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
|
||||
@@ -1107,7 +1109,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||
F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9
|
||||
F test/vtab1.test b631d147b198cfd7903ab5fed028eb2a3d321dc6
|
||||
F test/vtab1.test 1cef14310144718812351a61c5cfb4ba8494a171
|
||||
F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d
|
||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
|
||||
@@ -1239,7 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 28b044a51215a3f64dafb2cf3b6cb7d2029580ef 296b0c7397790ceadbdb330959e962f6491abc3e
|
||||
R 29b28d376c9121783d6d4ac3519f50ed
|
||||
P f09055f3c4348264c7336f90646375f0d98b061e 61b31e771430f490fc2c4cef55046debc4a5f4f5
|
||||
R 4cb97995ea5a95cf1669fe4c63af9fe5
|
||||
U drh
|
||||
Z c3d0de9dd44c494f12cc744c4f6471c6
|
||||
Z 1bc55c89abd689844735dcd7c551f20d
|
||||
|
@@ -1 +1 @@
|
||||
f09055f3c4348264c7336f90646375f0d98b061e
|
||||
2617d93713d9f4cf907ab2e7baef6a0f74f7198e
|
@@ -1457,23 +1457,28 @@ static void decodeIntArray(
|
||||
if( *z==' ' ) z++;
|
||||
}
|
||||
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
assert( pIndex!=0 );
|
||||
assert( pIndex!=0 ); {
|
||||
#else
|
||||
if( pIndex )
|
||||
if( pIndex ){
|
||||
#endif
|
||||
while( z[0] ){
|
||||
if( sqlite3_strglob("unordered*", z)==0 ){
|
||||
pIndex->bUnordered = 1;
|
||||
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
|
||||
pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
|
||||
}
|
||||
pIndex->bUnordered = 0;
|
||||
pIndex->noSkipScan = 0;
|
||||
while( z[0] ){
|
||||
if( sqlite3_strglob("unordered*", z)==0 ){
|
||||
pIndex->bUnordered = 1;
|
||||
}else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
|
||||
pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
|
||||
}else if( sqlite3_strglob("noskipscan*", z)==0 ){
|
||||
pIndex->noSkipScan = 1;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_COSTMULT
|
||||
else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
|
||||
pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
|
||||
}
|
||||
else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
|
||||
pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
|
||||
}
|
||||
#endif
|
||||
while( z[0]!=0 && z[0]!=' ' ) z++;
|
||||
while( z[0]==' ' ) z++;
|
||||
while( z[0]!=0 && z[0]!=' ' ) z++;
|
||||
while( z[0]==' ' ) z++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
166
src/btree.c
166
src/btree.c
@@ -1139,6 +1139,11 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
|
||||
** end of the page and all free space is collected into one
|
||||
** big FreeBlk that occurs in between the header and cell
|
||||
** pointer array and the cell content area.
|
||||
**
|
||||
** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
|
||||
** b-tree page so that there are no freeblocks or fragment bytes, all
|
||||
** unused bytes are contained in the unallocated space region, and all
|
||||
** cells are packed tightly at the end of the page.
|
||||
*/
|
||||
static int defragmentPage(MemPage *pPage){
|
||||
int i; /* Loop counter */
|
||||
@@ -1247,16 +1252,23 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){
|
||||
|
||||
for(iAddr=hdr+1; (pc = get2byte(&aData[iAddr]))>0; iAddr=pc){
|
||||
int size; /* Size of the free slot */
|
||||
/* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
|
||||
** increasing offset. */
|
||||
if( pc>usableSize-4 || pc<iAddr+4 ){
|
||||
*pRc = SQLITE_CORRUPT_BKPT;
|
||||
return 0;
|
||||
}
|
||||
/* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
|
||||
** freeblock form a big-endian integer which is the size of the freeblock
|
||||
** in bytes, including the 4-byte header. */
|
||||
size = get2byte(&aData[pc+2]);
|
||||
if( size>=nByte ){
|
||||
int x = size - nByte;
|
||||
testcase( x==4 );
|
||||
testcase( x==3 );
|
||||
if( x<4 ){
|
||||
/* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
|
||||
** number of bytes in fragments may not exceed 60. */
|
||||
if( aData[hdr+7]>=60 ){
|
||||
if( pbDefrag ) *pbDefrag = 1;
|
||||
return 0;
|
||||
@@ -1311,14 +1323,13 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
|
||||
assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
|
||||
gap = pPage->cellOffset + 2*pPage->nCell;
|
||||
assert( gap<=65536 );
|
||||
top = get2byte(&data[hdr+5]);
|
||||
if( gap>top ){
|
||||
if( top==0 ){
|
||||
top = 65536;
|
||||
}else{
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
}
|
||||
/* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
|
||||
** and the reserved space is zero (the usual value for reserved space)
|
||||
** then the cell content offset of an empty page wants to be 65536.
|
||||
** However, that integer is too large to be stored in a 2-byte unsigned
|
||||
** integer, so a value of 0 is used in its place. */
|
||||
top = get2byteNotZero(&data[hdr+5]);
|
||||
if( gap>top ) return SQLITE_CORRUPT_BKPT;
|
||||
|
||||
/* If there is enough space between gap and top for one more cell pointer
|
||||
** array entry offset, and if the freelist is not empty, then search the
|
||||
@@ -1345,7 +1356,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
|
||||
testcase( gap+2+nByte==top );
|
||||
if( gap+2+nByte>top ){
|
||||
defragment_page:
|
||||
testcase( pPage->nCell==0 );
|
||||
assert( pPage->nCell>0 || CORRUPT_DB );
|
||||
rc = defragmentPage(pPage);
|
||||
if( rc ) return rc;
|
||||
top = get2byteNotZero(&data[hdr+5]);
|
||||
@@ -1487,18 +1498,32 @@ static int decodeFlags(MemPage *pPage, int flagByte){
|
||||
pPage->childPtrSize = 4-4*pPage->leaf;
|
||||
pBt = pPage->pBt;
|
||||
if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
|
||||
/* EVIDENCE-OF: R-03640-13415 A value of 5 means the page is an interior
|
||||
** table b-tree page. */
|
||||
assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
|
||||
/* EVIDENCE-OF: R-20501-61796 A value of 13 means the page is a leaf
|
||||
** table b-tree page. */
|
||||
assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
|
||||
pPage->intKey = 1;
|
||||
pPage->intKeyLeaf = pPage->leaf;
|
||||
pPage->noPayload = !pPage->leaf;
|
||||
pPage->maxLocal = pBt->maxLeaf;
|
||||
pPage->minLocal = pBt->minLeaf;
|
||||
}else if( flagByte==PTF_ZERODATA ){
|
||||
/* EVIDENCE-OF: R-27225-53936 A value of 2 means the page is an interior
|
||||
** index b-tree page. */
|
||||
assert( (PTF_ZERODATA)==2 );
|
||||
/* EVIDENCE-OF: R-16571-11615 A value of 10 means the page is a leaf
|
||||
** index b-tree page. */
|
||||
assert( (PTF_ZERODATA|PTF_LEAF)==10 );
|
||||
pPage->intKey = 0;
|
||||
pPage->intKeyLeaf = 0;
|
||||
pPage->noPayload = 0;
|
||||
pPage->maxLocal = pBt->maxLocal;
|
||||
pPage->minLocal = pBt->minLocal;
|
||||
}else{
|
||||
/* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
|
||||
** an error. */
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
pPage->max1bytePayload = pBt->max1bytePayload;
|
||||
@@ -1538,21 +1563,33 @@ static int btreeInitPage(MemPage *pPage){
|
||||
|
||||
hdr = pPage->hdrOffset;
|
||||
data = pPage->aData;
|
||||
/* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
|
||||
** the b-tree page type. */
|
||||
if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
|
||||
assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
|
||||
pPage->maskPage = (u16)(pBt->pageSize - 1);
|
||||
pPage->nOverflow = 0;
|
||||
usableSize = pBt->usableSize;
|
||||
pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
|
||||
pPage->cellOffset = cellOffset = hdr + 8 + pPage->childPtrSize;
|
||||
pPage->aDataEnd = &data[usableSize];
|
||||
pPage->aCellIdx = &data[cellOffset];
|
||||
/* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
|
||||
** the start of the cell content area. A zero value for this integer is
|
||||
** interpreted as 65536. */
|
||||
top = get2byteNotZero(&data[hdr+5]);
|
||||
/* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
|
||||
** number of cells on the page. */
|
||||
pPage->nCell = get2byte(&data[hdr+3]);
|
||||
if( pPage->nCell>MX_CELL(pBt) ){
|
||||
/* To many cells for a single page. The page must be corrupt */
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
testcase( pPage->nCell==MX_CELL(pBt) );
|
||||
/* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
|
||||
** possible for a root page of a table that contains no rows) then the
|
||||
** offset to the cell content area will equal the page size minus the
|
||||
** bytes of reserved space. */
|
||||
assert( pPage->nCell>0 || top==usableSize || CORRUPT_DB );
|
||||
|
||||
/* A malformed database page might cause us to read past the end
|
||||
** of page when parsing a cell.
|
||||
@@ -1586,13 +1623,20 @@ static int btreeInitPage(MemPage *pPage){
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Compute the total free space on the page */
|
||||
/* Compute the total free space on the page
|
||||
** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
|
||||
** start of the first freeblock on the page, or is zero if there are no
|
||||
** freeblocks. */
|
||||
pc = get2byte(&data[hdr+1]);
|
||||
nFree = data[hdr+7] + top;
|
||||
nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */
|
||||
while( pc>0 ){
|
||||
u16 next, size;
|
||||
if( pc<iCellFirst || pc>iCellLast ){
|
||||
/* Start of free block is off the page */
|
||||
/* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
|
||||
** always be at least one cell before the first freeblock.
|
||||
**
|
||||
** Or, the freeblock is off the end of the page
|
||||
*/
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
next = get2byte(&data[pc]);
|
||||
@@ -1998,6 +2042,9 @@ int sqlite3BtreeOpen(
|
||||
#ifdef SQLITE_SECURE_DELETE
|
||||
pBt->btsFlags |= BTS_SECURE_DELETE;
|
||||
#endif
|
||||
/* EVIDENCE-OF: R-51873-39618 The page size for a database file is
|
||||
** determined by the 2-byte integer located at an offset of 16 bytes from
|
||||
** the beginning of the database file. */
|
||||
pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16);
|
||||
if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
|
||||
|| ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
|
||||
@@ -2016,6 +2063,9 @@ int sqlite3BtreeOpen(
|
||||
#endif
|
||||
nReserve = 0;
|
||||
}else{
|
||||
/* EVIDENCE-OF: R-37497-42412 The size of the reserved region is
|
||||
** determined by the one-byte unsigned integer found at an offset of 20
|
||||
** into the database file header. */
|
||||
nReserve = zDbHeader[20];
|
||||
pBt->btsFlags |= BTS_PAGESIZE_FIXED;
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
@@ -2525,6 +2575,9 @@ static int lockBtree(BtShared *pBt){
|
||||
u32 usableSize;
|
||||
u8 *page1 = pPage1->aData;
|
||||
rc = SQLITE_NOTADB;
|
||||
/* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins
|
||||
** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d
|
||||
** 61 74 20 33 00. */
|
||||
if( memcmp(page1, zMagicHeader, 16)!=0 ){
|
||||
goto page1_init_failed;
|
||||
}
|
||||
@@ -2565,15 +2618,21 @@ static int lockBtree(BtShared *pBt){
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The maximum embedded fraction must be exactly 25%. And the minimum
|
||||
** embedded fraction must be 12.5% for both leaf-data and non-leaf-data.
|
||||
/* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload
|
||||
** fractions and the leaf payload fraction values must be 64, 32, and 32.
|
||||
**
|
||||
** The original design allowed these amounts to vary, but as of
|
||||
** version 3.6.0, we require them to be fixed.
|
||||
*/
|
||||
if( memcmp(&page1[21], "\100\040\040",3)!=0 ){
|
||||
goto page1_init_failed;
|
||||
}
|
||||
/* EVIDENCE-OF: R-51873-39618 The page size for a database file is
|
||||
** determined by the 2-byte integer located at an offset of 16 bytes from
|
||||
** the beginning of the database file. */
|
||||
pageSize = (page1[16]<<8) | (page1[17]<<16);
|
||||
/* EVIDENCE-OF: R-25008-21688 The size of a page is a power of two
|
||||
** between 512 and 65536 inclusive. */
|
||||
if( ((pageSize-1)&pageSize)!=0
|
||||
|| pageSize>SQLITE_MAX_PAGE_SIZE
|
||||
|| pageSize<=256
|
||||
@@ -2581,6 +2640,13 @@ static int lockBtree(BtShared *pBt){
|
||||
goto page1_init_failed;
|
||||
}
|
||||
assert( (pageSize & 7)==0 );
|
||||
/* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte
|
||||
** integer at offset 20 is the number of bytes of space at the end of
|
||||
** each page to reserve for extensions.
|
||||
**
|
||||
** EVIDENCE-OF: R-37497-42412 The size of the reserved region is
|
||||
** determined by the one-byte unsigned integer found at an offset of 20
|
||||
** into the database file header. */
|
||||
usableSize = pageSize - page1[20];
|
||||
if( (u32)pageSize!=pBt->pageSize ){
|
||||
/* After reading the first page of the database assuming a page size
|
||||
@@ -2601,6 +2667,9 @@ static int lockBtree(BtShared *pBt){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto page1_init_failed;
|
||||
}
|
||||
/* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
|
||||
** be less than 480. In other words, if the page size is 512, then the
|
||||
** reserved space size cannot exceed 32. */
|
||||
if( usableSize<480 ){
|
||||
goto page1_init_failed;
|
||||
}
|
||||
@@ -5178,6 +5247,8 @@ static int allocateBtreePage(
|
||||
assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) );
|
||||
pPage1 = pBt->pPage1;
|
||||
mxPage = btreePagecount(pBt);
|
||||
/* EVIDENCE-OF: R-05119-02637 The 4-byte big-endian integer at offset 36
|
||||
** stores stores the total number of pages on the freelist. */
|
||||
n = get4byte(&pPage1->aData[36]);
|
||||
testcase( n==mxPage-1 );
|
||||
if( n>=mxPage ){
|
||||
@@ -5224,8 +5295,14 @@ static int allocateBtreePage(
|
||||
do {
|
||||
pPrevTrunk = pTrunk;
|
||||
if( pPrevTrunk ){
|
||||
/* EVIDENCE-OF: R-01506-11053 The first integer on a freelist trunk page
|
||||
** is the page number of the next freelist trunk page in the list or
|
||||
** zero if this is the last freelist trunk page. */
|
||||
iTrunk = get4byte(&pPrevTrunk->aData[0]);
|
||||
}else{
|
||||
/* EVIDENCE-OF: R-59841-13798 The 4-byte big-endian integer at offset 32
|
||||
** stores the page number of the first page of the freelist, or zero if
|
||||
** the freelist is empty. */
|
||||
iTrunk = get4byte(&pPage1->aData[32]);
|
||||
}
|
||||
testcase( iTrunk==mxPage );
|
||||
@@ -5240,8 +5317,9 @@ static int allocateBtreePage(
|
||||
}
|
||||
assert( pTrunk!=0 );
|
||||
assert( pTrunk->aData!=0 );
|
||||
|
||||
k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
|
||||
/* EVIDENCE-OF: R-13523-04394 The second integer on a freelist trunk page
|
||||
** is the number of leaf page pointers to follow. */
|
||||
k = get4byte(&pTrunk->aData[4]);
|
||||
if( k==0 && !searchList ){
|
||||
/* The trunk has no leaves and the list is not being searched.
|
||||
** So extract the trunk page itself and use it as the newly
|
||||
@@ -5559,6 +5637,11 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
** for now. At some point in the future (once everyone has upgraded
|
||||
** to 3.6.0 or later) we should consider fixing the conditional above
|
||||
** to read "usableSize/4-2" instead of "usableSize/4-8".
|
||||
**
|
||||
** EVIDENCE-OF: R-19920-11576 However, newer versions of SQLite still
|
||||
** avoid using the last six entries in the freelist trunk page array in
|
||||
** order that database files created by newer versions of SQLite can be
|
||||
** read by older versions of SQLite.
|
||||
*/
|
||||
rc = sqlite3PagerWrite(pTrunk->pDbPage);
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -5910,9 +5993,17 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
|
||||
return;
|
||||
}
|
||||
pPage->nCell--;
|
||||
memmove(ptr, ptr+2, 2*(pPage->nCell - idx));
|
||||
put2byte(&data[hdr+3], pPage->nCell);
|
||||
pPage->nFree += 2;
|
||||
if( pPage->nCell==0 ){
|
||||
memset(&data[hdr+1], 0, 4);
|
||||
data[hdr+7] = 0;
|
||||
put2byte(&data[hdr+5], pPage->pBt->usableSize);
|
||||
pPage->nFree = pPage->pBt->usableSize - pPage->hdrOffset
|
||||
- pPage->childPtrSize - 8;
|
||||
}else{
|
||||
memmove(ptr, ptr+2, 2*(pPage->nCell - idx));
|
||||
put2byte(&data[hdr+3], pPage->nCell);
|
||||
pPage->nFree += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6166,6 +6257,14 @@ static int pageFreeArray(
|
||||
}
|
||||
|
||||
/*
|
||||
** apCell[] and szCell[] contains pointers to and sizes of all cells in the
|
||||
** pages being balanced. The current page, pPg, has pPg->nCell cells starting
|
||||
** with apCell[iOld]. After balancing, this page should hold nNew cells
|
||||
** starting at apCell[iNew].
|
||||
**
|
||||
** This routine makes the necessary adjustments to pPg so that it contains
|
||||
** the correct cells after being balanced.
|
||||
**
|
||||
** The pPg->nFree field is invalid when this function returns. It is the
|
||||
** responsibility of the caller to set it correctly.
|
||||
*/
|
||||
@@ -6206,12 +6305,13 @@ static void editPage(
|
||||
);
|
||||
}
|
||||
|
||||
pData = &aData[get2byte(&aData[hdr+5])];
|
||||
pData = &aData[get2byteNotZero(&aData[hdr+5])];
|
||||
if( pData<pBegin ) goto editpage_fail;
|
||||
|
||||
/* Add cells to the start of the page */
|
||||
if( iNew<iOld ){
|
||||
int nAdd = iOld-iNew;
|
||||
int nAdd = MIN(nNew,iOld-iNew);
|
||||
assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB );
|
||||
pCellptr = pPg->aCellIdx;
|
||||
memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
|
||||
if( pageInsertArray(
|
||||
@@ -6316,7 +6416,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
|
||||
assert( pPage->nOverflow==1 );
|
||||
|
||||
/* This error condition is now caught prior to reaching this function */
|
||||
if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT;
|
||||
if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT;
|
||||
|
||||
/* Allocate a new page. This page will become the right-sibling of
|
||||
** pPage. Make the parent page writable, so that the new divider cell
|
||||
@@ -8560,8 +8660,14 @@ static int checkTreePage(
|
||||
assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
|
||||
memset(hit+contentOffset, 0, usableSize-contentOffset);
|
||||
memset(hit, 1, contentOffset);
|
||||
/* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
|
||||
** number of cells on the page. */
|
||||
nCell = get2byte(&data[hdr+3]);
|
||||
/* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page
|
||||
** immediately follows the b-tree page header. */
|
||||
cellStart = hdr + 12 - 4*pPage->leaf;
|
||||
/* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte
|
||||
** integer offsets to the cell contents. */
|
||||
for(i=0; i<nCell; i++){
|
||||
int pc = get2byte(&data[cellStart+i*2]);
|
||||
u32 size = 65536;
|
||||
@@ -8577,6 +8683,9 @@ static int checkTreePage(
|
||||
for(j=pc+size-1; j>=pc; j--) hit[j]++;
|
||||
}
|
||||
}
|
||||
/* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
|
||||
** is the offset of the first freeblock, or zero if there are no
|
||||
** freeblocks on the page. */
|
||||
i = get2byte(&data[hdr+1]);
|
||||
while( i>0 ){
|
||||
int size, j;
|
||||
@@ -8584,7 +8693,13 @@ static int checkTreePage(
|
||||
size = get2byte(&data[i+2]);
|
||||
assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */
|
||||
for(j=i+size-1; j>=i; j--) hit[j]++;
|
||||
/* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
|
||||
** big-endian integer which is the offset in the b-tree page of the next
|
||||
** freeblock in the chain, or zero if the freeblock is the last on the
|
||||
** chain. */
|
||||
j = get2byte(&data[i]);
|
||||
/* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
|
||||
** increasing offset. */
|
||||
assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */
|
||||
assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */
|
||||
i = j;
|
||||
@@ -8598,6 +8713,11 @@ static int checkTreePage(
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments
|
||||
** is stored in the fifth field of the b-tree page header.
|
||||
** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the
|
||||
** number of fragmented free bytes within the cell content area.
|
||||
*/
|
||||
if( cnt!=data[hdr+7] ){
|
||||
checkAppendMsg(pCheck,
|
||||
"Fragmentation of %d bytes reported as %d on page %d",
|
||||
|
@@ -3003,7 +3003,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
/* If the column has REAL affinity, it may currently be stored as an
|
||||
** integer. Use OP_RealAffinity to make sure it is really real. */
|
||||
** integer. Use OP_RealAffinity to make sure it is really real.
|
||||
**
|
||||
** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to
|
||||
** floating point when extracting it from the record. */
|
||||
if( pExpr->iColumn>=0
|
||||
&& pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
|
||||
){
|
||||
|
@@ -157,8 +157,8 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
|
||||
default: {
|
||||
/* Because sqlite3_value_double() returns 0.0 if the argument is not
|
||||
** something that can be converted into a number, we have:
|
||||
** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that
|
||||
** cannot be converted to a numeric value.
|
||||
** IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob
|
||||
** that cannot be converted to a numeric value.
|
||||
*/
|
||||
double rVal = sqlite3_value_double(argv[0]);
|
||||
if( rVal<0 ) rVal = -rVal;
|
||||
|
19
src/main.c
19
src/main.c
@@ -773,13 +773,20 @@ static int binCollFunc(
|
||||
){
|
||||
int rc, n;
|
||||
n = nKey1<nKey2 ? nKey1 : nKey2;
|
||||
/* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
|
||||
** strings byte by byte using the memcmp() function from the standard C
|
||||
** library. */
|
||||
rc = memcmp(pKey1, pKey2, n);
|
||||
if( rc==0 ){
|
||||
if( padFlag
|
||||
&& allSpaces(((char*)pKey1)+n, nKey1-n)
|
||||
&& allSpaces(((char*)pKey2)+n, nKey2-n)
|
||||
){
|
||||
/* Leave rc unchanged at 0 */
|
||||
/* EVIDENCE-OF: R-31624-24737 RTRIM is like BINARY except that extra
|
||||
** spaces at the end of either string do not change the result. In other
|
||||
** words, strings will compare equal to one another as long as they
|
||||
** differ only in the number of spaces at the end.
|
||||
*/
|
||||
}else{
|
||||
rc = nKey1 - nKey2;
|
||||
}
|
||||
@@ -2751,20 +2758,24 @@ static int openDatabase(
|
||||
/* Add the default collation sequence BINARY. BINARY works for both UTF-8
|
||||
** and UTF-16, so add a version for each to avoid any unnecessary
|
||||
** conversions. The only error that can occur here is a malloc() failure.
|
||||
**
|
||||
** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
|
||||
** functions:
|
||||
*/
|
||||
createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0);
|
||||
createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0);
|
||||
createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0);
|
||||
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
|
||||
createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
|
||||
if( db->mallocFailed ){
|
||||
goto opendb_out;
|
||||
}
|
||||
/* EVIDENCE-OF: R-08308-17224 The default collating function for all
|
||||
** strings is BINARY.
|
||||
*/
|
||||
db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
|
||||
assert( db->pDfltColl!=0 );
|
||||
|
||||
/* Also add a UTF-8 case-insensitive collation sequence. */
|
||||
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
|
||||
|
||||
/* Parse the filename/URI argument. */
|
||||
db->openFlags = flags;
|
||||
rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
|
||||
|
@@ -2899,7 +2899,7 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
|
||||
**
|
||||
** For an encrypted database, the situation is more complex: bytes
|
||||
** 24..39 of the database are white noise. But the probability of
|
||||
** white noising equaling 16 bytes of 0xff is vanishingly small so
|
||||
** white noise equaling 16 bytes of 0xff is vanishingly small so
|
||||
** we should still be ok.
|
||||
*/
|
||||
memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
|
||||
|
77
src/shell.c
77
src/shell.c
@@ -4319,10 +4319,12 @@ int main(int argc, char **argv){
|
||||
char *zErrMsg = 0;
|
||||
ShellState data;
|
||||
const char *zInitFile = 0;
|
||||
char *zFirstCmd = 0;
|
||||
int i;
|
||||
int rc = 0;
|
||||
int warnInmemoryDb = 0;
|
||||
int readStdin = 1;
|
||||
int nCmd = 0;
|
||||
char **azCmd = 0;
|
||||
|
||||
#if USE_SYSTEM_SQLITE+0!=1
|
||||
if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
|
||||
@@ -4342,6 +4344,18 @@ int main(int argc, char **argv){
|
||||
signal(SIGINT, interrupt_handler);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_SHELL_DBNAME_PROC
|
||||
{
|
||||
/* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
|
||||
** of a C-function that will provide the name of the database file. Use
|
||||
** this compile-time option to embed this shell program in larger
|
||||
** applications. */
|
||||
extern void SQLITE_SHELL_DBNAME_PROC(const char**);
|
||||
SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
|
||||
warnInmemoryDb = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Do an initial pass through the command-line argument to locate
|
||||
** the name of the database file, the name of the initialization file,
|
||||
** the size of the alternative malloc heap,
|
||||
@@ -4353,15 +4367,18 @@ int main(int argc, char **argv){
|
||||
if( z[0]!='-' ){
|
||||
if( data.zDbFilename==0 ){
|
||||
data.zDbFilename = z;
|
||||
continue;
|
||||
}else{
|
||||
/* Excesss arguments are interpreted as SQL (or dot-commands) and
|
||||
** mean that nothing is read from stdin */
|
||||
readStdin = 0;
|
||||
nCmd++;
|
||||
azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
|
||||
if( azCmd==0 ){
|
||||
fprintf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
azCmd[nCmd-1] = z;
|
||||
}
|
||||
if( zFirstCmd==0 ){
|
||||
zFirstCmd = z;
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
|
||||
fprintf(stderr,"Use -help for a list of options.\n");
|
||||
return 1;
|
||||
}
|
||||
if( z[1]=='-' ) z++;
|
||||
if( strcmp(z,"-separator")==0
|
||||
@@ -4451,11 +4468,6 @@ int main(int argc, char **argv){
|
||||
#else
|
||||
fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef SQLITE_SHELL_DBNAME_PROC
|
||||
{ extern void SQLITE_SHELL_DBNAME_PROC(const char**);
|
||||
SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
|
||||
warnInmemoryDb = 0; }
|
||||
#endif
|
||||
}
|
||||
data.out = stdout;
|
||||
@@ -4553,6 +4565,10 @@ int main(int argc, char **argv){
|
||||
}else if( strcmp(z,"-help")==0 ){
|
||||
usage(1);
|
||||
}else if( strcmp(z,"-cmd")==0 ){
|
||||
/* Run commands that follow -cmd first and separately from commands
|
||||
** that simply appear on the command-line. This seems goofy. It would
|
||||
** be better if all commands ran in the order that they appear. But
|
||||
** we retain the goofy behavior for historical compatibility. */
|
||||
if( i==argc-1 ) break;
|
||||
z = cmdline_option_value(argc,argv,++i);
|
||||
if( z[0]=='.' ){
|
||||
@@ -4576,23 +4592,28 @@ int main(int argc, char **argv){
|
||||
}
|
||||
}
|
||||
|
||||
if( zFirstCmd ){
|
||||
/* Run just the command that follows the database name
|
||||
if( !readStdin ){
|
||||
/* Run all arguments that do not begin with '-' as if they were separate
|
||||
** command-line inputs, except for the argToSkip argument which contains
|
||||
** the database filename.
|
||||
*/
|
||||
if( zFirstCmd[0]=='.' ){
|
||||
rc = do_meta_command(zFirstCmd, &data);
|
||||
if( rc==2 ) rc = 0;
|
||||
}else{
|
||||
open_db(&data, 0);
|
||||
rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
|
||||
if( zErrMsg!=0 ){
|
||||
fprintf(stderr,"Error: %s\n", zErrMsg);
|
||||
return rc!=0 ? rc : 1;
|
||||
}else if( rc!=0 ){
|
||||
fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
|
||||
return rc;
|
||||
for(i=0; i<nCmd; i++){
|
||||
if( azCmd[i][0]=='.' ){
|
||||
rc = do_meta_command(azCmd[i], &data);
|
||||
if( rc ) return rc==2 ? 0 : rc;
|
||||
}else{
|
||||
open_db(&data, 0);
|
||||
rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
|
||||
if( zErrMsg!=0 ){
|
||||
fprintf(stderr,"Error: %s\n", zErrMsg);
|
||||
return rc!=0 ? rc : 1;
|
||||
}else if( rc!=0 ){
|
||||
fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(azCmd);
|
||||
}else{
|
||||
/* Run commands received from standard input
|
||||
*/
|
||||
|
@@ -4164,9 +4164,9 @@ int sqlite3_create_function_v2(
|
||||
** These constant define integer codes that represent the various
|
||||
** text encodings supported by SQLite.
|
||||
*/
|
||||
#define SQLITE_UTF8 1
|
||||
#define SQLITE_UTF16LE 2
|
||||
#define SQLITE_UTF16BE 3
|
||||
#define SQLITE_UTF8 1 /* IMP: R-37514-35566 */
|
||||
#define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */
|
||||
#define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */
|
||||
#define SQLITE_UTF16 4 /* Use native byte order */
|
||||
#define SQLITE_ANY 5 /* Deprecated */
|
||||
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
|
||||
@@ -5900,34 +5900,34 @@ int sqlite3_vfs_unregister(sqlite3_vfs*);
|
||||
**
|
||||
** The SQLite source code contains multiple implementations
|
||||
** of these mutex routines. An appropriate implementation
|
||||
** is selected automatically at compile-time. ^(The following
|
||||
** is selected automatically at compile-time. The following
|
||||
** implementations are available in the SQLite core:
|
||||
**
|
||||
** <ul>
|
||||
** <li> SQLITE_MUTEX_PTHREADS
|
||||
** <li> SQLITE_MUTEX_W32
|
||||
** <li> SQLITE_MUTEX_NOOP
|
||||
** </ul>)^
|
||||
** </ul>
|
||||
**
|
||||
** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
|
||||
** The SQLITE_MUTEX_NOOP implementation is a set of routines
|
||||
** that does no real locking and is appropriate for use in
|
||||
** a single-threaded application. ^The SQLITE_MUTEX_PTHREADS and
|
||||
** a single-threaded application. The SQLITE_MUTEX_PTHREADS and
|
||||
** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
|
||||
** and Windows.
|
||||
**
|
||||
** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
|
||||
** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
|
||||
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
|
||||
** implementation is included with the library. In this case the
|
||||
** application must supply a custom mutex implementation using the
|
||||
** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
|
||||
** before calling sqlite3_initialize() or any other public sqlite3_
|
||||
** function that calls sqlite3_initialize().)^
|
||||
** function that calls sqlite3_initialize().
|
||||
**
|
||||
** ^The sqlite3_mutex_alloc() routine allocates a new
|
||||
** mutex and returns a pointer to it. ^If it returns NULL
|
||||
** that means that a mutex could not be allocated. ^SQLite
|
||||
** will unwind its stack and return an error. ^(The argument
|
||||
** to sqlite3_mutex_alloc() is one of these integer constants:
|
||||
** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
|
||||
** routine returns NULL if it is unable to allocate the requested
|
||||
** mutex. The argument to sqlite3_mutex_alloc() must one of these
|
||||
** integer constants:
|
||||
**
|
||||
** <ul>
|
||||
** <li> SQLITE_MUTEX_FAST
|
||||
@@ -5940,7 +5940,8 @@ int sqlite3_vfs_unregister(sqlite3_vfs*);
|
||||
** <li> SQLITE_MUTEX_STATIC_PMEM
|
||||
** <li> SQLITE_MUTEX_STATIC_APP1
|
||||
** <li> SQLITE_MUTEX_STATIC_APP2
|
||||
** </ul>)^
|
||||
** <li> SQLITE_MUTEX_STATIC_APP3
|
||||
** </ul>
|
||||
**
|
||||
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
|
||||
** cause sqlite3_mutex_alloc() to create
|
||||
@@ -5948,14 +5949,14 @@ int sqlite3_vfs_unregister(sqlite3_vfs*);
|
||||
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
|
||||
** The mutex implementation does not need to make a distinction
|
||||
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
|
||||
** not want to. ^SQLite will only request a recursive mutex in
|
||||
** cases where it really needs one. ^If a faster non-recursive mutex
|
||||
** not want to. SQLite will only request a recursive mutex in
|
||||
** cases where it really needs one. If a faster non-recursive mutex
|
||||
** implementation is available on the host platform, the mutex subsystem
|
||||
** might return such a mutex in response to SQLITE_MUTEX_FAST.
|
||||
**
|
||||
** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
|
||||
** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
|
||||
** a pointer to a static preexisting mutex. ^Six static mutexes are
|
||||
** a pointer to a static preexisting mutex. ^Nine static mutexes are
|
||||
** used by the current version of SQLite. Future versions of SQLite
|
||||
** may add additional static mutexes. Static mutexes are for internal
|
||||
** use by SQLite only. Applications that use SQLite mutexes should
|
||||
@@ -5964,16 +5965,13 @@ int sqlite3_vfs_unregister(sqlite3_vfs*);
|
||||
**
|
||||
** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
|
||||
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
|
||||
** returns a different mutex on every call. ^But for the static
|
||||
** returns a different mutex on every call. ^For the static
|
||||
** mutex types, the same mutex is returned on every call that has
|
||||
** the same type number.
|
||||
**
|
||||
** ^The sqlite3_mutex_free() routine deallocates a previously
|
||||
** allocated dynamic mutex. ^SQLite is careful to deallocate every
|
||||
** dynamic mutex that it allocates. The dynamic mutexes must not be in
|
||||
** use when they are deallocated. Attempting to deallocate a static
|
||||
** mutex results in undefined behavior. ^SQLite never deallocates
|
||||
** a static mutex.
|
||||
** allocated dynamic mutex. Attempting to deallocate a static
|
||||
** mutex results in undefined behavior.
|
||||
**
|
||||
** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
|
||||
** to enter a mutex. ^If another thread is already within the mutex,
|
||||
@@ -5981,23 +5979,21 @@ int sqlite3_vfs_unregister(sqlite3_vfs*);
|
||||
** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
|
||||
** upon successful entry. ^(Mutexes created using
|
||||
** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
|
||||
** In such cases the,
|
||||
** In such cases, the
|
||||
** mutex must be exited an equal number of times before another thread
|
||||
** can enter.)^ ^(If the same thread tries to enter any other
|
||||
** kind of mutex more than once, the behavior is undefined.
|
||||
** SQLite will never exhibit
|
||||
** such behavior in its own use of mutexes.)^
|
||||
** can enter.)^ If the same thread tries to enter any mutex other
|
||||
** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
|
||||
**
|
||||
** ^(Some systems (for example, Windows 95) do not support the operation
|
||||
** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
|
||||
** will always return SQLITE_BUSY. The SQLite core only ever uses
|
||||
** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^
|
||||
** will always return SQLITE_BUSY. The SQLite core only ever uses
|
||||
** sqlite3_mutex_try() as an optimization so this is acceptable
|
||||
** behavior.)^
|
||||
**
|
||||
** ^The sqlite3_mutex_leave() routine exits a mutex that was
|
||||
** previously entered by the same thread. ^(The behavior
|
||||
** previously entered by the same thread. The behavior
|
||||
** is undefined if the mutex is not currently entered by the
|
||||
** calling thread or is not currently allocated. SQLite will
|
||||
** never do either.)^
|
||||
** calling thread or is not currently allocated.
|
||||
**
|
||||
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
|
||||
** sqlite3_mutex_leave() is a NULL pointer, then all three routines
|
||||
@@ -6018,9 +6014,9 @@ void sqlite3_mutex_leave(sqlite3_mutex*);
|
||||
** used to allocate and use mutexes.
|
||||
**
|
||||
** Usually, the default mutex implementations provided by SQLite are
|
||||
** sufficient, however the user has the option of substituting a custom
|
||||
** sufficient, however the application has the option of substituting a custom
|
||||
** implementation for specialized deployments or systems for which SQLite
|
||||
** does not provide a suitable implementation. In this case, the user
|
||||
** does not provide a suitable implementation. In this case, the application
|
||||
** creates and populates an instance of this structure to pass
|
||||
** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
|
||||
** Additionally, an instance of this structure can be used as an
|
||||
@@ -6061,13 +6057,13 @@ void sqlite3_mutex_leave(sqlite3_mutex*);
|
||||
** (i.e. it is acceptable to provide an implementation that segfaults if
|
||||
** it is passed a NULL pointer).
|
||||
**
|
||||
** The xMutexInit() method must be threadsafe. ^It must be harmless to
|
||||
** The xMutexInit() method must be threadsafe. It must be harmless to
|
||||
** invoke xMutexInit() multiple times within the same process and without
|
||||
** intervening calls to xMutexEnd(). Second and subsequent calls to
|
||||
** xMutexInit() must be no-ops.
|
||||
**
|
||||
** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
|
||||
** and its associates). ^Similarly, xMutexAlloc() must not use SQLite memory
|
||||
** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
|
||||
** and its associates). Similarly, xMutexAlloc() must not use SQLite memory
|
||||
** allocation for a static mutex. ^However xMutexAlloc() may use SQLite
|
||||
** memory allocation for a fast or recursive mutex.
|
||||
**
|
||||
@@ -6093,29 +6089,29 @@ struct sqlite3_mutex_methods {
|
||||
** CAPI3REF: Mutex Verification Routines
|
||||
**
|
||||
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
|
||||
** are intended for use inside assert() statements. ^The SQLite core
|
||||
** are intended for use inside assert() statements. The SQLite core
|
||||
** never uses these routines except inside an assert() and applications
|
||||
** are advised to follow the lead of the core. ^The SQLite core only
|
||||
** are advised to follow the lead of the core. The SQLite core only
|
||||
** provides implementations for these routines when it is compiled
|
||||
** with the SQLITE_DEBUG flag. ^External mutex implementations
|
||||
** with the SQLITE_DEBUG flag. External mutex implementations
|
||||
** are only required to provide these routines if SQLITE_DEBUG is
|
||||
** defined and if NDEBUG is not defined.
|
||||
**
|
||||
** ^These routines should return true if the mutex in their argument
|
||||
** These routines should return true if the mutex in their argument
|
||||
** is held or not held, respectively, by the calling thread.
|
||||
**
|
||||
** ^The implementation is not required to provide versions of these
|
||||
** The implementation is not required to provide versions of these
|
||||
** routines that actually work. If the implementation does not provide working
|
||||
** versions of these routines, it should at least provide stubs that always
|
||||
** return true so that one does not get spurious assertion failures.
|
||||
**
|
||||
** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
|
||||
** If the argument to sqlite3_mutex_held() is a NULL pointer then
|
||||
** the routine should return 1. This seems counter-intuitive since
|
||||
** clearly the mutex cannot be held if it does not exist. But
|
||||
** the reason the mutex does not exist is because the build is not
|
||||
** using mutexes. And we do not want the assert() containing the
|
||||
** call to sqlite3_mutex_held() to fail, so a non-zero return is
|
||||
** the appropriate thing to do. ^The sqlite3_mutex_notheld()
|
||||
** the appropriate thing to do. The sqlite3_mutex_notheld()
|
||||
** interface should also return 1 when given a NULL pointer.
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
|
@@ -1803,6 +1803,7 @@ struct Index {
|
||||
unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */
|
||||
unsigned isResized:1; /* True if resizeIndexObject() has been called */
|
||||
unsigned isCovering:1; /* True if this is a covering index */
|
||||
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
int nSample; /* Number of elements in aSample[] */
|
||||
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
|
||||
|
17
src/test1.c
17
src/test1.c
@@ -3638,6 +3638,7 @@ static int test_prepare_v2(
|
||||
){
|
||||
sqlite3 *db;
|
||||
const char *zSql;
|
||||
char *zCopy = 0; /* malloc() copy of zSql */
|
||||
int bytes;
|
||||
const char *zTail = 0;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
@@ -3653,7 +3654,21 @@ static int test_prepare_v2(
|
||||
zSql = Tcl_GetString(objv[2]);
|
||||
if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
|
||||
|
||||
rc = sqlite3_prepare_v2(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
|
||||
/* Instead of using zSql directly, make a copy into a buffer obtained
|
||||
** directly from malloc(). The idea is to make it easier for valgrind
|
||||
** to spot buffer overreads. */
|
||||
if( bytes>=0 ){
|
||||
zCopy = malloc(bytes);
|
||||
memcpy(zCopy, zSql, bytes);
|
||||
}else{
|
||||
int n = strlen(zSql) + 1;
|
||||
zCopy = malloc(n);
|
||||
memcpy(zCopy, zSql, n);
|
||||
}
|
||||
rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, objc>=5 ? &zTail : 0);
|
||||
free(zCopy);
|
||||
zTail = &zSql[(zTail - zCopy)];
|
||||
|
||||
assert(rc==SQLITE_OK || pStmt==0);
|
||||
Tcl_ResetResult(interp);
|
||||
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
|
||||
|
10
src/vdbe.c
10
src/vdbe.c
@@ -2646,7 +2646,10 @@ case OP_MakeRecord: {
|
||||
nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
|
||||
}while( (--pRec)>=pData0 );
|
||||
|
||||
/* Add the initial header varint and total the size */
|
||||
/* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
|
||||
** which determines the total number of bytes in the header. The varint
|
||||
** value is the size of the header in bytes including the size varint
|
||||
** itself. */
|
||||
testcase( nHdr==126 );
|
||||
testcase( nHdr==127 );
|
||||
if( nHdr<=126 ){
|
||||
@@ -2680,7 +2683,11 @@ case OP_MakeRecord: {
|
||||
pRec = pData0;
|
||||
do{
|
||||
serial_type = pRec->uTemp;
|
||||
/* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
|
||||
** additional varints, one per column. */
|
||||
i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
|
||||
/* EVIDENCE-OF: R-64536-51728 The values for each column in the record
|
||||
** immediately follow the header. */
|
||||
j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
|
||||
}while( (++pRec)<=pLast );
|
||||
assert( i==nHdr );
|
||||
@@ -3818,7 +3825,6 @@ case OP_Found: { /* jump, in3 */
|
||||
);
|
||||
if( pIdxKey==0 ) goto no_mem;
|
||||
assert( pIn3->flags & MEM_Blob );
|
||||
/* assert( (pIn3->flags & MEM_Zero)==0 ); // zeroblobs already expanded */
|
||||
ExpandBlob(pIn3);
|
||||
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
|
||||
}
|
||||
|
@@ -1743,7 +1743,7 @@ void sqlite3VdbeMakeReady(
|
||||
p->aVar[n].db = db;
|
||||
}
|
||||
}
|
||||
if( p->azVar ){
|
||||
if( p->azVar && pParse->nzVar>0 ){
|
||||
p->nzVar = pParse->nzVar;
|
||||
memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
|
||||
memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
|
||||
@@ -2884,9 +2884,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
|
||||
i64 i = pMem->u.i;
|
||||
u64 u;
|
||||
if( i<0 ){
|
||||
if( i<(-MAX_6BYTE) ) return 6;
|
||||
/* Previous test prevents: u = -(-9223372036854775808) */
|
||||
u = -i;
|
||||
u = ~i;
|
||||
}else{
|
||||
u = i;
|
||||
}
|
||||
@@ -3052,10 +3050,14 @@ static u32 SQLITE_NOINLINE serialGet(
|
||||
u32 y = FOUR_BYTE_UINT(buf+4);
|
||||
x = (x<<32) + y;
|
||||
if( serial_type==6 ){
|
||||
/* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit
|
||||
** twos-complement integer. */
|
||||
pMem->u.i = *(i64*)&x;
|
||||
pMem->flags = MEM_Int;
|
||||
testcase( pMem->u.i<0 );
|
||||
}else{
|
||||
/* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit
|
||||
** floating point number. */
|
||||
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
|
||||
/* Verify that integers and floating point values use the same
|
||||
** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
|
||||
@@ -3083,35 +3085,46 @@ u32 sqlite3VdbeSerialGet(
|
||||
switch( serial_type ){
|
||||
case 10: /* Reserved for future use */
|
||||
case 11: /* Reserved for future use */
|
||||
case 0: { /* NULL */
|
||||
case 0: { /* Null */
|
||||
/* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
|
||||
pMem->flags = MEM_Null;
|
||||
break;
|
||||
}
|
||||
case 1: { /* 1-byte signed integer */
|
||||
case 1: {
|
||||
/* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement
|
||||
** integer. */
|
||||
pMem->u.i = ONE_BYTE_INT(buf);
|
||||
pMem->flags = MEM_Int;
|
||||
testcase( pMem->u.i<0 );
|
||||
return 1;
|
||||
}
|
||||
case 2: { /* 2-byte signed integer */
|
||||
/* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit
|
||||
** twos-complement integer. */
|
||||
pMem->u.i = TWO_BYTE_INT(buf);
|
||||
pMem->flags = MEM_Int;
|
||||
testcase( pMem->u.i<0 );
|
||||
return 2;
|
||||
}
|
||||
case 3: { /* 3-byte signed integer */
|
||||
/* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit
|
||||
** twos-complement integer. */
|
||||
pMem->u.i = THREE_BYTE_INT(buf);
|
||||
pMem->flags = MEM_Int;
|
||||
testcase( pMem->u.i<0 );
|
||||
return 3;
|
||||
}
|
||||
case 4: { /* 4-byte signed integer */
|
||||
/* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit
|
||||
** twos-complement integer. */
|
||||
pMem->u.i = FOUR_BYTE_INT(buf);
|
||||
pMem->flags = MEM_Int;
|
||||
testcase( pMem->u.i<0 );
|
||||
return 4;
|
||||
}
|
||||
case 5: { /* 6-byte signed integer */
|
||||
/* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit
|
||||
** twos-complement integer. */
|
||||
pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
|
||||
pMem->flags = MEM_Int;
|
||||
testcase( pMem->u.i<0 );
|
||||
@@ -3125,11 +3138,17 @@ u32 sqlite3VdbeSerialGet(
|
||||
}
|
||||
case 8: /* Integer 0 */
|
||||
case 9: { /* Integer 1 */
|
||||
/* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */
|
||||
/* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */
|
||||
pMem->u.i = serial_type-8;
|
||||
pMem->flags = MEM_Int;
|
||||
return 0;
|
||||
}
|
||||
default: {
|
||||
/* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in
|
||||
** length.
|
||||
** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and
|
||||
** (N-13)/2 bytes in length. */
|
||||
static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem };
|
||||
pMem->z = (char *)buf;
|
||||
pMem->n = (serial_type-12)/2;
|
||||
|
@@ -147,6 +147,13 @@
|
||||
# define SQLITE_DEBUG_SORTER_THREADS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Hard-coded maximum amount of data to accumulate in memory before flushing
|
||||
** to a level 0 PMA. The purpose of this limit is to prevent various integer
|
||||
** overflows. 512MiB.
|
||||
*/
|
||||
#define SQLITE_MAX_MXPMASIZE (1<<29)
|
||||
|
||||
/*
|
||||
** Private objects used by the sorter
|
||||
*/
|
||||
@@ -845,7 +852,7 @@ int sqlite3VdbeSorterInit(
|
||||
pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
|
||||
mxCache = db->aDb[0].pSchema->cache_size;
|
||||
if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
|
||||
pSorter->mxPmaSize = mxCache * pgsz;
|
||||
pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_MXPMASIZE);
|
||||
|
||||
/* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
|
||||
** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
|
||||
|
@@ -332,7 +332,12 @@ void sqlite3VtabBeginParse(
|
||||
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
|
||||
addModuleArgument(db, pTable, 0);
|
||||
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
|
||||
pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
|
||||
assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0)
|
||||
|| (pParse->sNameToken.z==pName1->z && pName2->z==0)
|
||||
);
|
||||
pParse->sNameToken.n = (int)(
|
||||
&pModuleName->z[pModuleName->n] - pParse->sNameToken.z
|
||||
);
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
/* Creating a virtual table invokes the authorization callback twice.
|
||||
|
@@ -2506,7 +2506,7 @@ int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
|
||||
memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr));
|
||||
|
||||
for(iFrame=pWal->hdr.mxFrame+1;
|
||||
rc==SQLITE_OK && iFrame<=iMax;
|
||||
ALWAYS(rc==SQLITE_OK) && iFrame<=iMax;
|
||||
iFrame++
|
||||
){
|
||||
/* This call cannot fail. Unless the page for which the page number
|
||||
|
57
src/where.c
57
src/where.c
@@ -4130,8 +4130,9 @@ static WhereLoop **whereLoopFindLesser(
|
||||
|
||||
/* Any loop using an appliation-defined index (or PRIMARY KEY or
|
||||
** UNIQUE constraint) with one or more == constraints is better
|
||||
** than an automatic index. */
|
||||
** than an automatic index. Unless it is a skip-scan. */
|
||||
if( (p->wsFlags & WHERE_AUTO_INDEX)!=0
|
||||
&& (pTemplate->nSkip)==0
|
||||
&& (pTemplate->wsFlags & WHERE_INDEXED)!=0
|
||||
&& (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0
|
||||
&& (p->prereq & pTemplate->prereq)==pTemplate->prereq
|
||||
@@ -4290,10 +4291,30 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
|
||||
** Adjust the WhereLoop.nOut value downward to account for terms of the
|
||||
** WHERE clause that reference the loop but which are not used by an
|
||||
** index.
|
||||
*
|
||||
** For every WHERE clause term that is not used by the index
|
||||
** and which has a truth probability assigned by one of the likelihood(),
|
||||
** likely(), or unlikely() SQL functions, reduce the estimated number
|
||||
** of output rows by the probability specified.
|
||||
**
|
||||
** In the current implementation, the first extra WHERE clause term reduces
|
||||
** the number of output rows by a factor of 10 and each additional term
|
||||
** reduces the number of output rows by sqrt(2).
|
||||
** TUNING: For every WHERE clause term that is not used by the index
|
||||
** and which does not have an assigned truth probability, heuristics
|
||||
** described below are used to try to estimate the truth probability.
|
||||
** TODO --> Perhaps this is something that could be improved by better
|
||||
** table statistics.
|
||||
**
|
||||
** Heuristic 1: Estimate the truth probability as 93.75%. The 93.75%
|
||||
** value corresponds to -1 in LogEst notation, so this means decrement
|
||||
** the WhereLoop.nOut field for every such WHERE clause term.
|
||||
**
|
||||
** Heuristic 2: If there exists one or more WHERE clause terms of the
|
||||
** form "x==EXPR" and EXPR is not a constant 0 or 1, then make sure the
|
||||
** final output row estimate is no greater than 1/4 of the total number
|
||||
** of rows in the table. In other words, assume that x==EXPR will filter
|
||||
** out at least 3 out of 4 rows. If EXPR is -1 or 0 or 1, then maybe the
|
||||
** "x" column is boolean or else -1 or 0 or 1 is a common default value
|
||||
** on the "x" column and so in that case only cap the output row estimate
|
||||
** at 1/2 instead of 1/4.
|
||||
*/
|
||||
static void whereLoopOutputAdjust(
|
||||
WhereClause *pWC, /* The WHERE clause */
|
||||
@@ -4302,9 +4323,10 @@ static void whereLoopOutputAdjust(
|
||||
){
|
||||
WhereTerm *pTerm, *pX;
|
||||
Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
|
||||
int i, j;
|
||||
int nEq = 0; /* Number of = constraints not within likely()/unlikely() */
|
||||
int i, j, k;
|
||||
LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */
|
||||
|
||||
assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
|
||||
for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){
|
||||
if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break;
|
||||
if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
|
||||
@@ -4317,20 +4339,26 @@ static void whereLoopOutputAdjust(
|
||||
}
|
||||
if( j<0 ){
|
||||
if( pTerm->truthProb<=0 ){
|
||||
/* If a truth probability is specified using the likelihood() hints,
|
||||
** then use the probability provided by the application. */
|
||||
pLoop->nOut += pTerm->truthProb;
|
||||
}else{
|
||||
/* In the absence of explicit truth probabilities, use heuristics to
|
||||
** guess a reasonable truth probability. */
|
||||
pLoop->nOut--;
|
||||
if( pTerm->eOperator&WO_EQ ) nEq++;
|
||||
if( pTerm->eOperator&WO_EQ ){
|
||||
Expr *pRight = pTerm->pExpr->pRight;
|
||||
if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
|
||||
k = 10;
|
||||
}else{
|
||||
k = 20;
|
||||
}
|
||||
if( iReduce<k ) iReduce = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* TUNING: If there is at least one equality constraint in the WHERE
|
||||
** clause that does not have a likelihood() explicitly assigned to it
|
||||
** then do not let the estimated number of output rows exceed half
|
||||
** the number of rows in the table. */
|
||||
if( nEq && pLoop->nOut>nRow-10 ){
|
||||
pLoop->nOut = nRow - 10;
|
||||
}
|
||||
if( pLoop->nOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4587,6 +4615,7 @@ static int whereLoopAddBtreeIndex(
|
||||
assert( 42==sqlite3LogEst(18) );
|
||||
if( saved_nEq==saved_nSkip
|
||||
&& saved_nEq+1<pProbe->nKeyCol
|
||||
&& pProbe->noSkipScan==0
|
||||
&& pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
|
||||
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
|
||||
){
|
||||
|
@@ -224,48 +224,4 @@ do_execsql_test autoindex2-120 {
|
||||
# on t3 and reordering the tables so that t3 was in the outer loop and
|
||||
# implementing the ORDER BY clause using a B-Tree.
|
||||
|
||||
do_execsql_test autoindex2-120 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT
|
||||
t1_id,
|
||||
t1.did,
|
||||
param2,
|
||||
param3,
|
||||
t1.ptime,
|
||||
t1.trange,
|
||||
t1.exmass,
|
||||
t1.mass,
|
||||
t1.vstatus,
|
||||
type,
|
||||
subtype,
|
||||
t1.deviation,
|
||||
t1.formula,
|
||||
dparam1,
|
||||
reserve1,
|
||||
reserve2,
|
||||
param4,
|
||||
t1.last_operation,
|
||||
t1.admin_uuid,
|
||||
t1.previous_value,
|
||||
t1.job_id,
|
||||
client_did,
|
||||
t1.last_t1,
|
||||
t1.data_t1,
|
||||
t1.previous_date,
|
||||
param5,
|
||||
param6,
|
||||
mgr_uuid
|
||||
FROM
|
||||
t3,
|
||||
t2,
|
||||
t1
|
||||
WHERE
|
||||
t1.ptime > 1393520400
|
||||
AND param3<>9001
|
||||
AND t3.flg7 = 1
|
||||
AND t1.did = t2.did
|
||||
AND t2.uid = t3.uid
|
||||
ORDER BY t1.ptime desc LIMIT 500;
|
||||
} {0 0 2 {SEARCH TABLE t1 USING INDEX t1x1 (ptime>?)} 0 1 1 {SEARCH TABLE t2 USING INDEX t2x0 (did=?)} 0 2 0 {SEARCH TABLE t3 USING INDEX t3x0 (uid=?)}}
|
||||
|
||||
finish_test
|
||||
|
@@ -17,6 +17,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix autoindex3
|
||||
|
||||
# The t1b and t2d indexes are not very selective. It used to be that
|
||||
# the autoindex mechanism would create automatic indexes on t1(b) or
|
||||
@@ -54,5 +55,38 @@ do_execsql_test autoindex3-140 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE d IN (5,b) AND x=y;
|
||||
} {/AUTO/}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 210 {
|
||||
CREATE TABLE v(b, d, e);
|
||||
CREATE TABLE u(a, b, c);
|
||||
ANALYZE sqlite_master;
|
||||
INSERT INTO "sqlite_stat1" VALUES('u','uab','40000 400 1');
|
||||
INSERT INTO "sqlite_stat1" VALUES('v','vbde','40000 400 1 1');
|
||||
INSERT INTO "sqlite_stat1" VALUES('v','ve','40000 21');
|
||||
|
||||
CREATE INDEX uab on u(a, b);
|
||||
CREATE INDEX ve on v(e);
|
||||
CREATE INDEX vbde on v(b,d,e);
|
||||
|
||||
DROP TABLE IF EXISTS sqlite_stat4;
|
||||
ANALYZE sqlite_master;
|
||||
}
|
||||
|
||||
# At one point, SQLite was using the inferior plan:
|
||||
#
|
||||
# 0|0|1|SEARCH TABLE v USING INDEX ve (e>?)
|
||||
# 0|1|0|SEARCH TABLE u USING COVERING INDEX uab (ANY(a) AND b=?)
|
||||
#
|
||||
# on the basis that the real index "uab" must be better than the automatic
|
||||
# index. This is not right - a skip-scan is not necessarily better than an
|
||||
# automatic index scan.
|
||||
#
|
||||
do_eqp_test 220 {
|
||||
select count(*) from u, v where u.b = v.b and v.e > 34;
|
||||
} {
|
||||
0 0 1 {SEARCH TABLE v USING INDEX ve (e>?)}
|
||||
0 1 0 {SEARCH TABLE u USING AUTOMATIC COVERING INDEX (b=?)}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
43
test/bigsort.test
Normal file
43
test/bigsort.test
Normal file
@@ -0,0 +1,43 @@
|
||||
# 2014 November 26
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix bigsort
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# At one point there was an overflow problem if the product of the
|
||||
# cache-size and page-size was larger than 2^31. Causing an infinite
|
||||
# loop if the product was also an integer multiple of 2^32, or
|
||||
# inefficiency otherwise.
|
||||
#
|
||||
do_execsql_test 1.0 {
|
||||
PRAGMA page_size = 1024;
|
||||
CREATE TABLE t1(a, b);
|
||||
BEGIN;
|
||||
WITH data(x,y) AS (
|
||||
SELECT 1, zeroblob(10000)
|
||||
UNION ALL
|
||||
SELECT x+1, y FROM data WHERE x < 300000
|
||||
)
|
||||
INSERT INTO t1 SELECT * FROM data;
|
||||
COMMIT;
|
||||
}
|
||||
do_execsql_test 1.1 {
|
||||
PRAGMA cache_size = 4194304;
|
||||
CREATE INDEX i1 ON t1(a, b);
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
132
test/btree01.test
Normal file
132
test/btree01.test
Normal file
@@ -0,0 +1,132 @@
|
||||
# 2014-11-27
|
||||
#
|
||||
# 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 contains test cases for b-tree logic.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix btree01
|
||||
|
||||
# The refactoring on the b-tree balance() routine in check-in
|
||||
# http://www.sqlite.org/src/info/face33bea1ba3a (2014-10-27)
|
||||
# caused the integrity_check on the following SQL to fail.
|
||||
#
|
||||
do_execsql_test btree01-1.1 {
|
||||
PRAGMA page_size=65536;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB);
|
||||
WITH RECURSIVE
|
||||
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
|
||||
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
|
||||
UPDATE t1 SET b=zeroblob(3000);
|
||||
UPDATE t1 SET b=zeroblob(64000) WHERE a=2;
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
# The previous test is sufficient to prevent a regression. But we
|
||||
# add a number of additional tests to stress the balancer in similar
|
||||
# ways, looking for related problems.
|
||||
#
|
||||
for {set i 1} {$i<=30} {incr i} {
|
||||
do_test btree01-1.2.$i {
|
||||
db eval {
|
||||
DELETE FROM t1;
|
||||
WITH RECURSIVE
|
||||
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
|
||||
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
|
||||
UPDATE t1 SET b=zeroblob(3000);
|
||||
UPDATE t1 SET b=zeroblob(64000) WHERE a=$::i;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {ok}
|
||||
}
|
||||
for {set i 1} {$i<=30} {incr i} {
|
||||
do_test btree01-1.3.$i {
|
||||
db eval {
|
||||
DELETE FROM t1;
|
||||
WITH RECURSIVE
|
||||
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
|
||||
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
|
||||
UPDATE t1 SET b=zeroblob(2000);
|
||||
UPDATE t1 SET b=zeroblob(64000) WHERE a=$::i;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {ok}
|
||||
}
|
||||
for {set i 1} {$i<=30} {incr i} {
|
||||
do_test btree01-1.4.$i {
|
||||
db eval {
|
||||
DELETE FROM t1;
|
||||
WITH RECURSIVE
|
||||
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
|
||||
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
|
||||
UPDATE t1 SET b=zeroblob(6499) WHERE (a%3)==0;
|
||||
UPDATE t1 SET b=zeroblob(6499) WHERE (a%3)==1;
|
||||
UPDATE t1 SET b=zeroblob(6499) WHERE (a%3)==2;
|
||||
UPDATE t1 SET b=zeroblob(64000) WHERE a=$::i;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {ok}
|
||||
}
|
||||
for {set i 1} {$i<=30} {incr i} {
|
||||
do_test btree01-1.5.$i {
|
||||
db eval {
|
||||
DELETE FROM t1;
|
||||
WITH RECURSIVE
|
||||
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
|
||||
INSERT INTO t1(a,b) SELECT i, zeroblob(6542) FROM c;
|
||||
UPDATE t1 SET b=zeroblob(2331);
|
||||
UPDATE t1 SET b=zeroblob(65496) WHERE a=$::i;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {ok}
|
||||
}
|
||||
for {set i 1} {$i<=30} {incr i} {
|
||||
do_test btree01-1.6.$i {
|
||||
db eval {
|
||||
DELETE FROM t1;
|
||||
WITH RECURSIVE
|
||||
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
|
||||
INSERT INTO t1(a,b) SELECT i, zeroblob(6542) FROM c;
|
||||
UPDATE t1 SET b=zeroblob(2332);
|
||||
UPDATE t1 SET b=zeroblob(65496) WHERE a=$::i;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {ok}
|
||||
}
|
||||
for {set i 1} {$i<=30} {incr i} {
|
||||
do_test btree01-1.7.$i {
|
||||
db eval {
|
||||
DELETE FROM t1;
|
||||
WITH RECURSIVE
|
||||
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30)
|
||||
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
|
||||
UPDATE t1 SET b=zeroblob(1);
|
||||
UPDATE t1 SET b=zeroblob(65000) WHERE a=$::i;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {ok}
|
||||
}
|
||||
for {set i 1} {$i<=31} {incr i} {
|
||||
do_test btree01-1.8.$i {
|
||||
db eval {
|
||||
DELETE FROM t1;
|
||||
WITH RECURSIVE
|
||||
c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<31)
|
||||
INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c;
|
||||
UPDATE t1 SET b=zeroblob(4000);
|
||||
UPDATE t1 SET b=zeroblob(65000) WHERE a=$::i;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {ok}
|
||||
}
|
||||
|
||||
finish_test
|
@@ -116,6 +116,7 @@ set allquicktests [test_set $alltests -exclude {
|
||||
vtab_err.test walslow.test walcrash.test walcrash3.test
|
||||
walthread.test rtree3.test indexfault.test securedel2.test
|
||||
sort3.test sort4.test fts4growth.test fts4growth2.test
|
||||
bigsort.test
|
||||
}]
|
||||
if {[info exists ::env(QUICKTEST_INCLUDE)]} {
|
||||
set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]
|
||||
|
@@ -1190,13 +1190,13 @@ ifcapable schema_pragmas {
|
||||
execsql2 {
|
||||
pragma collation_list;
|
||||
}
|
||||
} {seq 0 name NOCASE seq 1 name RTRIM seq 2 name BINARY}
|
||||
} {seq 0 name RTRIM seq 1 name NOCASE seq 2 name BINARY}
|
||||
do_test pragma-11.2 {
|
||||
db collate New_Collation blah...
|
||||
execsql {
|
||||
pragma collation_list;
|
||||
}
|
||||
} {0 New_Collation 1 NOCASE 2 RTRIM 3 BINARY}
|
||||
} {0 New_Collation 1 RTRIM 2 NOCASE 3 BINARY}
|
||||
}
|
||||
|
||||
ifcapable schema_pragmas&&tempdb {
|
||||
|
@@ -268,7 +268,7 @@ do_scanstatus_test 4.2.2 {
|
||||
nLoop 1 nVisit 1 nEst 1.0 zName sqlite_autoindex_p1_1
|
||||
zExplain {SEARCH TABLE p1 USING INDEX sqlite_autoindex_p1_1 (x=?)}
|
||||
|
||||
nLoop 1 nVisit 3 nEst 524288.0 zName c1 zExplain {SCAN TABLE c1}
|
||||
nLoop 1 nVisit 3 nEst 262144.0 zName c1 zExplain {SCAN TABLE c1}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
@@ -45,20 +45,21 @@ do_test shell1-1.1.1 {
|
||||
list $rc \
|
||||
[regexp {Error: unknown option: -bad} $res]
|
||||
} {1 1}
|
||||
do_test shell1-1.1.1b {
|
||||
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 {
|
||||
set res [catchcmd "-bad test.db \"select 3\" \"select 4\"" ""]
|
||||
set rc [lindex $res 0]
|
||||
list $rc \
|
||||
[regexp {Error: too many options: "select 4"} $res]
|
||||
} {1 1}
|
||||
catchcmd "test.db \"select 3\" \"select 4\"" ""
|
||||
} {0 {3
|
||||
4}}
|
||||
# error on extra options
|
||||
do_test shell1-1.1.3 {
|
||||
set res [catchcmd "-bad FOO test.db BAD" ".quit"]
|
||||
set rc [lindex $res 0]
|
||||
list $rc \
|
||||
[regexp {Error: too many options: "BAD"} $res]
|
||||
} {1 1}
|
||||
catchcmd "test.db FOO test.db BAD" ".quit"
|
||||
} {1 {Error: near "FOO": syntax error}}
|
||||
|
||||
# -help
|
||||
do_test shell1-1.2.1 {
|
||||
@@ -75,11 +76,11 @@ do_test shell1-1.3.1 {
|
||||
catchcmd "-init FOO test.db" ""
|
||||
} {0 {}}
|
||||
do_test shell1-1.3.2 {
|
||||
set res [catchcmd "-init FOO test.db .quit BAD" ""]
|
||||
set rc [lindex $res 0]
|
||||
list $rc \
|
||||
[regexp {Error: too many options: "BAD"} $res]
|
||||
} {1 1}
|
||||
catchcmd "-init FOO test.db .quit BAD" ""
|
||||
} {0 {}}
|
||||
do_test shell1-1.3.3 {
|
||||
catchcmd "-init FOO test.db BAD .quit" ""
|
||||
} {1 {Error: near "BAD": syntax error}}
|
||||
|
||||
# -echo print commands before execution
|
||||
do_test shell1-1.4.1 {
|
||||
|
@@ -52,9 +52,9 @@ do_test shell2-1.1.1 {
|
||||
# Ticket [f5cb008a65].
|
||||
do_test shell2-1.2.1 {
|
||||
set rc [catch { eval exec $CLI \":memory:\" \"select 3\" \"select 4\" } msg]
|
||||
list $rc \
|
||||
[regexp {Error: too many options: "select 4"} $msg]
|
||||
} {1 1}
|
||||
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")
|
||||
|
@@ -273,4 +273,23 @@ do_execsql_test skipscan1-6.3 {
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
|
||||
} {~/ANY/}
|
||||
|
||||
# If the sqlite_stat1 entry includes the "noskipscan" token, then never use
|
||||
# skipscan with that index.
|
||||
#
|
||||
do_execsql_test skipscan1-7.1 {
|
||||
UPDATE sqlite_stat1 SET stat='500000 125000 1 sz=100';
|
||||
ANALYZE sqlite_master;
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
|
||||
} {/ANY/}
|
||||
do_execsql_test skipscan1-7.2 {
|
||||
UPDATE sqlite_stat1 SET stat='500000 125000 1 noskipscan sz=100';
|
||||
ANALYZE sqlite_master;
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
|
||||
} {~/ANY/}
|
||||
do_execsql_test skipscan1-7.3 {
|
||||
UPDATE sqlite_stat1 SET stat='500000 125000 1 sz=100 noskipscan';
|
||||
ANALYZE sqlite_master;
|
||||
EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
|
||||
} {~/ANY/}
|
||||
|
||||
finish_test
|
||||
|
@@ -1395,4 +1395,46 @@ do_execsql_test 21.3 {
|
||||
SELECT * FROM t9v WHERE a=b;
|
||||
} {2 2 2}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# At one point executing a CREATE VIRTUAL TABLE statement that specified
|
||||
# a database name but no virtual table arguments was causing an internal
|
||||
# buffer overread. Valgrind would report errors while running the following
|
||||
# tests. Specifically:
|
||||
#
|
||||
# CREATE VIRTUAL TABLE t1 USING fts4; -- Ok - no db name.
|
||||
# CREATE VIRTUAL TABLE main.t1 USING fts4(x); -- Ok - has vtab arguments.
|
||||
# CREATE VIRTUAL TABLE main.t1 USING fts4; -- Had the problem.
|
||||
#
|
||||
ifcapable fts3 {
|
||||
forcedelete test.db2
|
||||
set nm [string repeat abcdefghij 100]
|
||||
do_execsql_test 22.1 {
|
||||
ATTACH 'test.db2' AS $nm
|
||||
}
|
||||
|
||||
execsql "SELECT * FROM sqlite_master"
|
||||
do_execsql_test 22.2 "CREATE VIRTUAL TABLE ${nm}.t1 USING fts4"
|
||||
|
||||
do_test 22.3.1 {
|
||||
set sql "CREATE VIRTUAL TABLE ${nm}.t2 USING fts4"
|
||||
set stmt [sqlite3_prepare_v2 db $sql -1 dummy]
|
||||
sqlite3_step $stmt
|
||||
} {SQLITE_DONE}
|
||||
|
||||
do_test 22.3.2 {
|
||||
sqlite3_finalize $stmt
|
||||
} {SQLITE_OK}
|
||||
|
||||
do_test 22.4.1 {
|
||||
set sql "CREATE VIRTUAL TABLE ${nm}.t3 USING fts4"
|
||||
set n [string length $sql]
|
||||
set stmt [sqlite3_prepare db "${sql}xyz" $n dummy]
|
||||
sqlite3_step $stmt
|
||||
} {SQLITE_DONE}
|
||||
|
||||
do_test 22.4.2 {
|
||||
sqlite3_finalize $stmt
|
||||
} {SQLITE_OK}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
Reference in New Issue
Block a user