diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 448a5a403a..29e071a50f 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -2066,7 +2066,37 @@ static int fts3DoclistOrMerge( *paOut = 0; *pnOut = 0; - aOut = sqlite3_malloc(n1+n2); + + /* Allocate space for the output. Both the input and output doclists + ** are delta encoded. If they are in ascending order (bDescDoclist==0), + ** then the first docid in each list is simply encoded as a varint. For + ** each subsequent docid, the varint stored is the difference between the + ** current and previous docid (a positive number - since the list is in + ** ascending order). + ** + ** The first docid written to the output is therefore encoded using the + ** same number of bytes as it is in whichever of the input lists it is + ** read from. And each subsequent docid read from the same input list + ** consumes either the same or less bytes as it did in the input (since + ** the difference between it and the previous value in the output must + ** be a positive value less than or equal to the delta value read from + ** the input list). The same argument applies to all but the first docid + ** read from the 'other' list. And to the contents of all position lists + ** that will be copied and merged from the input to the output. + ** + ** However, if the first docid copied to the output is a negative number, + ** then the encoding of the first docid from the 'other' input list may + ** be larger in the output than it was in the input (since the delta value + ** may be a larger positive integer than the actual docid). + ** + ** The space required to store the output is therefore the sum of the + ** sizes of the two inputs, plus enough space for exactly one of the input + ** docids to grow. + ** + ** A symetric argument may be made if the doclists are in descending + ** order. + */ + aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1); if( !aOut ) return SQLITE_NOMEM; p = aOut; @@ -2093,6 +2123,7 @@ static int fts3DoclistOrMerge( *paOut = aOut; *pnOut = (p-aOut); + assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 ); return SQLITE_OK; } diff --git a/manifest b/manifest index f5503e1304..3d19495e11 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Cleanup\spdb/ilk\sfiles\sgenerated\sby\sthe\sMSVC\smakefile. -D 2011-09-11T10:14:37.609 +C Allocate\sthe\scorrect\ssize\sfor\sthe\soutput\sbuffer\sin\sfts3DoclistOrMerge().\sFix\sfor\s[56be976859]. +D 2011-09-13T19:08:43.953 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -62,7 +62,7 @@ F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c f45ad45053a587ad1c005459b704b7ade8bd504e +F ext/fts3/fts3.c 195e4da669741c1f097434ec48c0ba5739193af9 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 30063fdd0bc433b5db1532e3a363cb0f2f7e8eb3 F ext/fts3/fts3_aux.c 0ebfa7b86cf8ff6a0861605fcc63b83ec1b70691 @@ -483,7 +483,7 @@ F test/fts3query.test ef79d31fdb355d094baec1c1b24b60439a1fb8a2 F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 8bb266521d7c5495c0ae522bb4d376ad5387d4a2 F test/fts3snippet.test 8e956051221a34c7daeb504f023cb54d5fa5a8b2 -F test/fts3sort.test 63d52c1812904b751f9e1ff487472e44833f5402 +F test/fts3sort.test 9a5176c9317bb545ec5f144d62e6fedb4da6c66e F test/fts4aa.test 6e7f90420b837b2c685f3bcbe84c868492d40a68 F test/func.test 6c5ce11e3a0021ca3c0649234e2d4454c89110ca F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f @@ -961,7 +961,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P d0712dfb24867a807c9cddcc12bd0aebe1d3e085 -R 2d6c3f1bb7ceef0c7739aec15017d5b3 -U mistachkin -Z a47fc06d3051baa0866b54de99b831cd +P a9db247b752bcda0131b8f01c6f0182f3101d154 +R d155e7b5d9350f72a6fc8ad44a77ee3c +U dan +Z 8c4428f39d0d1ba0e8478a40bc187eaf diff --git a/manifest.uuid b/manifest.uuid index 74ab610c51..63b21a1019 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a9db247b752bcda0131b8f01c6f0182f3101d154 \ No newline at end of file +07788c0f7f3740c1c280f6ce4dc68401c30bae6e \ No newline at end of file diff --git a/test/fts3sort.test b/test/fts3sort.test index ce5b5df76b..ccdc203442 100644 --- a/test/fts3sort.test +++ b/test/fts3sort.test @@ -158,5 +158,23 @@ do_execsql_test 2.3 { SELECT docid FROM t2 WHERE t2 MATCH 'aa'; } {3 1} +#------------------------------------------------------------------------- +# Test that ticket [56be976859] has been fixed. +# +do_execsql_test 3.1 { + CREATE VIRTUAL TABLE t3 USING fts4(x, order=DESC); + INSERT INTO t3(docid, x) VALUES(113382409004785664, 'aa'); + INSERT INTO t3(docid, x) VALUES(1, 'ab'); + SELECT rowid FROM t3 WHERE x MATCH 'a*' ORDER BY docid DESC; +} {113382409004785664 1} +do_execsql_test 3.2 { + CREATE VIRTUAL TABLE t4 USING fts4(x); + INSERT INTO t4(docid, x) VALUES(-113382409004785664, 'aa'); + INSERT INTO t4(docid, x) VALUES(1, 'ab'); + SELECT rowid FROM t4 WHERE x MATCH 'a*'; +} {-113382409004785664 1} + + + finish_test