Merge all recent changes from trunk,
including the fix for the OP_SCopy-vs-OP_Copy problem. FossilOrigin-Name: 9515c8344a6743bbb0c6a6e49fb79fb3139090df
This commit is contained in:
commit
652cc4b6dc
38
manifest
38
manifest
@ -1,5 +1,5 @@
|
|||||||
C Merge\sin\sfixes\s(including\sthe\scorrupt-database\scrash\sfix)\sand\nperformance\senhancements\sfrom\strunk.
|
C Merge\sall\srecent\schanges\sfrom\strunk,\nincluding\sthe\sfix\sfor\sthe\sOP_SCopy-vs-OP_Copy\sproblem.
|
||||||
D 2014-03-26T19:43:30.427
|
D 2014-04-03T16:35:33.203
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a
|
F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -178,7 +178,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
|||||||
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
|
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
|
||||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||||
F src/btree.c 8d7e432bdd27d63182865c708ea0e7606489b6d1
|
F src/btree.c a59a199f21338ae1847d69f5db87c3e8ef1b1578
|
||||||
F src/btree.h 232836cb51753f2e96aa8ce0f052c6df850f76ba
|
F src/btree.h 232836cb51753f2e96aa8ce0f052c6df850f76ba
|
||||||
F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4
|
F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4
|
||||||
F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0
|
F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0
|
||||||
@ -206,7 +206,7 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
|||||||
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
|
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
|
||||||
F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f
|
F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f
|
||||||
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
|
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
|
||||||
F src/mem5.c aeb019f271ea53de83d651ec526877e6ba863450
|
F src/mem5.c 74670012946c4adc8a6ad84d03acc80959c3e529
|
||||||
F src/memjournal.c 0683aac6cab6ec2b5374c0db37c0deb2436a3785
|
F src/memjournal.c 0683aac6cab6ec2b5374c0db37c0deb2436a3785
|
||||||
F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc
|
F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc
|
||||||
F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea
|
F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea
|
||||||
@ -232,11 +232,11 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
|
|||||||
F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
|
F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
|
||||||
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
||||||
F src/select.c 269c3e31a450fce642a10569221a49180348c88e
|
F src/select.c 269c3e31a450fce642a10569221a49180348c88e
|
||||||
F src/shell.c cee9f46f2688a261601b1fd3d7f4b3cddf9b5cdf
|
F src/shell.c 5260f2ada8dd06e9f5ae0a448c8c01e7a75dd881
|
||||||
F src/sqlite.h.in a31c8b7782a0388b4bd823ed3a3a3e4b93b0cf42
|
F src/sqlite.h.in a31c8b7782a0388b4bd823ed3a3a3e4b93b0cf42
|
||||||
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
||||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||||
F src/sqliteInt.h b0fa7a8b72fceda6bf989fba2699b5208c861cbc
|
F src/sqliteInt.h 2ce2e12bc5a4cf8e5511ee11ee4778a1911be7e9
|
||||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
@ -292,11 +292,11 @@ F src/update.c 7bb549d61efc6853f5cc708c1de6931179f8a12d
|
|||||||
F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c
|
F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c
|
||||||
F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
|
F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
|
||||||
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
||||||
F src/vdbe.c 99f878d003314340d6a1e8a8bb185b60ced628df
|
F src/vdbe.c 47bdf5f82fa23548bc0ee720c54e3b2b8802babe
|
||||||
F src/vdbe.h e8e1219a7fd7395deb7a9824f9b7757d642fcf1a
|
F src/vdbe.h d03fcf47890ae1c79a335ca994cb878b302697ca
|
||||||
F src/vdbeInt.h faadf45c5a0c32a251228222fed380ab1389202e
|
F src/vdbeInt.h c05d4572211384c560b7579e7a299248cf31d6bd
|
||||||
F src/vdbeapi.c d3c662762b62e330a03f29de8e2ac7098ef78030
|
F src/vdbeapi.c d3c662762b62e330a03f29de8e2ac7098ef78030
|
||||||
F src/vdbeaux.c 74aa0e2e9c87b2e9c9cdea501dbf9243d7b7759b
|
F src/vdbeaux.c f9c225c26b4cab6239a7790b4bd14a6cd96ba19e
|
||||||
F src/vdbeblob.c 2d1f0fdb0f5b72118520980360a594b1c30cbdd8
|
F src/vdbeblob.c 2d1f0fdb0f5b72118520980360a594b1c30cbdd8
|
||||||
F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447
|
F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447
|
||||||
F src/vdbesort.c 4abb7c0f8f19b7d7d82f4558d5da1a30fdf9ea38
|
F src/vdbesort.c 4abb7c0f8f19b7d7d82f4558d5da1a30fdf9ea38
|
||||||
@ -305,7 +305,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
|
|||||||
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
|
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
|
||||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||||
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
|
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
|
||||||
F src/where.c da8ec216f14af617505799b0b4e52c73dda7a5ca
|
F src/where.c ebad891b7494d0c5f925cf7ab135380bd958cba3
|
||||||
F src/whereInt.h 2564055b440e44ebec8b47f237bbccae6719b7af
|
F src/whereInt.h 2564055b440e44ebec8b47f237bbccae6719b7af
|
||||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
@ -417,9 +417,9 @@ F test/corruptC.test 02405cf7ed0c1e989060e1aab6d02ffbc3906fbb
|
|||||||
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
|
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
|
||||||
F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
|
F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
|
||||||
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
|
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
|
||||||
F test/corruptG.test 58ec333a01997fe655e34e5bea52b7a2a6b9704d
|
F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804
|
||||||
F test/corruptH.test 88ed71a086e13591c917aac6de32750e7c7281cb
|
F test/corruptH.test 88ed71a086e13591c917aac6de32750e7c7281cb
|
||||||
F test/corruptI.test 1b796461e5b635e0a74e3c4ecb1121c82d319dff
|
F test/corruptI.test b3e4203d420490fc3d3062711597bc1dea06a789
|
||||||
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
|
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
|
||||||
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
|
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
|
||||||
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
|
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
|
||||||
@ -1071,7 +1071,7 @@ F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
|
|||||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||||
F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b
|
F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b
|
||||||
F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
|
F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
|
||||||
F test/wal64k.test 63828c2161ad76ddd4109dee0a096b6ef6895698
|
F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
|
||||||
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
|
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
|
||||||
F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216
|
F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216
|
||||||
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
|
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
|
||||||
@ -1107,7 +1107,7 @@ F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a
|
|||||||
F test/whereD.test 6c2feb79ef1f68381b07f39017fe5f9b96da8d62
|
F test/whereD.test 6c2feb79ef1f68381b07f39017fe5f9b96da8d62
|
||||||
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
|
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
|
||||||
F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
|
F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
|
||||||
F test/whereG.test eb3a46b3eaf38e25e3013433b2db8a25a866c215
|
F test/whereG.test 2533b72ed4a31fd1687230a499b557b911525344
|
||||||
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
|
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
|
||||||
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
|
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
|
||||||
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
|
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
|
||||||
@ -1136,7 +1136,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
|||||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||||
F tool/lemon.c 07aba6270d5a5016ba8107b09e431eea4ecdc123
|
F tool/lemon.c 07aba6270d5a5016ba8107b09e431eea4ecdc123
|
||||||
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
|
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
|
||||||
F tool/logest.c 7ad625cac3d54012b27d468b7af6612f78b9ba75
|
F tool/logest.c 388c318c7ac8b52b7c08ca1e2de0f4ca9a8f7e81
|
||||||
F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383
|
F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383
|
||||||
F tool/mkkeywordhash.c c9e05e4a7bcab8fab9f583d5b321fb72f565ad97
|
F tool/mkkeywordhash.c c9e05e4a7bcab8fab9f583d5b321fb72f565ad97
|
||||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||||
@ -1174,7 +1174,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||||
P 42c9d8fc5fe4f0250bfa1f977c7cc63e5741408f f585f5d7a0f9bf8c590388654a3638231eba8892
|
P fc8ca1a87e7127bd28f32fd809aec3e24355fbfa d5513dfa23baa0b0a095aaf17d19aacd30dcef61
|
||||||
R fc3fab040eeffed1a38e67c3557fec70
|
R 507e4fb477cf51261d2563e52f7cfa77
|
||||||
U drh
|
U drh
|
||||||
Z 657de079eefd6dd1d0e2ef048fcceef3
|
Z a91c37323943563a6d3bfb60a104e003
|
||||||
|
@ -1 +1 @@
|
|||||||
fc8ca1a87e7127bd28f32fd809aec3e24355fbfa
|
9515c8344a6743bbb0c6a6e49fb79fb3139090df
|
@ -4588,6 +4588,7 @@ int sqlite3BtreeMovetoUnpacked(
|
|||||||
|
|
||||||
if( pIdxKey ){
|
if( pIdxKey ){
|
||||||
xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
|
xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
|
||||||
|
pIdxKey->isCorrupt = 0;
|
||||||
assert( pIdxKey->default_rc==1
|
assert( pIdxKey->default_rc==1
|
||||||
|| pIdxKey->default_rc==0
|
|| pIdxKey->default_rc==0
|
||||||
|| pIdxKey->default_rc==-1
|
|| pIdxKey->default_rc==-1
|
||||||
@ -4711,6 +4712,7 @@ int sqlite3BtreeMovetoUnpacked(
|
|||||||
c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
|
c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
|
||||||
sqlite3_free(pCellKey);
|
sqlite3_free(pCellKey);
|
||||||
}
|
}
|
||||||
|
assert( pIdxKey->isCorrupt==0 || c==0 );
|
||||||
if( c<0 ){
|
if( c<0 ){
|
||||||
lwr = idx+1;
|
lwr = idx+1;
|
||||||
}else if( c>0 ){
|
}else if( c>0 ){
|
||||||
@ -4720,6 +4722,7 @@ int sqlite3BtreeMovetoUnpacked(
|
|||||||
*pRes = 0;
|
*pRes = 0;
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
pCur->aiIdx[pCur->iPage] = (u16)idx;
|
pCur->aiIdx[pCur->iPage] = (u16)idx;
|
||||||
|
if( pIdxKey->isCorrupt ) rc = SQLITE_CORRUPT;
|
||||||
goto moveto_finish;
|
goto moveto_finish;
|
||||||
}
|
}
|
||||||
if( lwr>upr ) break;
|
if( lwr>upr ) break;
|
||||||
|
@ -248,7 +248,7 @@ static void *memsys5MallocUnsafe(int nByte){
|
|||||||
** block. If not, then split a block of the next larger power of
|
** block. If not, then split a block of the next larger power of
|
||||||
** two in order to create a new free block of size iLogsize.
|
** two in order to create a new free block of size iLogsize.
|
||||||
*/
|
*/
|
||||||
for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){}
|
for(iBin=iLogsize; iBin<=LOGMAX && mem5.aiFreelist[iBin]<0; iBin++){}
|
||||||
if( iBin>LOGMAX ){
|
if( iBin>LOGMAX ){
|
||||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||||
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
|
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
|
||||||
|
@ -2130,10 +2130,12 @@ static void tryToClone(struct callback_data *p, const char *zNewDb){
|
|||||||
fprintf(stderr, "Cannot create output database: %s\n",
|
fprintf(stderr, "Cannot create output database: %s\n",
|
||||||
sqlite3_errmsg(newDb));
|
sqlite3_errmsg(newDb));
|
||||||
}else{
|
}else{
|
||||||
|
sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
|
||||||
sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
|
sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
|
||||||
tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
|
tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
|
||||||
tryToCloneSchema(p, newDb, "type!='table'", 0);
|
tryToCloneSchema(p, newDb, "type!='table'", 0);
|
||||||
sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
|
sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
|
||||||
|
sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
|
||||||
}
|
}
|
||||||
sqlite3_close(newDb);
|
sqlite3_close(newDb);
|
||||||
}
|
}
|
||||||
|
@ -1635,6 +1635,7 @@ struct UnpackedRecord {
|
|||||||
KeyInfo *pKeyInfo; /* Collation and sort-order information */
|
KeyInfo *pKeyInfo; /* Collation and sort-order information */
|
||||||
u16 nField; /* Number of entries in apMem[] */
|
u16 nField; /* Number of entries in apMem[] */
|
||||||
i8 default_rc; /* Comparison result if keys are equal */
|
i8 default_rc; /* Comparison result if keys are equal */
|
||||||
|
u8 isCorrupt; /* Corruption detected by xRecordCompare() */
|
||||||
Mem *aMem; /* Values */
|
Mem *aMem; /* Values */
|
||||||
int r1; /* Value to return if (lhs > rhs) */
|
int r1; /* Value to return if (lhs > rhs) */
|
||||||
int r2; /* Value to return if (rhs < lhs) */
|
int r2; /* Value to return if (rhs < lhs) */
|
||||||
|
@ -5990,7 +5990,7 @@ case OP_VOpen: {
|
|||||||
|
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
/* Opcode: VFilter P1 P2 P3 P4 *
|
/* Opcode: VFilter P1 P2 P3 P4 *
|
||||||
** Synopsis: iPlan=r[P3] zPlan='P4'
|
** Synopsis: iplan=r[P3] zplan='P4'
|
||||||
**
|
**
|
||||||
** P1 is a cursor opened using VOpen. P2 is an address to jump to if
|
** P1 is a cursor opened using VOpen. P2 is an address to jump to if
|
||||||
** the filtered result set is empty.
|
** the filtered result set is empty.
|
||||||
|
@ -213,10 +213,10 @@ void sqlite3VdbeSetVarmask(Vdbe*, int);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
|
void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
|
||||||
int sqlite3VdbeRecordCompare(int,const void*,const UnpackedRecord*,int);
|
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*,int);
|
||||||
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
|
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
|
||||||
|
|
||||||
typedef int (*RecordCompare)(int,const void*,const UnpackedRecord*,int);
|
typedef int (*RecordCompare)(int,const void*,UnpackedRecord*,int);
|
||||||
RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
|
RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
|
@ -411,7 +411,7 @@ u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
|
|||||||
void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
|
void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
|
||||||
|
|
||||||
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
|
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
|
||||||
int sqlite3VdbeIdxKeyCompare(VdbeCursor*,const UnpackedRecord*,int*);
|
int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
|
||||||
int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
|
int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
|
||||||
int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
|
int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
|
||||||
int sqlite3VdbeExec(Vdbe*);
|
int sqlite3VdbeExec(Vdbe*);
|
||||||
|
@ -3407,10 +3407,13 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
|
|||||||
** Key1 and Key2 do not have to contain the same number of fields. If all
|
** Key1 and Key2 do not have to contain the same number of fields. If all
|
||||||
** fields that appear in both keys are equal, then pPKey2->default_rc is
|
** fields that appear in both keys are equal, then pPKey2->default_rc is
|
||||||
** returned.
|
** returned.
|
||||||
|
**
|
||||||
|
** If database corruption is discovered, set pPKey2->isCorrupt to non-zero
|
||||||
|
** and return 0.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeRecordCompare(
|
int sqlite3VdbeRecordCompare(
|
||||||
int nKey1, const void *pKey1, /* Left key */
|
int nKey1, const void *pKey1, /* Left key */
|
||||||
const UnpackedRecord *pPKey2, /* Right key */
|
UnpackedRecord *pPKey2, /* Right key */
|
||||||
int bSkip /* If true, skip the first field */
|
int bSkip /* If true, skip the first field */
|
||||||
){
|
){
|
||||||
u32 d1; /* Offset into aKey[] of next data element */
|
u32 d1; /* Offset into aKey[] of next data element */
|
||||||
@ -3436,7 +3439,10 @@ int sqlite3VdbeRecordCompare(
|
|||||||
}else{
|
}else{
|
||||||
idx1 = getVarint32(aKey1, szHdr1);
|
idx1 = getVarint32(aKey1, szHdr1);
|
||||||
d1 = szHdr1;
|
d1 = szHdr1;
|
||||||
if( d1>(unsigned)nKey1 ) return 1; /* Corruption */
|
if( d1>(unsigned)nKey1 ){
|
||||||
|
pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
|
||||||
|
return 0; /* Corruption */
|
||||||
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3513,7 +3519,8 @@ int sqlite3VdbeRecordCompare(
|
|||||||
testcase( (d1+mem1.n)==(unsigned)nKey1 );
|
testcase( (d1+mem1.n)==(unsigned)nKey1 );
|
||||||
testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
|
testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
|
||||||
if( (d1+mem1.n) > (unsigned)nKey1 ){
|
if( (d1+mem1.n) > (unsigned)nKey1 ){
|
||||||
rc = 1; /* Corruption */
|
pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
|
||||||
|
return 0; /* Corruption */
|
||||||
}else if( pKeyInfo->aColl[i] ){
|
}else if( pKeyInfo->aColl[i] ){
|
||||||
mem1.enc = pKeyInfo->enc;
|
mem1.enc = pKeyInfo->enc;
|
||||||
mem1.db = pKeyInfo->db;
|
mem1.db = pKeyInfo->db;
|
||||||
@ -3539,7 +3546,8 @@ int sqlite3VdbeRecordCompare(
|
|||||||
testcase( (d1+nStr)==(unsigned)nKey1 );
|
testcase( (d1+nStr)==(unsigned)nKey1 );
|
||||||
testcase( (d1+nStr+1)==(unsigned)nKey1 );
|
testcase( (d1+nStr+1)==(unsigned)nKey1 );
|
||||||
if( (d1+nStr) > (unsigned)nKey1 ){
|
if( (d1+nStr) > (unsigned)nKey1 ){
|
||||||
rc = 1; /* Corruption */
|
pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
|
||||||
|
return 0; /* Corruption */
|
||||||
}else{
|
}else{
|
||||||
int nCmp = MIN(nStr, pRhs->n);
|
int nCmp = MIN(nStr, pRhs->n);
|
||||||
rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
|
rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
|
||||||
@ -3598,7 +3606,7 @@ int sqlite3VdbeRecordCompare(
|
|||||||
*/
|
*/
|
||||||
static int vdbeRecordCompareInt(
|
static int vdbeRecordCompareInt(
|
||||||
int nKey1, const void *pKey1, /* Left key */
|
int nKey1, const void *pKey1, /* Left key */
|
||||||
const UnpackedRecord *pPKey2, /* Right key */
|
UnpackedRecord *pPKey2, /* Right key */
|
||||||
int bSkip /* Ignored */
|
int bSkip /* Ignored */
|
||||||
){
|
){
|
||||||
const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F];
|
const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F];
|
||||||
@ -3696,7 +3704,7 @@ static int vdbeRecordCompareInt(
|
|||||||
*/
|
*/
|
||||||
static int vdbeRecordCompareString(
|
static int vdbeRecordCompareString(
|
||||||
int nKey1, const void *pKey1, /* Left key */
|
int nKey1, const void *pKey1, /* Left key */
|
||||||
const UnpackedRecord *pPKey2, /* Right key */
|
UnpackedRecord *pPKey2, /* Right key */
|
||||||
int bSkip
|
int bSkip
|
||||||
){
|
){
|
||||||
const u8 *aKey1 = (const u8*)pKey1;
|
const u8 *aKey1 = (const u8*)pKey1;
|
||||||
@ -3717,7 +3725,10 @@ static int vdbeRecordCompareString(
|
|||||||
int szHdr = aKey1[0];
|
int szHdr = aKey1[0];
|
||||||
|
|
||||||
nStr = (serial_type-12) / 2;
|
nStr = (serial_type-12) / 2;
|
||||||
if( (szHdr + nStr) > nKey1 ) return 0; /* Corruption */
|
if( (szHdr + nStr) > nKey1 ){
|
||||||
|
pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
|
||||||
|
return 0; /* Corruption */
|
||||||
|
}
|
||||||
nCmp = MIN( pPKey2->aMem[0].n, nStr );
|
nCmp = MIN( pPKey2->aMem[0].n, nStr );
|
||||||
res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
|
res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
|
||||||
|
|
||||||
@ -3882,7 +3893,7 @@ idx_rowid_corruption:
|
|||||||
*/
|
*/
|
||||||
int sqlite3VdbeIdxKeyCompare(
|
int sqlite3VdbeIdxKeyCompare(
|
||||||
VdbeCursor *pC, /* The cursor to compare against */
|
VdbeCursor *pC, /* The cursor to compare against */
|
||||||
const UnpackedRecord *pUnpacked, /* Unpacked version of key */
|
UnpackedRecord *pUnpacked, /* Unpacked version of key */
|
||||||
int *res /* Write the comparison result here */
|
int *res /* Write the comparison result here */
|
||||||
){
|
){
|
||||||
i64 nCellKey = 0;
|
i64 nCellKey = 0;
|
||||||
|
48
src/where.c
48
src/where.c
@ -4328,18 +4328,34 @@ static int whereLoopAddBtree(
|
|||||||
)
|
)
|
||||||
){
|
){
|
||||||
pNew->iSortIdx = b ? iSortIdx : 0;
|
pNew->iSortIdx = b ? iSortIdx : 0;
|
||||||
|
/* TUNING: The base cost of an index scan is N + log2(N).
|
||||||
|
** The log2(N) is for the initial seek to the beginning and the N
|
||||||
|
** is for the scan itself. */
|
||||||
|
pNew->rRun = sqlite3LogEstAdd(rSize, rLogSize);
|
||||||
if( m==0 ){
|
if( m==0 ){
|
||||||
/* TUNING: Cost of a covering index scan is K*(N + log2(N)).
|
/* TUNING: Cost of a covering index scan is K*(N + log2(N)).
|
||||||
** + The extra factor K of between 1.1 and 3.0 that depends
|
** + The extra factor K of between 1.1 and 3.0 that depends
|
||||||
** on the relative sizes of the table and the index. K
|
** on the relative sizes of the table and the index. K
|
||||||
** is smaller for smaller indices, thus favoring them.
|
** is smaller for smaller indices, thus favoring them.
|
||||||
|
** The upper bound on K (3.0) matches the penalty factor
|
||||||
|
** on a full table scan that tries to encourage the use of
|
||||||
|
** indexed lookups over full scans.
|
||||||
*/
|
*/
|
||||||
pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 1 +
|
pNew->rRun += 1 + (15*pProbe->szIdxRow)/pTab->szTabRow;
|
||||||
(15*pProbe->szIdxRow)/pTab->szTabRow;
|
|
||||||
}else{
|
}else{
|
||||||
/* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N)
|
/* TUNING: The cost of scanning a non-covering index is multiplied
|
||||||
** which we will simplify to just N*log2(N) */
|
** by log2(N) to account for the binary search of the main table
|
||||||
pNew->rRun = rSize + rLogSize;
|
** that must happen for each row of the index.
|
||||||
|
** TODO: Should there be a multiplier here, analogous to the 3x
|
||||||
|
** multiplier for a fulltable scan or covering index scan, to
|
||||||
|
** further discourage the use of an index scan? Or is the log2(N)
|
||||||
|
** term sufficient discouragement?
|
||||||
|
** TODO: What if some or all of the WHERE clause terms can be
|
||||||
|
** computed without reference to the original table. Then the
|
||||||
|
** penality should reduce to logK where K is the number of output
|
||||||
|
** rows.
|
||||||
|
*/
|
||||||
|
pNew->rRun += rLogSize;
|
||||||
}
|
}
|
||||||
whereLoopOutputAdjust(pWC, pNew);
|
whereLoopOutputAdjust(pWC, pNew);
|
||||||
rc = whereLoopInsert(pBuilder, pNew);
|
rc = whereLoopInsert(pBuilder, pNew);
|
||||||
@ -4920,7 +4936,7 @@ static i8 wherePathSatisfiesOrderBy(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* End the loop over all WhereLoops from outer-most down to inner-most */
|
} /* End the loop over all WhereLoops from outer-most down to inner-most */
|
||||||
if( obSat==obDone ) return nOrderBy;
|
if( obSat==obDone ) return (i8)nOrderBy;
|
||||||
if( !isOrderDistinct ){
|
if( !isOrderDistinct ){
|
||||||
for(i=nOrderBy-1; i>0; i--){
|
for(i=nOrderBy-1; i>0; i--){
|
||||||
Bitmask m = MASKBIT(i) - 1;
|
Bitmask m = MASKBIT(i) - 1;
|
||||||
@ -5041,11 +5057,19 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
|||||||
pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
|
pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
|
||||||
iLoop, pWLoop, &revMask);
|
iLoop, pWLoop, &revMask);
|
||||||
if( isOrdered>=0 && isOrdered<nOrderBy ){
|
if( isOrdered>=0 && isOrdered<nOrderBy ){
|
||||||
/* TUNING: Estimated cost of sorting cost as roughly N*log(N).
|
/* TUNING: Estimated cost of sorting is N*log(N).
|
||||||
** If some but not all of the columns are in sorted order, then
|
** If the order-by clause has X terms but only the last Y terms
|
||||||
** scale down the log(N) term. */
|
** are out of order, then block-sorting will reduce the sorting
|
||||||
LogEst rScale = sqlite3LogEst((nOrderBy-isOrdered)*100/nOrderBy);
|
** cost to N*log(N)*log(Y/X). The log(Y/X) term is computed
|
||||||
LogEst rSortCost = nRowEst + estLog(nRowEst) + rScale - 66;
|
** by rScale.
|
||||||
|
** TODO: Should the sorting cost get a small multiplier to help
|
||||||
|
** discourage the use of sorting and encourage the use of index
|
||||||
|
** scans instead?
|
||||||
|
*/
|
||||||
|
LogEst rScale, rSortCost;
|
||||||
|
assert( nOrderBy>0 );
|
||||||
|
rScale = sqlite3LogEst((nOrderBy-isOrdered)*100/nOrderBy) - 66;
|
||||||
|
rSortCost = nRowEst + estLog(nRowEst) + rScale;
|
||||||
/* TUNING: The cost of implementing DISTINCT using a B-TREE is
|
/* TUNING: The cost of implementing DISTINCT using a B-TREE is
|
||||||
** also N*log(N) but it has a larger constant of proportionality.
|
** also N*log(N) but it has a larger constant of proportionality.
|
||||||
** Multiply by 3.0. */
|
** Multiply by 3.0. */
|
||||||
@ -5900,7 +5924,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
for(; k<last; k++, pOp++){
|
for(; k<last; k++, pOp++){
|
||||||
if( pOp->p1!=pLevel->iTabCur ) continue;
|
if( pOp->p1!=pLevel->iTabCur ) continue;
|
||||||
if( pOp->opcode==OP_Column ){
|
if( pOp->opcode==OP_Column ){
|
||||||
pOp->opcode = OP_SCopy;
|
pOp->opcode = OP_Copy;
|
||||||
pOp->p1 = pOp->p2 + pTabItem->regResult;
|
pOp->p1 = pOp->p2 + pTabItem->regResult;
|
||||||
pOp->p2 = pOp->p3;
|
pOp->p2 = pOp->p3;
|
||||||
pOp->p3 = 0;
|
pOp->p3 = 0;
|
||||||
|
@ -47,12 +47,12 @@ do_test 1.2 {
|
|||||||
catchsql {
|
catchsql {
|
||||||
SELECT c FROM t1 WHERE a>'abc';
|
SELECT c FROM t1 WHERE a>'abc';
|
||||||
}
|
}
|
||||||
} {0 {}}
|
} {1 {database disk image is malformed}}
|
||||||
do_test 1.3 {
|
do_test 1.3 {
|
||||||
catchsql {
|
catchsql {
|
||||||
PRAGMA integrity_check
|
PRAGMA integrity_check
|
||||||
}
|
}
|
||||||
} {0 ok}
|
} {1 {database disk image is malformed}}
|
||||||
do_test 1.4 {
|
do_test 1.4 {
|
||||||
catchsql {
|
catchsql {
|
||||||
SELECT c FROM t1 ORDER BY a;
|
SELECT c FROM t1 ORDER BY a;
|
||||||
@ -71,11 +71,6 @@ do_test 2.1 {
|
|||||||
catchsql {
|
catchsql {
|
||||||
SELECT rowid FROM t1 WHERE a='abc' and b='xyz123456789XYZ';
|
SELECT rowid FROM t1 WHERE a='abc' and b='xyz123456789XYZ';
|
||||||
}
|
}
|
||||||
# The following test result is brittle. The point above is to try to
|
} {1 {database disk image is malformed}}
|
||||||
# force a buffer overread by a corrupt database file. If we get an
|
|
||||||
# incorrect answer from a corrupt database file, that is OK. If the
|
|
||||||
# result below changes, that just means that "undefined behavior" has
|
|
||||||
# changed.
|
|
||||||
} {/0 .*/}
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -51,7 +51,7 @@ do_test 1.3 {
|
|||||||
hexio_write test.db $off FFFF7f02
|
hexio_write test.db $off FFFF7f02
|
||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
catchsql { SELECT * FROM t1 WHERE a = 10 }
|
catchsql { SELECT * FROM t1 WHERE a = 10 }
|
||||||
} {0 {}}
|
} {1 {database disk image is malformed}}
|
||||||
|
|
||||||
do_test 2.0 {
|
do_test 2.0 {
|
||||||
execsql {
|
execsql {
|
||||||
|
@ -19,6 +19,11 @@ set testprefix wal64k
|
|||||||
|
|
||||||
ifcapable !wal {finish_test ; return }
|
ifcapable !wal {finish_test ; return }
|
||||||
|
|
||||||
|
if {$tcl_platform(platform) != "unix"} {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
db close
|
db close
|
||||||
test_syscall pagesize 65536
|
test_syscall pagesize 65536
|
||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
@ -44,4 +49,3 @@ integrity_check 1.3
|
|||||||
db close
|
db close
|
||||||
test_syscall pagesize -1
|
test_syscall pagesize -1
|
||||||
finish_test
|
finish_test
|
||||||
|
|
||||||
|
@ -166,5 +166,18 @@ do_eqp_test whereG-3.4 {
|
|||||||
SELECT * FROM a, b WHERE a2=5 AND a1=b1;
|
SELECT * FROM a, b WHERE a2=5 AND a1=b1;
|
||||||
} {/.*SCAN TABLE a.*SEARCH TABLE b USING INDEX .*b_1 .b1=..*/}
|
} {/.*SCAN TABLE a.*SEARCH TABLE b USING INDEX .*b_1 .b1=..*/}
|
||||||
|
|
||||||
|
# Ticket [1e64dd782a126f48d78c43a664844a41d0e6334e]:
|
||||||
|
# Incorrect result in a nested GROUP BY/DISTINCT due to the use of an OP_SCopy
|
||||||
|
# where an OP_Copy was needed.
|
||||||
|
#
|
||||||
|
do_execsql_test whereG-4.0 {
|
||||||
|
CREATE TABLE t4(x);
|
||||||
|
INSERT INTO t4 VALUES('right'),('wrong');
|
||||||
|
SELECT DISTINCT x
|
||||||
|
FROM (SELECT x FROM t4 GROUP BY x)
|
||||||
|
WHERE x='right'
|
||||||
|
ORDER BY x;
|
||||||
|
} {right}
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -17,13 +17,7 @@
|
|||||||
**
|
**
|
||||||
** ./LogEst ARGS
|
** ./LogEst ARGS
|
||||||
**
|
**
|
||||||
** Arguments:
|
** See the showHelp() routine for a description of valid arguments.
|
||||||
**
|
|
||||||
** 'x' Multiple the top two elements of the stack
|
|
||||||
** '+' Add the top two elements of the stack
|
|
||||||
** NUM Convert NUM from integer to LogEst and push onto the stack
|
|
||||||
** ^NUM Interpret NUM as a LogEst and push onto stack.
|
|
||||||
**
|
|
||||||
** Examples:
|
** Examples:
|
||||||
**
|
**
|
||||||
** To convert 123 from LogEst to integer:
|
** To convert 123 from LogEst to integer:
|
||||||
@ -97,12 +91,31 @@ static LogEst logEstFromDouble(double x){
|
|||||||
return e*10;
|
return e*10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int isInteger(const char *z){
|
||||||
|
while( z[0]>='0' && z[0]<='9' ) z++;
|
||||||
|
return z[0]==0;
|
||||||
|
}
|
||||||
|
|
||||||
int isFloat(const char *z){
|
int isFloat(const char *z){
|
||||||
while( z[0] ){
|
char c;
|
||||||
if( z[0]=='.' || z[0]=='E' || z[0]=='e' ) return 1;
|
while( ((c=z[0])>='0' && c<='9') || c=='.' || c=='E' || c=='e'
|
||||||
z++;
|
|| c=='+' || c=='-' ) z++;
|
||||||
}
|
return z[0]==0;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
static void showHelp(const char *zArgv0){
|
||||||
|
printf("Usage: %s ARGS...\n", zArgv0);
|
||||||
|
printf("Arguments:\n"
|
||||||
|
" NUM Convert NUM from integer to LogEst and push onto the stack\n"
|
||||||
|
" ^NUM Interpret NUM as a LogEst and push onto stack\n"
|
||||||
|
" x Multiple the top two elements of the stack\n"
|
||||||
|
" + Add the top two elements of the stack\n"
|
||||||
|
" dup Dupliate the top element on the stack\n"
|
||||||
|
" inv Take the reciprocal of the top of stack. N = 1/N.\n"
|
||||||
|
" log Find the LogEst of the number on top of stack\n"
|
||||||
|
" nlogn Compute NlogN where N is the top of stack\n"
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv){
|
int main(int argc, char **argv){
|
||||||
@ -111,30 +124,43 @@ int main(int argc, char **argv){
|
|||||||
LogEst a[100];
|
LogEst a[100];
|
||||||
for(i=1; i<argc; i++){
|
for(i=1; i<argc; i++){
|
||||||
const char *z = argv[i];
|
const char *z = argv[i];
|
||||||
if( z[0]=='+' ){
|
if( strcmp(z,"+")==0 ){
|
||||||
if( n>=2 ){
|
if( n>=2 ){
|
||||||
a[n-2] = logEstAdd(a[n-2],a[n-1]);
|
a[n-2] = logEstAdd(a[n-2],a[n-1]);
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
}else if( z[0]=='x' ){
|
}else if( strcmp(z,"x")==0 ){
|
||||||
if( n>=2 ){
|
if( n>=2 ){
|
||||||
a[n-2] = logEstMultiply(a[n-2],a[n-1]);
|
a[n-2] = logEstMultiply(a[n-2],a[n-1]);
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
|
}else if( strcmp(z,"dup")==0 ){
|
||||||
|
if( n>0 ){
|
||||||
|
a[n] = a[n-1];
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}else if( strcmp(z,"log")==0 ){
|
||||||
|
if( n>0 ) a[n-1] = logEstFromInteger(a[n-1]) - 33;
|
||||||
|
}else if( strcmp(z,"nlogn")==0 ){
|
||||||
|
if( n>0 ) a[n-1] += logEstFromInteger(a[n-1]) - 33;
|
||||||
|
}else if( strcmp(z,"inv")==0 ){
|
||||||
|
if( n>0 ) a[n-1] = -a[n-1];
|
||||||
}else if( z[0]=='^' ){
|
}else if( z[0]=='^' ){
|
||||||
a[n++] = atoi(z+1);
|
a[n++] = atoi(z+1);
|
||||||
}else if( isFloat(z) ){
|
}else if( isInteger(z) ){
|
||||||
|
a[n++] = logEstFromInteger(atoi(z));
|
||||||
|
}else if( isFloat(z) && z[0]!='-' ){
|
||||||
a[n++] = logEstFromDouble(atof(z));
|
a[n++] = logEstFromDouble(atof(z));
|
||||||
}else{
|
}else{
|
||||||
a[n++] = logEstFromInteger(atoi(z));
|
showHelp(argv[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(i=n-1; i>=0; i--){
|
for(i=n-1; i>=0; i--){
|
||||||
if( a[i]<0 ){
|
if( a[i]<0 ){
|
||||||
printf("%d (%f)\n", a[i], 1.0/(double)logEstToInt(-a[i]));
|
printf("%5d (%f)\n", a[i], 1.0/(double)logEstToInt(-a[i]));
|
||||||
}else{
|
}else{
|
||||||
sqlite3_uint64 x = logEstToInt(a[i]+100)*100/1024;
|
sqlite3_uint64 x = logEstToInt(a[i]+100)*100/1024;
|
||||||
printf("%d (%lld.%02lld)\n", a[i], x/100, x%100);
|
printf("%5d (%lld.%02lld)\n", a[i], x/100, x%100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user