mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Merge the pre-3.8.6 changes into the threads branch.
FossilOrigin-Name: a608fd1d52606a009c3acc7f1d184b86a7df3c82
This commit is contained in:
@ -318,7 +318,7 @@ static int unicodeNext(
|
||||
){
|
||||
unicode_cursor *pCsr = (unicode_cursor *)pC;
|
||||
unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer);
|
||||
int iCode;
|
||||
int iCode = 0;
|
||||
char *zOut;
|
||||
const unsigned char *z = &pCsr->aInput[pCsr->iOff];
|
||||
const unsigned char *zStart = z;
|
||||
|
@ -39,7 +39,7 @@ int sqlite3FtsUnicodeIsalnum(int c){
|
||||
** C. It is not possible to represent a range larger than 1023 codepoints
|
||||
** using this format.
|
||||
*/
|
||||
const static unsigned int aEntry[] = {
|
||||
static const unsigned int aEntry[] = {
|
||||
0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
|
||||
0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
|
||||
0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
|
||||
@ -131,7 +131,7 @@ int sqlite3FtsUnicodeIsalnum(int c){
|
||||
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
|
||||
}else if( c<(1<<22) ){
|
||||
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
|
||||
int iRes;
|
||||
int iRes = 0;
|
||||
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
|
||||
int iLo = 0;
|
||||
while( iHi>=iLo ){
|
||||
@ -202,7 +202,7 @@ static int remove_diacritic(int c){
|
||||
}
|
||||
assert( key>=aDia[iRes] );
|
||||
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
@ -160,7 +160,7 @@ proc print_rd {map} {
|
||||
}
|
||||
assert( key>=aDia[iRes] );
|
||||
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);}
|
||||
puts "\};"
|
||||
puts "\}"
|
||||
}
|
||||
|
||||
proc print_isdiacritic {zFunc map} {
|
||||
@ -298,7 +298,7 @@ proc an_print_range_array {lRange} {
|
||||
** using this format.
|
||||
*/
|
||||
}]
|
||||
puts -nonewline " const static unsigned int aEntry\[\] = \{"
|
||||
puts -nonewline " static const unsigned int aEntry\[\] = \{"
|
||||
set i 0
|
||||
foreach range $lRange {
|
||||
foreach {iFirst nRange} $range {}
|
||||
@ -349,7 +349,7 @@ proc print_isalnum {zFunc lRange} {
|
||||
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
|
||||
}else if( c<(1<<22) ){
|
||||
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
|
||||
int iRes;
|
||||
int iRes = 0;
|
||||
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
|
||||
int iLo = 0;
|
||||
while( iHi>=iLo ){
|
||||
@ -732,7 +732,7 @@ proc print_fileheader {} {
|
||||
*/
|
||||
}]
|
||||
puts ""
|
||||
puts "#if defined(SQLITE_ENABLE_FTS4_UNICODE61)"
|
||||
puts "#ifndef SQLITE_DISABLE_FTS3_UNICODE"
|
||||
puts "#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)"
|
||||
puts ""
|
||||
puts "#include <assert.h>"
|
||||
@ -808,4 +808,4 @@ if {$::generate_test_code} {
|
||||
}
|
||||
|
||||
puts "#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */"
|
||||
puts "#endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */"
|
||||
puts "#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */"
|
||||
|
@ -61,7 +61,6 @@ static void writefileFunc(
|
||||
){
|
||||
FILE *out;
|
||||
const char *z;
|
||||
int n;
|
||||
sqlite3_int64 rc;
|
||||
const char *zFile;
|
||||
|
||||
@ -71,11 +70,9 @@ static void writefileFunc(
|
||||
if( out==0 ) return;
|
||||
z = (const char*)sqlite3_value_blob(argv[1]);
|
||||
if( z==0 ){
|
||||
n = 0;
|
||||
rc = 0;
|
||||
}else{
|
||||
n = sqlite3_value_bytes(argv[1]);
|
||||
rc = fwrite(z, 1, n, out);
|
||||
rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
|
||||
}
|
||||
fclose(out);
|
||||
sqlite3_result_int64(context, rc);
|
||||
|
65
manifest
65
manifest
@ -1,5 +1,5 @@
|
||||
C Merge\sall\srecent\schanges\sfrom\strunk.
|
||||
D 2014-08-06T02:03:35.291
|
||||
C Merge\sthe\spre-3.8.6\schanges\sinto\sthe\sthreads\sbranch.
|
||||
D 2014-08-14T14:02:48.852
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -94,22 +94,22 @@ F ext/fts3/fts3_tokenize_vtab.c 011170fe9eba5ff062f1a31d3188e00267716706
|
||||
F ext/fts3/fts3_tokenizer.c bbdc731bc91338050675c6d1da9ab82147391e16
|
||||
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c e80eef8a11f2020dc9c1eb95c5b405b9012f2fbe
|
||||
F ext/fts3/fts3_unicode2.c c8adda75aad0c6c252ef3dd555f811f437485044
|
||||
F ext/fts3/fts3_unicode.c a93f5edc0aff44ef8b06d7cb55b52026541ca145
|
||||
F ext/fts3/fts3_unicode2.c c3d01968d497bd7001e7dc774ba75b372738c057
|
||||
F ext/fts3/fts3_write.c 8260388626516a7005d06a9dce94f9e55c6c2a41
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3view.c 3986531f2fc0ceca0c89c31ec7d0589b6adb19d6
|
||||
F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
|
||||
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
|
||||
F ext/fts3/unicode/mkunicode.tcl dc6f268eb526710e2c6e496c372471d773d0c368
|
||||
F ext/fts3/unicode/mkunicode.tcl a2567f9d6ad6779879a2e394c120ad8718557e65
|
||||
F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
|
||||
F ext/icu/icu.c d415ccf984defeb9df2c0e1afcfaa2f6dc05eacb
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/misc/amatch.c 678056a4bfcd83c4e82dea81d37543cd1d6dbee1
|
||||
F ext/misc/closure.c 636024302cde41b2bf0c542f81c40c624cfb7012
|
||||
F ext/misc/compress.c 76e45655f4046e756064ab10c62e18f2eb846b9f
|
||||
F ext/misc/fileio.c beea82bb5055b6590cffe2d2e6d922905894f691
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
F ext/misc/fuzzer.c 136533c53cfce0957f0b48fa11dba27e21c5c01d
|
||||
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
@ -179,17 +179,17 @@ F src/delete.c bcf8f72126cea80fc3d5bc5494cf19b3f8935aaf
|
||||
F src/expr.c f749009cf4a8534efb5e0d5cd7c9fb1fb0f2836c
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 8545f3b36da47473e10800ea4fb0810fd4062514
|
||||
F src/func.c 3bc223ea36cd29a91c481485343d0ee4257ab8dc
|
||||
F src/func.c bbb724b74ed96ca42675a7274646a71dd52bcda7
|
||||
F src/global.c 77ec119d6f6453039c2820336af8e8f804f20acf
|
||||
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
|
||||
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c 991e4964e9295da3993e2c0f81c7faf642371848
|
||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
||||
F src/legacy.c febc2a9e7ad6c1a6191c7b5b9170b325d263f343
|
||||
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
||||
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
|
||||
F src/main.c 42ba5977d1c4324620b2ef2bc05b7bb28a2331e4
|
||||
F src/main.c 333a7134a4e08f7660c4e52390eda99c49493ba6
|
||||
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
|
||||
@ -207,8 +207,8 @@ F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
|
||||
F src/os.h 60d419395e32a8029fa380a80a3da2e9030f635e
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c a7baf1b30f3c58ba20b813e01aab23b18ae44f85
|
||||
F src/os_win.c 9a7fda788394109131677a9fceee8d54820b6c16
|
||||
F src/os_unix.c bd7df3094a60915c148517504c76df4fca24e542
|
||||
F src/os_win.c 058cefbeb0f9713b7cc161c6d09e5a1770d26e11
|
||||
F src/os_win.h 057344a6720b4c8405d9bd98f58cb37a6ee46c25
|
||||
F src/pager.c f6bb1fa6cdf2062f2d8aec3e64db302bca519ab8
|
||||
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
|
||||
@ -220,12 +220,12 @@ F src/pragma.c d10ef67c4de79f78188b965b4b7988aff1d66f2e
|
||||
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
|
||||
F src/printf.c af06f66927919730f03479fed6ae9854f73419f4
|
||||
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
|
||||
F src/resolve.c 5fc110baeacf120a73fe34e103f052632ff11a02
|
||||
F src/resolve.c 0ea356d32a5e884add23d1b9b4e8736681dd5697
|
||||
F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
|
||||
F src/select.c c28f5165280ea7214285e4c53a23b257e1a06127
|
||||
F src/shell.c 05e9e7f667a6340643b647c4be0db15dd7627d92
|
||||
F src/sqlite.h.in 44b761ddf5362581617d08457f11ee582eb103a2
|
||||
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
||||
F src/select.c f8b0b6c43bee15f4e239ead1c9c9e3009e507e39
|
||||
F src/shell.c 26f8ef7f52b26644bb9098c62cee8694c17b3259
|
||||
F src/sqlite.h.in fef15a64d1358f5c365bd3f46f4c1915d5a5e5f0
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||
F src/sqliteInt.h b500ee46173fb510f8e10891a58bbf8e657bb3e6
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
@ -284,11 +284,11 @@ F src/update.c ea336ce7b8b3fc5e316ba8f082e6445babf81059
|
||||
F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05
|
||||
F src/util.c 3076bdd51cdbf60a6e2e57fada745be37133c73e
|
||||
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
||||
F src/vdbe.c 787d1b5178abaf44600702f6976a927d79ce3a92
|
||||
F src/vdbe.c aae4addde348f8a8d94a907f41c4524b7e2e0529
|
||||
F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8
|
||||
F src/vdbeInt.h 8870adf012235708f125f8cd1c988f487dc3eb6f
|
||||
F src/vdbeapi.c 24e40422382beb774daab11fe9fe9d37e8a04949
|
||||
F src/vdbeaux.c 3f1d2baa4a8cbdad33cb255a5f4fd1af7a414683
|
||||
F src/vdbeaux.c 142fdb31f6423fb3c66a7b0687dbf894a259b1cf
|
||||
F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac
|
||||
F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394
|
||||
F src/vdbesort.c b9a830685826c057cfd41993902a5afc6fe436e1
|
||||
@ -297,8 +297,8 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
|
||||
F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
|
||||
F src/where.c ce1b9a3a2573033cd15e0882719db7f211f21cdd
|
||||
F src/whereInt.h 929c1349b5355fd44f22cee5c14d72b3329c58a6
|
||||
F src/where.c ab20f9c24a422ee8900831b343c3d1e5e7aca87b
|
||||
F src/whereInt.h 923820bee9726033a501a08d2fc69b9c1ee4feb3
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||
@ -443,11 +443,11 @@ F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
|
||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||
F test/distinct.test 086e70c765f172e8974e9f83b9ac5ca03c154e77
|
||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||
F test/e_createtable.test ed82efcedc4b3656b27a5fcd12335cdb7e20eeee
|
||||
F test/e_createtable.test 181653f6f45e3adde73f8686600ce5ad7515466b
|
||||
F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a
|
||||
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
|
||||
F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306
|
||||
F test/e_expr.test 5c71d183fbf519a4769fd2e2124afdc70b5b1f42
|
||||
F test/e_expr.test 8f5fdd7261e2d746813b0c6a1c0e34824ad3c5ad
|
||||
F test/e_fkey.test a1783fe1f759e1990e6a11adfcf0702dac4d0707
|
||||
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
||||
F test/e_insert.test 7b2fa9cd1456f83474d6c5d27db3abaeb8be2023
|
||||
@ -590,7 +590,7 @@ F test/fts4unicode.test 01ec3fe2a7c3cfff3b4c0581b83caa11b33efa36
|
||||
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
|
||||
F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef
|
||||
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
|
||||
F test/func3.test e82d16b13739f1a0c5efb20048583c79b767b625
|
||||
F test/func3.test d202a7606d23f90988a664e88e268aed1087c11c
|
||||
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
|
||||
F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4
|
||||
F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74
|
||||
@ -614,7 +614,7 @@ F test/incrblob.test e81846d214f3637622620fbde7cd526781cfe328
|
||||
F test/incrblob2.test bf4d549aa4a466d7fbe3e3a3693d3861263d5600
|
||||
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
|
||||
F test/incrblob4.test f26502a5697893e5acea268c910f16478c2f0fab
|
||||
F test/incrblob_err.test d2562d2771ebffd4b3af89ef64c140dd44371597
|
||||
F test/incrblob_err.test af1f12ba60d220c9752073ff2bda2ad59e88960d
|
||||
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
|
||||
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
|
||||
F test/incrvacuum2.test 379eeb8740b0ef60c372c439ad4cbea20b34bb9b
|
||||
@ -677,7 +677,7 @@ F test/lock_common.tcl 0c270b121d40959fa2f3add382200c27045b3d95
|
||||
F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2
|
||||
F test/main.test 39c4bb8a157f57298ed1659d6df89d9f35aaf2c8
|
||||
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
|
||||
F test/malloc.test ada8ae15193ffc6415bf431a6db31d4ec507dbfe
|
||||
F test/malloc.test 96939d2d1a6f39667bbebe5bc27c6525f2ab614e
|
||||
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
|
||||
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
|
||||
F test/malloc5.test fafce0aa9157060445cd1a56ad50fc79d82f28c3
|
||||
@ -697,7 +697,8 @@ F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb
|
||||
F test/mallocI.test a88c2b9627c8506bf4703d8397420043a786cdb6
|
||||
F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
|
||||
F test/mallocK.test 3cff7c0f64735f6883bacdd294e45a6ed5714817
|
||||
F test/malloc_common.tcl 58e54229c4132ef882a11fab6419ec4cd3073589
|
||||
F test/mallocL.test 252ddc7eb4fbf75364eab17b938816085ff1fc17
|
||||
F test/malloc_common.tcl 3663f9001ce3e29bbaa9677ffe15cd468e3ec7e3
|
||||
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test fcb5297b321b562084fc79d64d5a12a1cd2b639b
|
||||
@ -773,7 +774,7 @@ F test/rdonly.test dd30a4858d8e0fbad2304c2bd74a33d4df36412a
|
||||
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
|
||||
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
|
||||
F test/releasetest.mk 2eced2f9ae701fd0a29e714a241760503ccba25a
|
||||
F test/releasetest.tcl 06d289d8255794073a58d2850742f627924545ce
|
||||
F test/releasetest.tcl a0df0dfc5e3ee83ade87b9cc96db41b52d590b9e
|
||||
F test/resolver01.test 33abf37ff8335e6bf98f2b45a0af3e06996ccd9a
|
||||
F test/rollback.test e9504a009a202c3ed711da2e6879ff60c5a4669c
|
||||
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
|
||||
@ -1112,7 +1113,7 @@ F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
||||
F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
|
||||
F test/where8.test 806f1dcec4088be2b826b33f757fe6e17c3236a1
|
||||
F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
|
||||
F test/where9.test 4f3eab951353a3ae164befc521c777dfa903e46c
|
||||
F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2
|
||||
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
|
||||
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
|
||||
F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a
|
||||
@ -1122,7 +1123,7 @@ F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
|
||||
F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3
|
||||
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
|
||||
F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622
|
||||
F test/whereJ.test 7dde28284d20f358b559ca592e294db03e1d7103
|
||||
F test/whereJ.test 35a40a50d0e13aa6b0de7cc5d4b204e5f9f9669f
|
||||
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
|
||||
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
|
||||
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
|
||||
@ -1190,7 +1191,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 655d8cfc752b3f5f63521a57f2155f8e14aaf7c4 717245d48714c08156c9b7636aaa6c3a402bad66
|
||||
R 522f9cbdadcee03fc45f476dbd20c9a7
|
||||
P a353a8515fb2eff86042d0c33e39772f4d04e0b3 13a2d90a2869c53b79754de39045bbbdbc7688e3
|
||||
R 64b417b620c9f6c58aeb23fe611b07d3
|
||||
U drh
|
||||
Z 56e08fa149f3ad8b1a6753df47adb03f
|
||||
Z b2ed58163bf8c58a60958e9dca71f3dd
|
||||
|
@ -1 +1 @@
|
||||
a353a8515fb2eff86042d0c33e39772f4d04e0b3
|
||||
a608fd1d52606a009c3acc7f1d184b86a7df3c82
|
@ -9,12 +9,9 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file contains the C functions that implement various SQL
|
||||
** functions of SQLite.
|
||||
**
|
||||
** There is only one exported symbol in this file - the function
|
||||
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
|
||||
** All other code has file scope.
|
||||
** This file contains the C-language implementions for many of the SQL
|
||||
** functions of SQLite. (Some function, and in particular the date and
|
||||
** time functions, are implemented separately.)
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <stdlib.h>
|
||||
|
@ -96,6 +96,9 @@ int sqlite3_exec(
|
||||
}
|
||||
}
|
||||
if( xCallback(pArg, nCol, azVals, azCols) ){
|
||||
/* EVIDENCE-OF: R-38229-40159 If the callback function to
|
||||
** sqlite3_exec() returns non-zero, then sqlite3_exec() will
|
||||
** return SQLITE_ABORT. */
|
||||
rc = SQLITE_ABORT;
|
||||
sqlite3VdbeFinalize((Vdbe *)pStmt);
|
||||
pStmt = 0;
|
||||
|
@ -836,6 +836,8 @@ static int connectionIsBusy(sqlite3 *db){
|
||||
*/
|
||||
static int sqlite3Close(sqlite3 *db, int forceZombie){
|
||||
if( !db ){
|
||||
/* EVIDENCE-OF: R-63257-11740 Calling sqlite3_close() or
|
||||
** sqlite3_close_v2() with a NULL pointer argument is a harmless no-op. */
|
||||
return SQLITE_OK;
|
||||
}
|
||||
if( !sqlite3SafetyCheckSickOrOk(db) ){
|
||||
@ -1065,7 +1067,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
|
||||
** Return a static string containing the name corresponding to the error code
|
||||
** specified in the argument.
|
||||
*/
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
#if (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) || defined(SQLITE_TEST)
|
||||
const char *sqlite3ErrName(int rc){
|
||||
const char *zName = 0;
|
||||
int i, origRc = rc;
|
||||
@ -1100,7 +1102,6 @@ const char *sqlite3ErrName(int rc){
|
||||
case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break;
|
||||
case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break;
|
||||
case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break;
|
||||
case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break;
|
||||
case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break;
|
||||
case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break;
|
||||
case SQLITE_IOERR_CHECKRESERVEDLOCK:
|
||||
@ -2085,7 +2086,7 @@ static const int aHardLimit[] = {
|
||||
SQLITE_MAX_FUNCTION_ARG,
|
||||
SQLITE_MAX_ATTACHED,
|
||||
SQLITE_MAX_LIKE_PATTERN_LENGTH,
|
||||
SQLITE_MAX_VARIABLE_NUMBER,
|
||||
SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */
|
||||
SQLITE_MAX_TRIGGER_DEPTH,
|
||||
};
|
||||
|
||||
|
@ -94,11 +94,10 @@
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
|
||||
#include <sys/mman.h>
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS
|
||||
# include <sys/ioctl.h>
|
||||
# if OS_VXWORKS
|
||||
# include <semaphore.h>
|
||||
@ -318,7 +317,11 @@ static int posixOpen(const char *zFile, int flags, int mode){
|
||||
** we are not running as root.
|
||||
*/
|
||||
static int posixFchown(int fd, uid_t uid, gid_t gid){
|
||||
#if OS_VXWORKS
|
||||
return 0;
|
||||
#else
|
||||
return geteuid() ? 0 : fchown(fd,uid,gid);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Forward reference */
|
||||
@ -374,7 +377,7 @@ static struct unix_syscall {
|
||||
{ "read", (sqlite3_syscall_ptr)read, 0 },
|
||||
#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)
|
||||
|
||||
#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
|
||||
#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
|
||||
{ "pread", (sqlite3_syscall_ptr)pread, 0 },
|
||||
#else
|
||||
{ "pread", (sqlite3_syscall_ptr)0, 0 },
|
||||
@ -391,7 +394,7 @@ static struct unix_syscall {
|
||||
{ "write", (sqlite3_syscall_ptr)write, 0 },
|
||||
#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
|
||||
|
||||
#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
|
||||
#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
|
||||
{ "pwrite", (sqlite3_syscall_ptr)pwrite, 0 },
|
||||
#else
|
||||
{ "pwrite", (sqlite3_syscall_ptr)0, 0 },
|
||||
@ -761,16 +764,6 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
|
||||
case EPERM:
|
||||
return SQLITE_PERM;
|
||||
|
||||
/* EDEADLK is only possible if a call to fcntl(F_SETLKW) is made. And
|
||||
** this module never makes such a call. And the code in SQLite itself
|
||||
** asserts that SQLITE_IOERR_BLOCKED is never returned. For these reasons
|
||||
** this case is also commented out. If the system does set errno to EDEADLK,
|
||||
** the default SQLITE_IOERR_XXX code will be returned. */
|
||||
#if 0
|
||||
case EDEADLK:
|
||||
return SQLITE_IOERR_BLOCKED;
|
||||
#endif
|
||||
|
||||
#if EOPNOTSUPP!=ENOTSUP
|
||||
case EOPNOTSUPP:
|
||||
/* something went terribly awry, unless during file system support
|
||||
@ -1303,9 +1296,13 @@ static int findInodeInfo(
|
||||
** Return TRUE if pFile has been renamed or unlinked since it was first opened.
|
||||
*/
|
||||
static int fileHasMoved(unixFile *pFile){
|
||||
#if OS_VXWORKS
|
||||
return pFile->pInode!=0 && pFile->pId!=pFile->pInode->fileId.pId;
|
||||
#else
|
||||
struct stat buf;
|
||||
return pFile->pInode!=0 &&
|
||||
(osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino);
|
||||
(osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -2448,7 +2445,6 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
||||
/* Otherwise see if some other process holds it. */
|
||||
if( !reserved ){
|
||||
sem_t *pSem = pFile->pInode->pSem;
|
||||
struct stat statBuf;
|
||||
|
||||
if( sem_trywait(pSem)==-1 ){
|
||||
int tErrno = errno;
|
||||
@ -2501,7 +2497,6 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
||||
*/
|
||||
static int semLock(sqlite3_file *id, int eFileLock) {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
int fd;
|
||||
sem_t *pSem = pFile->pInode->pSem;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
@ -5888,7 +5883,11 @@ static int unixDelete(
|
||||
UNUSED_PARAMETER(NotUsed);
|
||||
SimulateIOError(return SQLITE_IOERR_DELETE);
|
||||
if( osUnlink(zPath)==(-1) ){
|
||||
if( errno==ENOENT ){
|
||||
if( errno==ENOENT
|
||||
#if OS_VXWORKS
|
||||
|| errno==0x380003
|
||||
#endif
|
||||
){
|
||||
rc = SQLITE_IOERR_DELETE_NOENT;
|
||||
}else{
|
||||
rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
|
||||
|
40
src/os_win.c
40
src/os_win.c
@ -72,18 +72,14 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Check if the GetVersionEx[AW] functions should be considered deprecated
|
||||
** and avoid using them in that case. It should be noted here that if the
|
||||
** value of the SQLITE_WIN32_GETVERSIONEX pre-processor macro is zero
|
||||
** (whether via this block or via being manually specified), that implies
|
||||
** the underlying operating system will always be based on the Windows NT
|
||||
** Kernel.
|
||||
** Check to see if the GetVersionEx[AW] functions are deprecated on the
|
||||
** target system. GetVersionEx was first deprecated in Win8.1.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_GETVERSIONEX
|
||||
# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE
|
||||
# define SQLITE_WIN32_GETVERSIONEX 0
|
||||
# define SQLITE_WIN32_GETVERSIONEX 0 /* GetVersionEx() is deprecated */
|
||||
# else
|
||||
# define SQLITE_WIN32_GETVERSIONEX 1
|
||||
# define SQLITE_WIN32_GETVERSIONEX 1 /* GetVersionEx() is current */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -155,7 +151,7 @@
|
||||
** [sometimes] not used by the code (e.g. via conditional compilation).
|
||||
*/
|
||||
#ifndef UNUSED_VARIABLE_VALUE
|
||||
# define UNUSED_VARIABLE_VALUE(x) (void)(x)
|
||||
# define UNUSED_VARIABLE_VALUE(x) (void)(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1043,10 +1039,21 @@ static struct win_syscall {
|
||||
#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
|
||||
LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
|
||||
|
||||
/*
|
||||
** NOTE: On some sub-platforms, the InterlockedCompareExchange "function"
|
||||
** is really just a macro that uses a compiler intrinsic (e.g. x64).
|
||||
** So do not try to make this is into a redefinable interface.
|
||||
*/
|
||||
#if defined(InterlockedCompareExchange)
|
||||
{ "InterlockedCompareExchange", (SYSCALL)0, 0 },
|
||||
|
||||
#define osInterlockedCompareExchange InterlockedCompareExchange
|
||||
#else
|
||||
{ "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 },
|
||||
|
||||
#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG volatile*, \
|
||||
LONG,LONG))aSyscall[76].pCurrent)
|
||||
#endif /* defined(InterlockedCompareExchange) */
|
||||
|
||||
}; /* End of the overrideable system calls */
|
||||
|
||||
@ -1313,20 +1320,29 @@ DWORD sqlite3Win32Wait(HANDLE hObject){
|
||||
** based on the NT kernel.
|
||||
*/
|
||||
int sqlite3_win32_is_nt(void){
|
||||
#if defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
|
||||
if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){
|
||||
#if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8
|
||||
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
|
||||
defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8
|
||||
OSVERSIONINFOW sInfo;
|
||||
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
|
||||
osGetVersionExW(&sInfo);
|
||||
#else
|
||||
osInterlockedCompareExchange(&sqlite3_os_type,
|
||||
(sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
|
||||
#elif defined(SQLITE_WIN32_HAS_ANSI)
|
||||
OSVERSIONINFOA sInfo;
|
||||
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
|
||||
osGetVersionExA(&sInfo);
|
||||
#endif
|
||||
osInterlockedCompareExchange(&sqlite3_os_type,
|
||||
(sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
|
||||
#endif
|
||||
}
|
||||
return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
|
||||
#elif SQLITE_TEST
|
||||
return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SQLITE_WIN32_MALLOC
|
||||
|
@ -354,7 +354,7 @@ static int lookupName(
|
||||
}
|
||||
}
|
||||
if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
|
||||
/* IMP: R-24309-18625 */
|
||||
/* IMP: R-51414-32910 */
|
||||
/* IMP: R-44911-55124 */
|
||||
iCol = -1;
|
||||
}
|
||||
@ -710,7 +710,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
/* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to
|
||||
** likelihood(X, 0.0625).
|
||||
** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
|
||||
** likelihood(X,0.0625). */
|
||||
** likelihood(X,0.0625).
|
||||
** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for
|
||||
** likelihood(X,0.9375).
|
||||
** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to
|
||||
** likelihood(X,0.9375). */
|
||||
/* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */
|
||||
pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938;
|
||||
}
|
||||
|
@ -732,7 +732,7 @@ static void selectInnerLoop(
|
||||
sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
|
||||
}
|
||||
assert( sqlite3VdbeCurrentAddr(v)==iJump );
|
||||
assert( sqlite3VdbeCurrentAddr(v)==iJump || pParse->db->mallocFailed );
|
||||
sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nResultCol-1);
|
||||
break;
|
||||
}
|
||||
|
10
src/shell.c
10
src/shell.c
@ -1694,7 +1694,6 @@ static void writefileFunc(
|
||||
){
|
||||
FILE *out;
|
||||
const char *z;
|
||||
int n;
|
||||
sqlite3_int64 rc;
|
||||
const char *zFile;
|
||||
|
||||
@ -1704,11 +1703,9 @@ static void writefileFunc(
|
||||
if( out==0 ) return;
|
||||
z = (const char*)sqlite3_value_blob(argv[1]);
|
||||
if( z==0 ){
|
||||
n = 0;
|
||||
rc = 0;
|
||||
}else{
|
||||
n = sqlite3_value_bytes(argv[1]);
|
||||
rc = fwrite(z, 1, n, out);
|
||||
rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
|
||||
}
|
||||
fclose(out);
|
||||
sqlite3_result_int64(context, rc);
|
||||
@ -3126,7 +3123,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
&& (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
|
||||
){
|
||||
char *zCmd;
|
||||
int i;
|
||||
int i, x;
|
||||
if( nArg<2 ){
|
||||
fprintf(stderr, "Usage: .system COMMAND\n");
|
||||
rc = 1;
|
||||
@ -3137,8 +3134,9 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
|
||||
zCmd, azArg[i]);
|
||||
}
|
||||
(void)system(zCmd);
|
||||
x = system(zCmd);
|
||||
sqlite3_free(zCmd);
|
||||
if( x ) fprintf(stderr, "System command returns %d\n", x);
|
||||
}else
|
||||
|
||||
if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
|
||||
|
@ -264,7 +264,7 @@ typedef sqlite_uint64 sqlite3_uint64;
|
||||
**
|
||||
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
|
||||
** for the [sqlite3] object.
|
||||
** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if
|
||||
** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
|
||||
** the [sqlite3] object is successfully destroyed and all associated
|
||||
** resources are deallocated.
|
||||
**
|
||||
@ -272,7 +272,7 @@ typedef sqlite_uint64 sqlite3_uint64;
|
||||
** statements or unfinished sqlite3_backup objects then sqlite3_close()
|
||||
** will leave the database connection open and return [SQLITE_BUSY].
|
||||
** ^If sqlite3_close_v2() is called with unfinalized prepared statements
|
||||
** and unfinished sqlite3_backups, then the database connection becomes
|
||||
** and/or unfinished sqlite3_backups, then the database connection becomes
|
||||
** an unusable "zombie" which will automatically be deallocated when the
|
||||
** last prepared statement is finalized or the last sqlite3_backup is
|
||||
** finished. The sqlite3_close_v2() interface is intended for use with
|
||||
@ -285,7 +285,7 @@ typedef sqlite_uint64 sqlite3_uint64;
|
||||
** with the [sqlite3] object prior to attempting to close the object. ^If
|
||||
** sqlite3_close_v2() is called on a [database connection] that still has
|
||||
** outstanding [prepared statements], [BLOB handles], and/or
|
||||
** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
|
||||
** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
|
||||
** of resources is deferred until all [prepared statements], [BLOB handles],
|
||||
** and [sqlite3_backup] objects are also destroyed.
|
||||
**
|
||||
@ -381,16 +381,14 @@ int sqlite3_exec(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Result Codes
|
||||
** KEYWORDS: SQLITE_OK {error code} {error codes}
|
||||
** KEYWORDS: {result code} {result codes}
|
||||
** KEYWORDS: {result code definitions}
|
||||
**
|
||||
** Many SQLite functions return an integer result code from the set shown
|
||||
** here in order to indicate success or failure.
|
||||
**
|
||||
** New error codes may be added in future versions of SQLite.
|
||||
**
|
||||
** See also: [SQLITE_IOERR_READ | extended result codes],
|
||||
** [sqlite3_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes].
|
||||
** See also: [extended result code definitions]
|
||||
*/
|
||||
#define SQLITE_OK 0 /* Successful result */
|
||||
/* beginning-of-error-codes */
|
||||
@ -428,26 +426,19 @@ int sqlite3_exec(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Extended Result Codes
|
||||
** KEYWORDS: {extended error code} {extended error codes}
|
||||
** KEYWORDS: {extended result code} {extended result codes}
|
||||
** KEYWORDS: {extended result code definitions}
|
||||
**
|
||||
** In its default configuration, SQLite API routines return one of 26 integer
|
||||
** [SQLITE_OK | result codes]. However, experience has shown that many of
|
||||
** In its default configuration, SQLite API routines return one of 30 integer
|
||||
** [result codes]. However, experience has shown that many of
|
||||
** these result codes are too coarse-grained. They do not provide as
|
||||
** much information about problems as programmers might like. In an effort to
|
||||
** address this, newer versions of SQLite (version 3.3.8 and later) include
|
||||
** support for additional result codes that provide more detailed information
|
||||
** about errors. The extended result codes are enabled or disabled
|
||||
** about errors. These [extended result codes] are enabled or disabled
|
||||
** on a per database connection basis using the
|
||||
** [sqlite3_extended_result_codes()] API.
|
||||
**
|
||||
** Some of the available extended result codes are listed here.
|
||||
** One may expect the number of extended result codes will increase
|
||||
** over time. Software that uses extended result codes should expect
|
||||
** to see new result codes in future releases of SQLite.
|
||||
**
|
||||
** The SQLITE_OK result code will never be extended. It will always
|
||||
** be exactly zero.
|
||||
** [sqlite3_extended_result_codes()] API. Or, the extended code for
|
||||
** the most recent error can be obtained using
|
||||
** [sqlite3_extended_errcode()].
|
||||
*/
|
||||
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
|
||||
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
|
||||
@ -680,7 +671,7 @@ struct sqlite3_file {
|
||||
** locking strategy (for example to use dot-file locks), to inquire
|
||||
** about the status of a lock, or to break stale locks. The SQLite
|
||||
** core reserves all opcodes less than 100 for its own use.
|
||||
** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available.
|
||||
** A [file control opcodes | list of opcodes] less than 100 is available.
|
||||
** Applications that define a custom xFileControl method should use opcodes
|
||||
** greater than 100 to avoid conflicts. VFS implementations should
|
||||
** return [SQLITE_NOTFOUND] for file control opcodes that they do not
|
||||
@ -753,6 +744,7 @@ struct sqlite3_io_methods {
|
||||
|
||||
/*
|
||||
** CAPI3REF: Standard File Control Opcodes
|
||||
** KEYWORDS: {file control opcodes} {file control opcode}
|
||||
**
|
||||
** These integer constants are opcodes for the xFileControl method
|
||||
** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
|
||||
@ -2051,7 +2043,7 @@ int sqlite3_complete16(const void *sql);
|
||||
** The sqlite3_busy_handler() interface is used to implement
|
||||
** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout].
|
||||
**
|
||||
** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]
|
||||
** ^If the busy callback is NULL, then [SQLITE_BUSY]
|
||||
** is returned immediately upon encountering the lock. ^If the busy callback
|
||||
** is not NULL, then the callback might be invoked with two arguments.
|
||||
**
|
||||
@ -2060,7 +2052,7 @@ int sqlite3_complete16(const void *sql);
|
||||
** the busy handler callback is the number of times that the busy handler has
|
||||
** been invoked for the same locking event. ^If the
|
||||
** busy callback returns 0, then no additional attempts are made to
|
||||
** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned
|
||||
** access the database and [SQLITE_BUSY] is returned
|
||||
** to the application.
|
||||
** ^If the callback returns non-zero, then another attempt
|
||||
** is made to access the database and the cycle repeats.
|
||||
@ -2068,7 +2060,7 @@ int sqlite3_complete16(const void *sql);
|
||||
** The presence of a busy handler does not guarantee that it will be invoked
|
||||
** when there is lock contention. ^If SQLite determines that invoking the busy
|
||||
** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY]
|
||||
** or [SQLITE_IOERR_BLOCKED] to the application instead of invoking the
|
||||
** to the application instead of invoking the
|
||||
** busy handler.
|
||||
** Consider a scenario where one process is holding a read lock that
|
||||
** it is trying to promote to a reserved lock and
|
||||
@ -2083,21 +2075,6 @@ int sqlite3_complete16(const void *sql);
|
||||
**
|
||||
** ^The default busy callback is NULL.
|
||||
**
|
||||
** ^The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED]
|
||||
** when SQLite is in the middle of a large transaction where all the
|
||||
** changes will not fit into the in-memory cache. SQLite will
|
||||
** already hold a RESERVED lock on the database file, but it needs
|
||||
** to promote this lock to EXCLUSIVE so that it can spill cache
|
||||
** pages into the database file without harm to concurrent
|
||||
** readers. ^If it is unable to promote the lock, then the in-memory
|
||||
** cache will be left in an inconsistent state and so the error
|
||||
** code is promoted from the relatively benign [SQLITE_BUSY] to
|
||||
** the more severe [SQLITE_IOERR_BLOCKED]. ^This error code promotion
|
||||
** forces an automatic rollback of the changes. See the
|
||||
** <a href="/cvstrac/wiki?p=CorruptionFollowingBusyError">
|
||||
** CorruptionFollowingBusyError</a> wiki page for a discussion of why
|
||||
** this is important.
|
||||
**
|
||||
** ^(There can only be a single busy handler defined for each
|
||||
** [database connection]. Setting a new busy handler clears any
|
||||
** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()]
|
||||
@ -2122,7 +2099,7 @@ int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
|
||||
** will sleep multiple times until at least "ms" milliseconds of sleeping
|
||||
** have accumulated. ^After at least "ms" milliseconds of sleeping,
|
||||
** the handler returns 0 which causes [sqlite3_step()] to return
|
||||
** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
|
||||
** [SQLITE_BUSY].
|
||||
**
|
||||
** ^Calling this routine with an argument less than or equal to zero
|
||||
** turns off all busy handlers.
|
||||
@ -2534,8 +2511,8 @@ int sqlite3_set_authorizer(
|
||||
** [sqlite3_set_authorizer | authorizer documentation] for additional
|
||||
** information.
|
||||
**
|
||||
** Note that SQLITE_IGNORE is also used as a [SQLITE_ROLLBACK | return code]
|
||||
** from the [sqlite3_vtab_on_conflict()] interface.
|
||||
** Note that SQLITE_IGNORE is also used as a [conflict resolution mode]
|
||||
** returned from the [sqlite3_vtab_on_conflict()] interface.
|
||||
*/
|
||||
#define SQLITE_DENY 1 /* Abort the SQL statement with an error */
|
||||
#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
|
||||
@ -7376,6 +7353,7 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Conflict resolution modes
|
||||
** KEYWORDS: {conflict resolution mode}
|
||||
**
|
||||
** These constants are returned by [sqlite3_vtab_on_conflict()] to
|
||||
** inform a [virtual table] implementation what the [ON CONFLICT] mode
|
||||
|
@ -35,6 +35,14 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif /* defined(_WIN32) */
|
||||
|
||||
/*
|
||||
* Icon
|
||||
*/
|
||||
|
||||
#define IDI_SQLITE 101
|
||||
|
||||
IDI_SQLITE ICON "..\\art\\sqlite370.ico"
|
||||
|
||||
/*
|
||||
* Version
|
||||
*/
|
||||
|
@ -3266,7 +3266,7 @@ case OP_ReopenIdx: {
|
||||
assert( pOp->p5==0 );
|
||||
assert( pOp->p4type==P4_KEYINFO );
|
||||
pCur = p->apCsr[pOp->p1];
|
||||
if( pCur && pCur->pgnoRoot==pOp->p2 ){
|
||||
if( pCur && pCur->pgnoRoot==(u32)pOp->p2 ){
|
||||
assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */
|
||||
break;
|
||||
}
|
||||
@ -3553,7 +3553,7 @@ case OP_Close: {
|
||||
** the key and P2 is not zero, then jump to P2.
|
||||
**
|
||||
** This opcode leaves the cursor configured to move in forward order,
|
||||
** from the begining toward the end. In other words, the cursor is
|
||||
** from the beginning toward the end. In other words, the cursor is
|
||||
** configured to use Next, not Prev.
|
||||
**
|
||||
** See also: Found, NotFound, SeekLt, SeekGe, SeekLe
|
||||
@ -4571,7 +4571,7 @@ case OP_Sort: { /* jump */
|
||||
** to the following instruction.
|
||||
**
|
||||
** This opcode leaves the cursor configured to move in forward order,
|
||||
** from the begining toward the end. In other words, the cursor is
|
||||
** from the beginning toward the end. In other words, the cursor is
|
||||
** configured to use Next, not Prev.
|
||||
*/
|
||||
case OP_Rewind: { /* jump */
|
||||
|
@ -84,18 +84,35 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
|
||||
}
|
||||
|
||||
/*
|
||||
** Resize the Vdbe.aOp array so that it is at least one op larger than
|
||||
** it was.
|
||||
** Resize the Vdbe.aOp array so that it is at least nOp elements larger
|
||||
** than its current size. nOp is guaranteed to be less than or equal
|
||||
** to 1024/sizeof(Op).
|
||||
**
|
||||
** If an out-of-memory error occurs while resizing the array, return
|
||||
** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain
|
||||
** SQLITE_NOMEM. In this case Vdbe.aOp and Parse.nOpAlloc remain
|
||||
** unchanged (this is so that any opcodes already allocated can be
|
||||
** correctly deallocated along with the rest of the Vdbe).
|
||||
*/
|
||||
static int growOpArray(Vdbe *v){
|
||||
static int growOpArray(Vdbe *v, int nOp){
|
||||
VdbeOp *pNew;
|
||||
Parse *p = v->pParse;
|
||||
|
||||
/* The SQLITE_TEST_REALLOC_STRESS compile-time option is designed to force
|
||||
** more frequent reallocs and hence provide more opportunities for
|
||||
** simulated OOM faults. SQLITE_TEST_REALLOC_STRESS is generally used
|
||||
** during testing only. With SQLITE_TEST_REALLOC_STRESS grow the op array
|
||||
** by the minimum* amount required until the size reaches 512. Normal
|
||||
** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current
|
||||
** size of the op array or add 1KB of space, whichever is smaller. */
|
||||
#ifdef SQLITE_TEST_REALLOC_STRESS
|
||||
int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp);
|
||||
#else
|
||||
int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
|
||||
UNUSED_PARAMETER(nOp);
|
||||
#endif
|
||||
|
||||
assert( nOp<=(1024/sizeof(Op)) );
|
||||
assert( nNew>=(p->nOpAlloc+nOp) );
|
||||
pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
|
||||
if( pNew ){
|
||||
p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op);
|
||||
@ -139,7 +156,7 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
assert( op>0 && op<0xff );
|
||||
if( p->pParse->nOpAlloc<=i ){
|
||||
if( growOpArray(p) ){
|
||||
if( growOpArray(p, 1) ){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -541,7 +558,7 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
|
||||
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
|
||||
int addr;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p) ){
|
||||
if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
|
||||
return 0;
|
||||
}
|
||||
addr = p->nOp;
|
||||
@ -726,7 +743,7 @@ void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){
|
||||
** Change the opcode at addr into OP_Noop
|
||||
*/
|
||||
void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
|
||||
if( p->aOp ){
|
||||
if( addr<p->nOp ){
|
||||
VdbeOp *pOp = &p->aOp[addr];
|
||||
sqlite3 *db = p->db;
|
||||
freeP4(db, pOp->p4type, pOp->p4.p);
|
||||
@ -2301,7 +2318,6 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
|
||||
/* Check for one of the special errors */
|
||||
mrc = p->rc & 0xff;
|
||||
assert( p->rc!=SQLITE_IOERR_BLOCKED ); /* This error no longer exists */
|
||||
isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
|
||||
|| mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
|
||||
if( isSpecialError ){
|
||||
|
197
src/where.c
197
src/where.c
@ -5400,6 +5400,45 @@ static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return the cost of sorting nRow rows, assuming that the keys have
|
||||
** nOrderby columns and that the first nSorted columns are already in
|
||||
** order.
|
||||
*/
|
||||
static LogEst whereSortingCost(
|
||||
WhereInfo *pWInfo,
|
||||
LogEst nRow,
|
||||
int nOrderBy,
|
||||
int nSorted
|
||||
){
|
||||
/* TUNING: Estimated cost of a full external sort, where N is
|
||||
** the number of rows to sort is:
|
||||
**
|
||||
** cost = (3.0 * N * log(N)).
|
||||
**
|
||||
** Or, if the order-by clause has X terms but only the last Y
|
||||
** terms are out of order, then block-sorting will reduce the
|
||||
** sorting cost to:
|
||||
**
|
||||
** cost = (3.0 * N * log(N)) * (Y/X)
|
||||
**
|
||||
** The (Y/X) term is implemented using stack variable rScale
|
||||
** below. */
|
||||
LogEst rScale, rSortCost;
|
||||
assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
|
||||
rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
|
||||
rSortCost = nRow + estLog(nRow) + rScale + 16;
|
||||
|
||||
/* TUNING: The cost of implementing DISTINCT using a B-TREE is
|
||||
** similar but with a larger constant of proportionality.
|
||||
** Multiply by an additional factor of 3.0. */
|
||||
if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
|
||||
rSortCost += 16;
|
||||
}
|
||||
|
||||
return rSortCost;
|
||||
}
|
||||
|
||||
/*
|
||||
** Given the list of WhereLoop objects at pWInfo->pLoops, this routine
|
||||
** attempts to find the lowest cost path that visits each WhereLoop
|
||||
@ -5421,9 +5460,8 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
int ii, jj; /* Loop counters */
|
||||
int mxI = 0; /* Index of next entry to replace */
|
||||
int nOrderBy; /* Number of ORDER BY clause terms */
|
||||
LogEst rCost; /* Cost of a path */
|
||||
LogEst nOut; /* Number of outputs */
|
||||
LogEst mxCost = 0; /* Maximum cost of a set of paths */
|
||||
LogEst mxUnsorted = 0; /* Maximum unsorted cost of a set of path */
|
||||
int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */
|
||||
WherePath *aFrom; /* All nFrom paths at the previous level */
|
||||
WherePath *aTo; /* The nTo best paths at the current level */
|
||||
@ -5431,7 +5469,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
WherePath *pTo; /* An element of aTo[] that we are working on */
|
||||
WhereLoop *pWLoop; /* One of the WhereLoop objects */
|
||||
WhereLoop **pX; /* Used to divy up the pSpace memory */
|
||||
LogEst *aSortCost = 0; /* Sorting and partial sorting costs */
|
||||
char *pSpace; /* Temporary memory used by this routine */
|
||||
int nSpace; /* Bytes of space allocated at pSpace */
|
||||
|
||||
pParse = pWInfo->pParse;
|
||||
db = pParse->db;
|
||||
@ -5441,11 +5481,23 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
** For joins of 3 or more tables, track the 10 best paths */
|
||||
mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10);
|
||||
assert( nLoop<=pWInfo->pTabList->nSrc );
|
||||
WHERETRACE(0x002, ("---- begin solver\n"));
|
||||
WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d)\n", nRowEst));
|
||||
|
||||
/* Allocate and initialize space for aTo and aFrom */
|
||||
ii = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
|
||||
pSpace = sqlite3DbMallocRaw(db, ii);
|
||||
/* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this
|
||||
** case the purpose of this call is to estimate the number of rows returned
|
||||
** by the overall query. Once this estimate has been obtained, the caller
|
||||
** will invoke this function a second time, passing the estimate as the
|
||||
** nRowEst parameter. */
|
||||
if( pWInfo->pOrderBy==0 || nRowEst==0 ){
|
||||
nOrderBy = 0;
|
||||
}else{
|
||||
nOrderBy = pWInfo->pOrderBy->nExpr;
|
||||
}
|
||||
|
||||
/* Allocate and initialize space for aTo, aFrom and aSortCost[] */
|
||||
nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
|
||||
nSpace += sizeof(LogEst) * nOrderBy;
|
||||
pSpace = sqlite3DbMallocRaw(db, nSpace);
|
||||
if( pSpace==0 ) return SQLITE_NOMEM;
|
||||
aTo = (WherePath*)pSpace;
|
||||
aFrom = aTo+mxChoice;
|
||||
@ -5454,6 +5506,18 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){
|
||||
pFrom->aLoop = pX;
|
||||
}
|
||||
if( nOrderBy ){
|
||||
/* If there is an ORDER BY clause and it is not being ignored, set up
|
||||
** space for the aSortCost[] array. Each element of the aSortCost array
|
||||
** is either zero - meaning it has not yet been initialized - or the
|
||||
** cost of sorting nRowEst rows of data where the first X terms of
|
||||
** the ORDER BY clause are already in order, where X is the array
|
||||
** index. */
|
||||
aSortCost = (LogEst*)pX;
|
||||
memset(aSortCost, 0, sizeof(LogEst) * nOrderBy);
|
||||
}
|
||||
assert( aSortCost==0 || &pSpace[nSpace]==(char*)&aSortCost[nOrderBy] );
|
||||
assert( aSortCost!=0 || &pSpace[nSpace]==(char*)pX );
|
||||
|
||||
/* Seed the search with a single WherePath containing zero WhereLoops.
|
||||
**
|
||||
@ -5462,15 +5526,15 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
** rows, then do not use the automatic index. */
|
||||
aFrom[0].nRow = MIN(pParse->nQueryLoop, 46); assert( 46==sqlite3LogEst(25) );
|
||||
nFrom = 1;
|
||||
|
||||
/* Precompute the cost of sorting the final result set, if the caller
|
||||
** to sqlite3WhereBegin() was concerned about sorting */
|
||||
if( pWInfo->pOrderBy==0 || nRowEst==0 ){
|
||||
aFrom[0].isOrdered = 0;
|
||||
nOrderBy = 0;
|
||||
}else{
|
||||
aFrom[0].isOrdered = nLoop>0 ? -1 : 1;
|
||||
nOrderBy = pWInfo->pOrderBy->nExpr;
|
||||
assert( aFrom[0].isOrdered==0 );
|
||||
if( nOrderBy ){
|
||||
/* If nLoop is zero, then there are no FROM terms in the query. Since
|
||||
** in this case the query may return a maximum of one row, the results
|
||||
** are already in the requested order. Set isOrdered to nOrderBy to
|
||||
** indicate this. Or, if nLoop is greater than zero, set isOrdered to
|
||||
** -1, indicating that the result set may or may not be ordered,
|
||||
** depending on the loops added to the current plan. */
|
||||
aFrom[0].isOrdered = nLoop>0 ? -1 : nOrderBy;
|
||||
}
|
||||
|
||||
/* Compute successively longer WherePaths using the previous generation
|
||||
@ -5480,66 +5544,71 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
nTo = 0;
|
||||
for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){
|
||||
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
|
||||
Bitmask maskNew;
|
||||
Bitmask revMask = 0;
|
||||
i8 isOrdered = pFrom->isOrdered;
|
||||
LogEst nOut; /* Rows visited by (pFrom+pWLoop) */
|
||||
LogEst rCost; /* Cost of path (pFrom+pWLoop) */
|
||||
LogEst rUnsorted; /* Unsorted cost of (pFrom+pWLoop) */
|
||||
i8 isOrdered = pFrom->isOrdered; /* isOrdered for (pFrom+pWLoop) */
|
||||
Bitmask maskNew; /* Mask of src visited by (..) */
|
||||
Bitmask revMask = 0; /* Mask of rev-order loops for (..) */
|
||||
|
||||
if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
|
||||
if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
|
||||
/* At this point, pWLoop is a candidate to be the next loop.
|
||||
** Compute its cost */
|
||||
rCost = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
|
||||
rCost = sqlite3LogEstAdd(rCost, pFrom->rCost);
|
||||
rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
|
||||
rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted);
|
||||
nOut = pFrom->nRow + pWLoop->nOut;
|
||||
maskNew = pFrom->maskLoop | pWLoop->maskSelf;
|
||||
if( isOrdered<0 ){
|
||||
isOrdered = wherePathSatisfiesOrderBy(pWInfo,
|
||||
pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
|
||||
iLoop, pWLoop, &revMask);
|
||||
if( isOrdered>=0 && isOrdered<nOrderBy ){
|
||||
/* TUNING: Estimated cost of a full external sort, where N is
|
||||
** the number of rows to sort is:
|
||||
**
|
||||
** cost = (3.0 * N * log(N)).
|
||||
**
|
||||
** Or, if the order-by clause has X terms but only the last Y
|
||||
** terms are out of order, then block-sorting will reduce the
|
||||
** sorting cost to:
|
||||
**
|
||||
** cost = (3.0 * N * log(N)) * (Y/X)
|
||||
**
|
||||
** The (Y/X) term is implemented using stack variable rScale
|
||||
** below. */
|
||||
LogEst rScale, rSortCost;
|
||||
assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
|
||||
rScale = sqlite3LogEst((nOrderBy-isOrdered)*100/nOrderBy) - 66;
|
||||
rSortCost = nRowEst + estLog(nRowEst) + rScale + 16;
|
||||
|
||||
/* TUNING: The cost of implementing DISTINCT using a B-TREE is
|
||||
** similar but with a larger constant of proportionality.
|
||||
** Multiply by an additional factor of 3.0. */
|
||||
if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
|
||||
rSortCost += 16;
|
||||
}
|
||||
WHERETRACE(0x002,
|
||||
("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",
|
||||
rSortCost, (nOrderBy-isOrdered), nOrderBy, rCost,
|
||||
sqlite3LogEstAdd(rCost,rSortCost)));
|
||||
rCost = sqlite3LogEstAdd(rCost, rSortCost);
|
||||
}
|
||||
}else{
|
||||
revMask = pFrom->revLoop;
|
||||
}
|
||||
/* Check to see if pWLoop should be added to the mxChoice best so far */
|
||||
if( isOrdered>=0 && isOrdered<nOrderBy ){
|
||||
if( aSortCost[isOrdered]==0 ){
|
||||
aSortCost[isOrdered] = whereSortingCost(
|
||||
pWInfo, nRowEst, nOrderBy, isOrdered
|
||||
);
|
||||
}
|
||||
rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]);
|
||||
|
||||
WHERETRACE(0x002,
|
||||
("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",
|
||||
aSortCost[isOrdered], (nOrderBy-isOrdered), nOrderBy,
|
||||
rUnsorted, rCost));
|
||||
}else{
|
||||
rCost = rUnsorted;
|
||||
}
|
||||
|
||||
/* Check to see if pWLoop should be added to the set of
|
||||
** mxChoice best-so-far paths.
|
||||
**
|
||||
** First look for an existing path among best-so-far paths
|
||||
** that covers the same set of loops and has the same isOrdered
|
||||
** setting as the current path candidate.
|
||||
**
|
||||
** The term "((pTo->isOrdered^isOrdered)&0x80)==0" is equivalent
|
||||
** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range
|
||||
** of legal values for isOrdered, -1..64.
|
||||
*/
|
||||
for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
|
||||
if( pTo->maskLoop==maskNew
|
||||
&& ((pTo->isOrdered^isOrdered)&80)==0
|
||||
&& ((pTo->isOrdered^isOrdered)&0x80)==0
|
||||
){
|
||||
testcase( jj==nTo-1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( jj>=nTo ){
|
||||
if( nTo>=mxChoice && rCost>=mxCost ){
|
||||
/* None of the existing best-so-far paths match the candidate. */
|
||||
if( nTo>=mxChoice
|
||||
&& (rCost>mxCost || (rCost==mxCost && rUnsorted>=mxUnsorted))
|
||||
){
|
||||
/* The current candidate is no better than any of the mxChoice
|
||||
** paths currently in the best-so-far buffer. So discard
|
||||
** this candidate as not viable. */
|
||||
#ifdef WHERETRACE_ENABLED /* 0x4 */
|
||||
if( sqlite3WhereTrace&0x4 ){
|
||||
sqlite3DebugPrintf("Skip %s cost=%-3d,%3d order=%c\n",
|
||||
@ -5549,7 +5618,8 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
/* Add a new Path to the aTo[] set */
|
||||
/* If we reach this points it means that the new candidate path
|
||||
** needs to be added to the set of best-so-far paths. */
|
||||
if( nTo<mxChoice ){
|
||||
/* Increase the size of the aTo set by one */
|
||||
jj = nTo++;
|
||||
@ -5566,7 +5636,11 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
}
|
||||
#endif
|
||||
}else{
|
||||
if( pTo->rCost<=rCost ){
|
||||
/* Control reaches here if best-so-far path pTo=aTo[jj] covers the
|
||||
** same set of loops and has the sam isOrdered setting as the
|
||||
** candidate path. Check to see if the candidate should replace
|
||||
** pTo or if the candidate should be skipped */
|
||||
if( pTo->rCost<rCost || (pTo->rCost==rCost && pTo->nRow<=nOut) ){
|
||||
#ifdef WHERETRACE_ENABLED /* 0x4 */
|
||||
if( sqlite3WhereTrace&0x4 ){
|
||||
sqlite3DebugPrintf(
|
||||
@ -5578,11 +5652,13 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
|
||||
}
|
||||
#endif
|
||||
/* Discard the candidate path from further consideration */
|
||||
testcase( pTo->rCost==rCost );
|
||||
continue;
|
||||
}
|
||||
testcase( pTo->rCost==rCost+1 );
|
||||
/* A new and better score for a previously created equivalent path */
|
||||
/* Control reaches here if the candidate path is better than the
|
||||
** pTo path. Replace pTo with the candidate. */
|
||||
#ifdef WHERETRACE_ENABLED /* 0x4 */
|
||||
if( sqlite3WhereTrace&0x4 ){
|
||||
sqlite3DebugPrintf(
|
||||
@ -5600,15 +5676,20 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
pTo->revLoop = revMask;
|
||||
pTo->nRow = nOut;
|
||||
pTo->rCost = rCost;
|
||||
pTo->rUnsorted = rUnsorted;
|
||||
pTo->isOrdered = isOrdered;
|
||||
memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop);
|
||||
pTo->aLoop[iLoop] = pWLoop;
|
||||
if( nTo>=mxChoice ){
|
||||
mxI = 0;
|
||||
mxCost = aTo[0].rCost;
|
||||
mxUnsorted = aTo[0].nRow;
|
||||
for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
|
||||
if( pTo->rCost>mxCost ){
|
||||
if( pTo->rCost>mxCost
|
||||
|| (pTo->rCost==mxCost && pTo->rUnsorted>mxUnsorted)
|
||||
){
|
||||
mxCost = pTo->rCost;
|
||||
mxUnsorted = pTo->rUnsorted;
|
||||
mxI = jj;
|
||||
}
|
||||
}
|
||||
|
@ -183,6 +183,7 @@ struct WherePath {
|
||||
Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */
|
||||
LogEst nRow; /* Estimated number of rows generated by this path */
|
||||
LogEst rCost; /* Total cost of this path */
|
||||
LogEst rUnsorted; /* Total cost of this path ignoring sorting costs */
|
||||
i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */
|
||||
WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */
|
||||
};
|
||||
|
@ -1175,9 +1175,9 @@ do_createtable_tests 4.2 -repair {
|
||||
# EVIDENCE-OF: R-59124-61339 Each row in a table with a primary key must
|
||||
# have a unique combination of values in its primary key columns.
|
||||
#
|
||||
# EVIDENCE-OF: R-39102-06737 If an INSERT or UPDATE statement attempts
|
||||
# to modify the table content so that two or more rows feature identical
|
||||
# primary key values, it is a constraint violation.
|
||||
# EVIDENCE-OF: R-06471-16287 If an INSERT or UPDATE statement attempts
|
||||
# to modify the table content so that two or more rows have identical
|
||||
# primary key values, that is a constraint violation.
|
||||
#
|
||||
drop_all_tables
|
||||
do_execsql_test 4.3.0 {
|
||||
|
@ -450,7 +450,7 @@ do_execsql_test e_expr-10.3.4 { SELECT typeof('isn''t') } {text}
|
||||
# containing hexadecimal data and preceded by a single "x" or "X"
|
||||
# character.
|
||||
#
|
||||
# EVIDENCE-OF: R-39344-59787 For example: X'53514C697465'
|
||||
# EVIDENCE-OF: R-19836-11244 Example: X'53514C697465'
|
||||
#
|
||||
do_execsql_test e_expr-10.4.1 { SELECT typeof(X'0123456789ABCDEF') } blob
|
||||
do_execsql_test e_expr-10.4.2 { SELECT typeof(x'0123456789ABCDEF') } blob
|
||||
@ -1596,6 +1596,13 @@ do_expr_test e_expr-30.4.1 { CAST('' AS INTEGER) } integer 0
|
||||
do_expr_test e_expr-30.4.2 { CAST('not a number' AS INTEGER) } integer 0
|
||||
do_expr_test e_expr-30.4.3 { CAST('XXI' AS INTEGER) } integer 0
|
||||
|
||||
# EVIDENCE-OF: R-08980-53124 The CAST operator understands decimal
|
||||
# integers only — conversion of hexadecimal integers stops at
|
||||
# the "x" in the "0x" prefix of the hexadecimal integer string and thus
|
||||
# result of the CAST is always zero.
|
||||
do_expr_test e_expr-30.5.1 { CAST('0x1234' AS INTEGER) } integer 0
|
||||
do_expr_test e_expr-30.5.2 { CAST('0X1234' AS INTEGER) } integer 0
|
||||
|
||||
# EVIDENCE-OF: R-02752-50091 A cast of a REAL value into an INTEGER
|
||||
# results in the integer between the REAL value and zero that is closest
|
||||
# to the REAL value.
|
||||
|
@ -153,28 +153,38 @@ do_test func3-5.39 {
|
||||
db eval {EXPLAIN SELECT unlikely(min(1.0+'2.0',4*11))}
|
||||
} [db eval {EXPLAIN SELECT min(1.0+'2.0',4*11)}]
|
||||
|
||||
do_execsql_test func3-5.40 {
|
||||
|
||||
# EVIDENCE-OF: R-23735-03107 The likely(X) function returns the argument
|
||||
# X unchanged.
|
||||
#
|
||||
do_execsql_test func3-5.50 {
|
||||
SELECT likely(9223372036854775807);
|
||||
} {9223372036854775807}
|
||||
do_execsql_test func3-5.41 {
|
||||
do_execsql_test func3-5.51 {
|
||||
SELECT likely(-9223372036854775808);
|
||||
} {-9223372036854775808}
|
||||
do_execsql_test func3-5.42 {
|
||||
do_execsql_test func3-5.52 {
|
||||
SELECT likely(14.125);
|
||||
} {14.125}
|
||||
do_execsql_test func3-5.43 {
|
||||
do_execsql_test func3-5.53 {
|
||||
SELECT likely(NULL);
|
||||
} {{}}
|
||||
do_execsql_test func3-5.44 {
|
||||
do_execsql_test func3-5.54 {
|
||||
SELECT likely('test-string');
|
||||
} {test-string}
|
||||
do_execsql_test func3-5.45 {
|
||||
do_execsql_test func3-5.55 {
|
||||
SELECT quote(likely(x'010203000405'));
|
||||
} {X'010203000405'}
|
||||
do_test func3-5.49 {
|
||||
|
||||
# EVIDENCE-OF: R-43464-09689 The likely(X) function is a no-op that the
|
||||
# code generator optimizes away so that it consumes no CPU cycles at
|
||||
# run-time (that is, during calls to sqlite3_step()).
|
||||
#
|
||||
do_test func3-5.59 {
|
||||
db eval {EXPLAIN SELECT likely(min(1.0+'2.0',4*11))}
|
||||
} [db eval {EXPLAIN SELECT min(1.0+'2.0',4*11)}]
|
||||
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix incrblob_err
|
||||
|
||||
ifcapable {!incrblob || !memdebug || !tclvar} {
|
||||
finish_test
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix malloc
|
||||
|
||||
|
||||
# Only run these tests if memory debugging is turned on.
|
||||
|
43
test/mallocL.test
Normal file
43
test/mallocL.test
Normal file
@ -0,0 +1,43 @@
|
||||
# 2014 August 12
|
||||
#
|
||||
# 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 test script is designed to show that the assert() fix at
|
||||
# [f1cb48f412] really is required.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix mallocL
|
||||
|
||||
do_test 1.0 {
|
||||
for {set i 0} {$i < 40} {incr i} {
|
||||
lappend cols "c$i"
|
||||
lappend vals $i
|
||||
}
|
||||
|
||||
execsql "CREATE TABLE t1([join $cols ,])"
|
||||
execsql "CREATE INDEX i1 ON t1([join $cols ,])"
|
||||
execsql "INSERT INTO t1 VALUES([join $vals ,])"
|
||||
} {}
|
||||
|
||||
for {set j 1} {$j < 40} {incr j} {
|
||||
set ::sql "SELECT DISTINCT [join [lrange $cols 0 $j] ,] FROM t1"
|
||||
do_faultsim_test 1.$j -faults oom* -body {
|
||||
execsql $::sql
|
||||
} -test {
|
||||
faultsim_test_result [list 0 [lrange $::vals 0 $::j]]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
@ -409,6 +409,7 @@ proc do_malloc_test {tn args} {
|
||||
|
||||
if {[string is integer $tn]} {
|
||||
set tn malloc-$tn
|
||||
catch { set tn $::testprefix-$tn }
|
||||
}
|
||||
if {[info exists ::mallocopts(-start)]} {
|
||||
set start $::mallocopts(-start)
|
||||
|
@ -176,6 +176,12 @@ array set ::Configs {
|
||||
-DSQLITE_DISABLE_FTS4_DEFERRED
|
||||
-DSQLITE_ENABLE_RTREE
|
||||
}
|
||||
|
||||
"No-lookaside" {
|
||||
-DSQLITE_TEST_REALLOC_STRESS=1
|
||||
-DSQLITE_OMIT_LOOKASIDE=1
|
||||
-DHAVE_USLEEP=1
|
||||
}
|
||||
}
|
||||
|
||||
array set ::Platforms {
|
||||
@ -188,6 +194,7 @@ array set ::Platforms {
|
||||
"Extra-Robustness" test
|
||||
"Device-Two" test
|
||||
"Ftrapv" test
|
||||
"No-lookaside" test
|
||||
"Default" "threadtest test"
|
||||
"Device-One" fulltest
|
||||
}
|
||||
|
@ -781,7 +781,12 @@ do_test where9-6.8.2 {
|
||||
OR (b NOT NULL AND c NOT NULL AND d IS NULL)
|
||||
}
|
||||
} {1 {no query solution}}
|
||||
|
||||
set solution_possible 0
|
||||
ifcapable stat4||stat3 {
|
||||
if {[permutation] != "no_optimization"} { set solution_possible 1 }
|
||||
}
|
||||
if $solution_possible {
|
||||
# When STAT3 is enabled, the "b NOT NULL" terms get translated
|
||||
# into b>NULL, which can be satified by the index t1b. It is a very
|
||||
# expensive way to do the query, but it works, and so a solution is possible.
|
||||
|
@ -9,7 +9,7 @@
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file implements a single regression test for a complex
|
||||
# This file implements regression tests for a complex
|
||||
# query planning case.
|
||||
#
|
||||
|
||||
@ -328,4 +328,48 @@ do_execsql_test whereJ-1.4 {
|
||||
GROUP BY aid;
|
||||
} {/B-TREE/}
|
||||
|
||||
############################################################################
|
||||
# Ensure that the sorting cost does not swamp the loop costs and cause
|
||||
# distinctions between individual loop costs to get lost, and hence for
|
||||
# sub-optimal loops to be chosen.
|
||||
#
|
||||
do_execsql_test whereJ-2.1 {
|
||||
CREATE TABLE tab(
|
||||
id INTEGER PRIMARY KEY,
|
||||
minChild INTEGER REFERENCES t1,
|
||||
maxChild INTEGER REFERENCES t1,
|
||||
x INTEGER
|
||||
);
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT t4.x
|
||||
FROM tab AS t0, tab AS t1, tab AS t2, tab AS t3, tab AS t4
|
||||
WHERE t0.id=0
|
||||
AND t1.id BETWEEN t0.minChild AND t0.maxChild
|
||||
AND t2.id BETWEEN t1.minChild AND t1.maxChild
|
||||
AND t3.id BETWEEN t2.minChild AND t2.maxChild
|
||||
AND t4.id BETWEEN t3.minChild AND t3.maxChild
|
||||
ORDER BY t4.x;
|
||||
} {~/SCAN/}
|
||||
do_execsql_test whereJ-2.2 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT t4.x
|
||||
FROM tab AS t0a, tab AS t0b,
|
||||
tab AS t1a, tab AS t1b,
|
||||
tab AS t2a, tab AS t2b,
|
||||
tab AS t3a, tab AS t3b,
|
||||
tab AS t4
|
||||
WHERE 1
|
||||
AND t0a.id=1
|
||||
AND t1a.id BETWEEN t0a.minChild AND t0a.maxChild
|
||||
AND t2a.id BETWEEN t1a.minChild AND t1a.maxChild
|
||||
AND t3a.id BETWEEN t2a.minChild AND t2a.maxChild
|
||||
AND t0b.id=2
|
||||
AND t1b.id BETWEEN t0b.minChild AND t0b.maxChild
|
||||
AND t2b.id BETWEEN t1b.minChild AND t1b.maxChild
|
||||
AND t3b.id BETWEEN t2b.minChild AND t2b.maxChild
|
||||
AND t4.id BETWEEN t3a.minChild AND t3b.maxChild
|
||||
ORDER BY t4.x;
|
||||
} {~/SCAN/}
|
||||
|
||||
|
||||
finish_test
|
||||
|
Reference in New Issue
Block a user