From 311ec02587f9b4ab6a0786261ea301531a1681f9 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 27 Mar 2012 15:00:06 +0000 Subject: [PATCH] Remove the fts3merge.test script in favour of changing the fts4merge.test script so that it runs tests using both fts4 and fts3. Fix some problems with incr-merge and FTS3 tables. FossilOrigin-Name: 5c447e226afca0d46b9ed994dea26a16a9ae168c --- ext/fts3/fts3.c | 6 +- ext/fts3/fts3Int.h | 1 + ext/fts3/fts3_snippet.c | 4 +- ext/fts3/fts3_write.c | 12 +- manifest | 26 +- manifest.uuid | 2 +- test/fts3_common.tcl | 44 ++- test/fts4check.test | 4 +- test/fts4merge.test | 592 ++++++++++++++++++++-------------------- 9 files changed, 366 insertions(+), 325 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 626a63d971..e18f2b10ec 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -642,6 +642,7 @@ static int fts3CreateTables(Fts3Table *p){ p->zDb, p->zName ); } + assert( p->bHasStat==p->bFts4 ); if( p->bHasStat ){ sqlite3Fts3CreateStatTable(&rc, p); } @@ -1284,6 +1285,7 @@ static int fts3InitVtab( p->nMaxPendingData = FTS3_MAX_PENDING_DATA; p->bHasDocsize = (isFts4 && bNoDocsize==0); p->bHasStat = isFts4; + p->bFts4 = isFts4; p->bDescIdx = bDescIdx; p->bAutoincrmerge = 0xff; /* 0xff means setting unknown */ p->zContentTbl = zContent; @@ -2974,7 +2976,7 @@ static int fts3FilterMethod( if( nVal==2 ) pCsr->iLangid = sqlite3_value_int(apVal[1]); rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, - p->azColumn, p->bHasStat, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr + p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr ); if( rc!=SQLITE_OK ){ if( rc==SQLITE_ERROR ){ @@ -4385,7 +4387,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){ fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc); /* Determine which, if any, tokens in the expression should be deferred. */ - if( rc==SQLITE_OK && nToken>1 && pTab->bHasStat ){ + if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){ Fts3TokenAndCost *aTC; Fts3Expr **apOr; aTC = (Fts3TokenAndCost *)sqlite3_malloc( diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h index d0ee847ede..7d6c34789f 100644 --- a/ext/fts3/fts3Int.h +++ b/ext/fts3/fts3Int.h @@ -209,6 +209,7 @@ struct Fts3Table { char *zWriteExprlist; int nNodeSize; /* Soft limit for node size */ + u8 bFts4; /* True for FTS4, false for FTS3 */ u8 bHasStat; /* True if %_stat table exists */ u8 bHasDocsize; /* True if %_docsize table exists */ u8 bDescIdx; /* True if doclists are in reverse order */ diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c index fd5bc9786b..dd3706cc80 100644 --- a/ext/fts3/fts3_snippet.c +++ b/ext/fts3/fts3_snippet.c @@ -794,8 +794,8 @@ static int fts3MatchinfoCheck( ){ if( (cArg==FTS3_MATCHINFO_NPHRASE) || (cArg==FTS3_MATCHINFO_NCOL) - || (cArg==FTS3_MATCHINFO_NDOC && pTab->bHasStat) - || (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bHasStat) + || (cArg==FTS3_MATCHINFO_NDOC && pTab->bFts4) + || (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4) || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize) || (cArg==FTS3_MATCHINFO_LCS) || (cArg==FTS3_MATCHINFO_HITS) diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 640c2078cc..c0f25dd431 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -1516,7 +1516,7 @@ int sqlite3Fts3MsrOvfl( int rc = SQLITE_OK; int pgsz = p->nPgsz; - assert( p->bHasStat ); + assert( p->bFts4 ); assert( pgsz>0 ); for(ii=0; rc==SQLITE_OK && iinSegment; ii++){ @@ -3302,7 +3302,7 @@ static int fts3DoRebuild(Fts3Table *p){ } } } - if( p->bHasStat ){ + if( p->bFts4 ){ fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry); } sqlite3_free(aSz); @@ -4729,7 +4729,10 @@ static int fts3DoIncrmerge( rc = SQLITE_ERROR; }else{ rc = SQLITE_OK; - if( !p->bHasStat ) sqlite3Fts3CreateStatTable(&rc, p); + if( !p->bHasStat ){ + assert( p->bFts4==0 ); + sqlite3Fts3CreateStatTable(&rc, p); + } if( rc==SQLITE_OK ){ rc = sqlite3Fts3Incrmerge(p, nMerge, nMin); } @@ -4754,6 +4757,7 @@ static int fts3DoAutoincrmerge( sqlite3_stmt *pStmt = 0; p->bAutoincrmerge = fts3Getint(&zParam)!=0; if( !p->bHasStat ){ + assert( p->bFts4==0 ); sqlite3Fts3CreateStatTable(&rc, p); if( rc ) return rc; } @@ -5347,7 +5351,7 @@ int sqlite3Fts3UpdateMethod( nChng++; } - if( p->bHasStat ){ + if( p->bFts4 ){ fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng); } diff --git a/manifest b/manifest index e97049c786..a666fe4095 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sfts3view\sutility,\slabel\sthe\sblank\ssegments\sused\sto\smark\sthe\send\sof\sa\nsegment\ssequence\sfor\sa\slevel/idx\sas\s"null".\s\sImprove\sthe\salignment\sof\sroot\nsegment\snames. -D 2012-03-27T14:54:44.486 +C Remove\sthe\sfts3merge.test\sscript\sin\sfavour\sof\schanging\sthe\sfts4merge.test\sscript\sso\sthat\sit\sruns\stests\susing\sboth\sfts4\sand\sfts3.\sFix\ssome\sproblems\swith\sincr-merge\sand\sFTS3\stables. +D 2012-03-27T15:00:06.725 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -63,22 +63,22 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 5e2d74de50f5b591703923b765e74832621b7c3a +F ext/fts3/fts3.c f41f52a24f1a9d7f94291a0e17027e0c28e4f54b F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe -F ext/fts3/fts3Int.h 133e5c613ac6920be5b914d43acc1478df1332e1 +F ext/fts3/fts3Int.h 5fd2ec4e47faf17bf4a508d6b8ec5fc0f2c80bff F ext/fts3/fts3_aux.c 5205182bd8f372782597888156404766edf5781e F ext/fts3/fts3_expr.c dbc7ba4c3a6061adde0f38ed8e9b349568299551 F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914 F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec F ext/fts3/fts3_icu.c 6c8f395cdf9e1e3afa7fadb7e523dbbf381c6dfa F ext/fts3/fts3_porter.c a465b49fcb8249a755792f87516eff182efa42b3 -F ext/fts3/fts3_snippet.c c9e126c20760988aa7c43c6ea1379db34738282e +F ext/fts3/fts3_snippet.c 51a3a34c217e24678a133782c1dfb6f2f70fe559 F ext/fts3/fts3_term.c d3466cf99432291be08e379d89645462431809d6 F ext/fts3/fts3_test.c 6b7cc68aef4efb084e1449f7d20c4b20d3bdf6b4 F ext/fts3/fts3_tokenizer.c 3da7254a9881f7e270ab28e2004e0d22b3212bce F ext/fts3/fts3_tokenizer.h 66dec98e365854b6cd2d54f1a96bb6d428fc5a68 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 -F ext/fts3/fts3_write.c a9990753ba132cd79b666c61ec58ae15eb032387 +F ext/fts3/fts3_write.c ceb65d6a85f44c7dd1d96f12d04e20f75884bfe3 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3view.c 2c7f1bc1feddca85397be174fb6871007c27898b @@ -450,7 +450,7 @@ F test/fts2q.test b2fbbe038b7a31a52a6079b215e71226d8c6a682 F test/fts2r.test b154c30b63061d8725e320fba1a39e2201cadd5e F test/fts2token.test d8070b241a15ff13592a9ae4a8b7c171af6f445a F test/fts3.test 672a040ea57036fb4b6fdc09027c18d7d24ab654 -F test/fts3_common.tcl 52423d0f15bca1d1d2f2b432f0542c4036d655c7 +F test/fts3_common.tcl 99cf6659b87c0f74f55963c2aea03b3a7d66ceb0 F test/fts3aa.test 909d5f530d30a8e36b9328d67285eae6537c79c0 F test/fts3ab.test 09aeaa162aee6513d9ff336b6932211008b9d1f9 F test/fts3ac.test 636ed7486043055d4f126a0e385f2d5a82ebbf63 @@ -498,10 +498,10 @@ F test/fts3shared.test 8bb266521d7c5495c0ae522bb4d376ad5387d4a2 F test/fts3snippet.test 8e956051221a34c7daeb504f023cb54d5fa5a8b2 F test/fts3sort.test 95be0b19d7e41c44b29014f13ea8bddd495fd659 F test/fts4aa.test 6e7f90420b837b2c685f3bcbe84c868492d40a68 -F test/fts4check.test 72134071f4e9f8bed76af1f2375fd5aff0c5ea48 +F test/fts4check.test 66fa274cab2b615f2fb338b257713aba8fad88a8 F test/fts4content.test 17b2360f7d1a9a7e5aa8022783f5c5731b6dfd4f F test/fts4langid.test 24a6e41063b416bbdf371ff6b4476fa41c194aa7 -F test/fts4merge.test c7ee5fbb3b316d1496f1d2fa861c53840b84cef9 +F test/fts4merge.test c424309743fdd203f8e56a1f1cd7872cd66cc0ee F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test e0e21332f592fc003fcab112928ea891407d83cb F test/func.test 6c5ce11e3a0021ca3c0649234e2d4454c89110ca @@ -1000,7 +1000,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P e9436d8038e5a0d1ba992a77d1064d4a55595f57 -R 539ad1cd9b19a07386b41fe8ff2433cc -U drh -Z cd0ad279479f240b2399ce3360a34f55 +P 04aea0245e4183fef3664609f5a6353b65d71a85 +R b8c319973c3298c33d22a9e309ade35c +U dan +Z fbf5edaf3f2b7351822253f4d48708a9 diff --git a/manifest.uuid b/manifest.uuid index 99d066996b..d4a6a25e2f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -04aea0245e4183fef3664609f5a6353b65d71a85 \ No newline at end of file +5c447e226afca0d46b9ed994dea26a16a9ae168c \ No newline at end of file diff --git a/test/fts3_common.tcl b/test/fts3_common.tcl index d36ca10989..2ed1f70bf6 100644 --- a/test/fts3_common.tcl +++ b/test/fts3_common.tcl @@ -45,16 +45,29 @@ # #------------------------------------------------------------------------- -# USAGE: fts3_build_db_1 N +# USAGE: fts3_build_db_1 SWITCHES N # # Build a sample FTS table in the database opened by database connection # [db]. The name of the new table is "t1". # -proc fts3_build_db_1 {n} { +proc fts3_build_db_1 {args} { + + set default(-module) fts4 + + set nArg [llength $args] + if {($nArg%2)==0} { + error "wrong # args: should be \"fts3_build_db_1 ?switches? n\"" + } + + set n [lindex $args [expr $nArg-1]] + array set opts [array get default] + array set opts [lrange $args 0 [expr $nArg-2]] + foreach k [array names opts] { + if {0==[info exists default($k)]} { error "unknown option: $k" } + } if {$n > 10000} {error "n must be <= 10000"} - - db eval { CREATE VIRTUAL TABLE t1 USING fts4(x, y) } + db eval "CREATE VIRTUAL TABLE t1 USING $opts(-module) (x, y)" set xwords [list zero one two three four five six seven eight nine ten] set ywords [list alpha beta gamma delta epsilon zeta eta theta iota kappa] @@ -85,12 +98,29 @@ proc fts3_build_db_1 {n} { # Build a sample FTS table in the database opened by database connection # [db]. The name of the new table is "t2". # -proc fts3_build_db_2 {n args} { +proc fts3_build_db_2 {args} { + + set default(-module) fts4 + set default(-extra) "" + + set nArg [llength $args] + if {($nArg%2)==0} { + error "wrong # args: should be \"fts3_build_db_1 ?switches? n\"" + } + + set n [lindex $args [expr $nArg-1]] + array set opts [array get default] + array set opts [lrange $args 0 [expr $nArg-2]] + foreach k [array names opts] { + if {0==[info exists default($k)]} { error "unknown option: $k" } + } if {$n > 100000} {error "n must be <= 100000"} - set sql "CREATE VIRTUAL TABLE t2 USING fts4(content" - foreach a $args { append sql ", " $a } + set sql "CREATE VIRTUAL TABLE t2 USING $opts(-module) (content" + if {$opts(-extra) != ""} { + append sql ", " $opts(-extra) + } append sql ")" db eval $sql diff --git a/test/fts4check.test b/test/fts4check.test index 77815b2ab7..cc1d018aad 100644 --- a/test/fts4check.test +++ b/test/fts4check.test @@ -88,7 +88,7 @@ do_test 1.3 { fts_integrity db t1 } {ok} # this causes the integrity-check code to fail. # -do_test 2.0 { fts3_build_db_2 20000 {prefix="3,1"} } {} +do_test 2.0 { fts3_build_db_2 -extra {prefix="3,1"} 20000 } {} do_test 2.1 { fts_integrity db t2 } {ok} foreach {tn disruption} { 1 { @@ -152,6 +152,4 @@ foreach {tn disruption} { do_execsql_test 3.2.3.$tn "ROLLBACK" } - - finish_test diff --git a/test/fts4merge.test b/test/fts4merge.test index 0a4f6b6184..fabb651e64 100644 --- a/test/fts4merge.test +++ b/test/fts4merge.test @@ -15,7 +15,6 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/fts3_common.tcl -set ::testprefix fts4merge # If SQLITE_ENABLE_FTS3 is defined, omit this file. ifcapable !fts3 { @@ -28,308 +27,315 @@ proc fts3_integrity_check {tbl} { return "ok" } -#------------------------------------------------------------------------- -# Test cases 1.* -# -do_test 1.0 { fts3_build_db_1 1004 } {} -do_test 1.1 { fts3_integrity_check t1 } {ok} -do_execsql_test 1.1 { - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level -} { - 0 {0 1 2 3 4 5 6 7 8 9 10 11} - 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} - 2 {0 1 2} -} - -for {set i 0} {$i<20} {incr i} { - do_execsql_test 1.2.$i.1 { INSERT INTO t1(t1) VALUES('merge=1') } - do_test 1.2.$i.2 { fts3_integrity_check t1 } ok - do_execsql_test 1.2.$i.3 { - SELECT docid FROM t1 WHERE t1 MATCH 'zero one two three' - } {123 132 213 231 312 321} -} - -do_execsql_test 1.3 { - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level -} { - 0 {0 1 2 3} - 1 {0 1 2 3 4 5 6} - 2 {0 1 2 3} -} - -for {set i 0} {$i<100} {incr i} { - do_execsql_test 1.4.$i { INSERT INTO t1(t1) VALUES('merge=1,4') } - do_test 1.4.$i.2 { fts3_integrity_check t1 } ok - do_execsql_test 1.4.$i.3 { - SELECT docid FROM t1 WHERE t1 MATCH 'zero one two three' - } {123 132 213 231 312 321} -} - -do_execsql_test 1.5 { - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level -} { - 2 {0 1} - 3 0 -} - -#------------------------------------------------------------------------- -# Test cases 2.* test that errors in the xxx part of the 'merge=xxx' are -# handled correctly. -# -do_execsql_test 2.0 { CREATE VIRTUAL TABLE t2 USING fts4 } - -foreach {tn arg} { - 1 {merge=abc} - 2 {merge=%%%} - 3 {merge=,} - 4 {merge=5,} - 5 {merge=6,%} - 6 {merge=6,six} - 7 {merge=6,1} - 8 {merge=6,0} -} { - do_catchsql_test 2.$tn { - INSERT INTO t2(t2) VALUES($arg); - } {1 {SQL logic error or missing database}} -} - -#------------------------------------------------------------------------- -# Test cases 3.* -# -do_test 3.0 { +foreach mod {fts3 fts4} { + set ::testprefix fts4merge-$mod reset_db - execsql { PRAGMA page_size = 512 } - fts3_build_db_2 30040 -} {} -do_test 3.1 { fts3_integrity_check t2 } {ok} -do_execsql_test 3.2 { - SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level -} { - 0 {0 1 2 3 4 5 6} - 1 {0 1 2 3 4} - 2 {0 1 2 3 4} - 3 {0 1 2 3 4 5 6} -} - -do_execsql_test 3.3 { - INSERT INTO t2(t2) VALUES('merge=1000000,2'); - SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level -} { - 0 0 - 2 0 - 3 0 - 4 0 - 6 0 -} - -#------------------------------------------------------------------------- -# Test cases 4.* -# -reset_db -do_execsql_test 4.1 { - PRAGMA page_size = 512; - CREATE VIRTUAL TABLE t4 USING fts4; - PRAGMA main.page_size; -} {512} - -do_test 4.2 { - foreach x {a c b d e f g h i j k l m n o p} { - execsql "INSERT INTO t4 VALUES('[string repeat $x 600]')" + #------------------------------------------------------------------------- + # Test cases 1.* + # + do_test 1.0 { fts3_build_db_1 -module $mod 1004 } {} + do_test 1.1 { fts3_integrity_check t1 } {ok} + do_execsql_test 1.1 { + SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level + } { + 0 {0 1 2 3 4 5 6 7 8 9 10 11} + 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} + 2 {0 1 2} } - execsql {SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level} -} {0 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15}} - -foreach {tn expect} { - 1 "0 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} 1 0" - 2 "0 {0 1 2 3 4 5 6 7 8 9 10 11 12} 1 0" - 3 "0 {0 1 2 3 4 5 6 7 8 9 10 11} 1 0" - 4 "0 {0 1 2 3 4 5 6 7 8 9 10} 1 0" - 5 "0 {0 1 2 3 4 5 6 7 8 9} 1 0" - 6 "0 {0 1 2 3 4 5 6 7 8} 1 0" - 7 "0 {0 1 2 3 4 5 6 7} 1 0" - 8 "0 {0 1 2 3 4 5 6} 1 0" - 9 "0 {0 1 2 3 4 5} 1 0" -} { - do_execsql_test 4.3.$tn { - INSERT INTO t4(t4) VALUES('merge=1,16'); + + for {set i 0} {$i<20} {incr i} { + do_execsql_test 1.2.$i.1 { INSERT INTO t1(t1) VALUES('merge=1') } + do_test 1.2.$i.2 { fts3_integrity_check t1 } ok + do_execsql_test 1.2.$i.3 { + SELECT docid FROM t1 WHERE t1 MATCH 'zero one two three' + } {123 132 213 231 312 321} + } + + do_execsql_test 1.3 { + SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level + } { + 0 {0 1 2 3} + 1 {0 1 2 3 4 5 6} + 2 {0 1 2 3} + } + + for {set i 0} {$i<100} {incr i} { + do_execsql_test 1.4.$i { INSERT INTO t1(t1) VALUES('merge=1,4') } + do_test 1.4.$i.2 { fts3_integrity_check t1 } ok + do_execsql_test 1.4.$i.3 { + SELECT docid FROM t1 WHERE t1 MATCH 'zero one two three' + } {123 132 213 231 312 321} + } + + do_execsql_test 1.5 { + SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level + } { + 2 {0 1} + 3 0 + } + + #------------------------------------------------------------------------- + # Test cases 2.* test that errors in the xxx part of the 'merge=xxx' are + # handled correctly. + # + do_execsql_test 2.0 "CREATE VIRTUAL TABLE t2 USING $mod" + + foreach {tn arg} { + 1 {merge=abc} + 2 {merge=%%%} + 3 {merge=,} + 4 {merge=5,} + 5 {merge=6,%} + 6 {merge=6,six} + 7 {merge=6,1} + 8 {merge=6,0} + } { + do_catchsql_test 2.$tn { + INSERT INTO t2(t2) VALUES($arg); + } {1 {SQL logic error or missing database}} + } + + #------------------------------------------------------------------------- + # Test cases 3.* + # + do_test 3.0 { + reset_db + execsql { PRAGMA page_size = 512 } + fts3_build_db_2 -module $mod 30040 + } {} + do_test 3.1 { fts3_integrity_check t2 } {ok} + + do_execsql_test 3.2 { + SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level + } { + 0 {0 1 2 3 4 5 6} + 1 {0 1 2 3 4} + 2 {0 1 2 3 4} + 3 {0 1 2 3 4 5 6} + } + + do_execsql_test 3.3 { + INSERT INTO t2(t2) VALUES('merge=1000000,2'); + SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level + } { + 0 0 + 2 0 + 3 0 + 4 0 + 6 0 + } + + #------------------------------------------------------------------------- + # Test cases 4.* + # + reset_db + do_execsql_test 4.1 " + PRAGMA page_size = 512; + CREATE VIRTUAL TABLE t4 USING $mod; + PRAGMA main.page_size; + " {512} + + do_test 4.2 { + foreach x {a c b d e f g h i j k l m n o p} { + execsql "INSERT INTO t4 VALUES('[string repeat $x 600]')" + } + execsql {SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level} + } {0 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15}} + + foreach {tn expect} { + 1 "0 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} 1 0" + 2 "0 {0 1 2 3 4 5 6 7 8 9 10 11 12} 1 0" + 3 "0 {0 1 2 3 4 5 6 7 8 9 10 11} 1 0" + 4 "0 {0 1 2 3 4 5 6 7 8 9 10} 1 0" + 5 "0 {0 1 2 3 4 5 6 7 8 9} 1 0" + 6 "0 {0 1 2 3 4 5 6 7 8} 1 0" + 7 "0 {0 1 2 3 4 5 6 7} 1 0" + 8 "0 {0 1 2 3 4 5 6} 1 0" + 9 "0 {0 1 2 3 4 5} 1 0" + } { + do_execsql_test 4.3.$tn { + INSERT INTO t4(t4) VALUES('merge=1,16'); + SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level; + } $expect + } + + do_execsql_test 4.4.1 { + SELECT quote(value) FROM t4_stat WHERE rowid=1 + } {X'0006'} + + do_execsql_test 4.4.2 { + DELETE FROM t4_stat WHERE rowid=1; + INSERT INTO t4(t4) VALUES('merge=1,12'); SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level; - } $expect -} - -do_execsql_test 4.4.1 { - SELECT quote(value) FROM t4_stat WHERE rowid=1 -} {X'0006'} - -do_execsql_test 4.4.2 { - DELETE FROM t4_stat WHERE rowid=1; - INSERT INTO t4(t4) VALUES('merge=1,12'); - SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level; -} "0 {0 1 2 3 4 5} 1 0" - - -#------------------------------------------------------------------------- -# Test cases 5.* -# -# Test that if a crisis-merge occurs that disrupts an ongoing incremental -# merge, the next call to "merge=A,B" identifies this and starts a new -# incremental merge. There are two scenarios: -# -# * There are less segments on the input level that the disrupted -# incremental merge operated on, or -# -# * Sufficient segments exist on the input level but the segments -# contain keys smaller than the largest key in the potential output -# segment. -# -do_test 5.1 { - reset_db - fts3_build_db_1 1000 -} {} - -do_execsql_test 5.2 { - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; -} { - 0 {0 1 2 3 4 5 6 7} - 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} - 2 {0 1 2} -} - -do_execsql_test 5.3 { - INSERT INTO t1(t1) VALUES('merge=1,5'); - INSERT INTO t1(t1) VALUES('merge=1,5'); - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; -} { - 0 {0 1 2} - 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14} - 2 {0 1 2 3} -} - -do_execsql_test 5.4 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'0105'} -do_test 5.5 { - foreach docid [execsql {SELECT docid FROM t1}] { - execsql {INSERT INTO t1 SELECT * FROM t1 WHERE docid=$docid} + } "0 {0 1 2 3 4 5} 1 0" + + + #------------------------------------------------------------------------- + # Test cases 5.* + # + # Test that if a crisis-merge occurs that disrupts an ongoing incremental + # merge, the next call to "merge=A,B" identifies this and starts a new + # incremental merge. There are two scenarios: + # + # * There are less segments on the input level that the disrupted + # incremental merge operated on, or + # + # * Sufficient segments exist on the input level but the segments + # contain keys smaller than the largest key in the potential output + # segment. + # + do_test 5.1 { + reset_db + fts3_build_db_1 -module $mod 1000 + } {} + + do_execsql_test 5.2 { + SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; + } { + 0 {0 1 2 3 4 5 6 7} + 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} + 2 {0 1 2} } -} {} - -do_execsql_test 5.6 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'0105'} - -do_execsql_test 5.7 { - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; - SELECT quote(value) from t1_stat WHERE rowid=1; -} { - 0 {0 1 2 3 4 5 6 7 8 9 10} - 1 {0 1 2 3 4 5 6 7 8 9 10 11 12} - 2 {0 1 2 3 4 5 6 7} - X'0105' -} - -do_execsql_test 5.8 { - INSERT INTO t1(t1) VALUES('merge=1,6'); - INSERT INTO t1(t1) VALUES('merge=1,6'); - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; - SELECT quote(value) from t1_stat WHERE rowid=1; -} { - 0 {0 1 2 3 4} - 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} - 2 {0 1 2 3 4 5 6 7 8} X'0106' -} - -do_test 5.8.1 { fts3_integrity_check t1 } ok - -do_test 5.9 { - set L [expr 16*16*7 + 16*3 + 12] - foreach docid [execsql { - SELECT docid FROM t1 UNION ALL SELECT docid FROM t1 LIMIT $L - }] { - execsql {INSERT INTO t1 SELECT * FROM t1 WHERE docid=$docid} + + do_execsql_test 5.3 { + INSERT INTO t1(t1) VALUES('merge=1,5'); + INSERT INTO t1(t1) VALUES('merge=1,5'); + SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; + } { + 0 {0 1 2} + 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14} + 2 {0 1 2 3} } -} {} - -do_execsql_test 5.10 { - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; - SELECT quote(value) from t1_stat WHERE rowid=1; -} { - 0 0 1 {0 1} 2 0 3 0 X'0106' -} - -do_execsql_test 5.11 { - INSERT INTO t1(t1) VALUES('merge=1,6'); - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; - SELECT quote(value) from t1_stat WHERE rowid=1; -} { - 0 0 1 {0 1} 2 0 3 0 X'' -} - -#------------------------------------------------------------------------- -# Test cases 6.* -# -# At one point the following test caused an assert() to fail (because the -# second 'merge=1,2' operation below actually "merges" a single input -# segment, which was unexpected). -# -do_test 6.1 { - reset_db - set a [string repeat a 900] - set b [string repeat b 900] - set c [string repeat c 900] - set d [string repeat d 900] - execsql { - CREATE VIRTUAL TABLE t1 USING fts4; - BEGIN; - INSERT INTO t1 VALUES($a); - INSERT INTO t1 VALUES($b); - COMMIT; - BEGIN; - INSERT INTO t1 VALUES($c); - INSERT INTO t1 VALUES($d); - COMMIT; + + do_execsql_test 5.4 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'0105'} + do_test 5.5 { + foreach docid [execsql {SELECT docid FROM t1}] { + execsql {INSERT INTO t1 SELECT * FROM t1 WHERE docid=$docid} + } + } {} + + do_execsql_test 5.6 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'0105'} + + do_execsql_test 5.7 { + SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; + SELECT quote(value) from t1_stat WHERE rowid=1; + } { + 0 {0 1 2 3 4 5 6 7 8 9 10} + 1 {0 1 2 3 4 5 6 7 8 9 10 11 12} + 2 {0 1 2 3 4 5 6 7} + X'0105' } - - execsql { - INSERT INTO t1(t1) VALUES('merge=1,2'); - INSERT INTO t1(t1) VALUES('merge=1,2'); + + do_execsql_test 5.8 { + INSERT INTO t1(t1) VALUES('merge=1,6'); + INSERT INTO t1(t1) VALUES('merge=1,6'); + SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; + SELECT quote(value) from t1_stat WHERE rowid=1; + } { + 0 {0 1 2 3 4} + 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} + 2 {0 1 2 3 4 5 6 7 8} X'0106' } -} {} + + do_test 5.8.1 { fts3_integrity_check t1 } ok + + do_test 5.9 { + set L [expr 16*16*7 + 16*3 + 12] + foreach docid [execsql { + SELECT docid FROM t1 UNION ALL SELECT docid FROM t1 LIMIT $L + }] { + execsql {INSERT INTO t1 SELECT * FROM t1 WHERE docid=$docid} + } + } {} + + do_execsql_test 5.10 { + SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; + SELECT quote(value) from t1_stat WHERE rowid=1; + } { + 0 0 1 {0 1} 2 0 3 0 X'0106' + } + + do_execsql_test 5.11 { + INSERT INTO t1(t1) VALUES('merge=1,6'); + SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; + SELECT quote(value) from t1_stat WHERE rowid=1; + } { + 0 0 1 {0 1} 2 0 3 0 X'' + } + + #------------------------------------------------------------------------- + # Test cases 6.* + # + # At one point the following test caused an assert() to fail (because the + # second 'merge=1,2' operation below actually "merges" a single input + # segment, which was unexpected). + # + do_test 6.1 { + reset_db + set a [string repeat a 900] + set b [string repeat b 900] + set c [string repeat c 900] + set d [string repeat d 900] -#------------------------------------------------------------------------- -# Test cases 7.* -# -# Test that the value returned by sqlite3_total_changes() increases by -# 1 following a no-op "merge=A,B", or by more than 1 if actual work is -# performed. -# -do_test 7.0 { - reset_db - fts3_build_db_1 1000 -} {} + execsql "CREATE VIRTUAL TABLE t1 USING $mod" + execsql { + BEGIN; + INSERT INTO t1 VALUES($a); + INSERT INTO t1 VALUES($b); + COMMIT; + BEGIN; + INSERT INTO t1 VALUES($c); + INSERT INTO t1 VALUES($d); + COMMIT; + } + + execsql { + INSERT INTO t1(t1) VALUES('merge=1,2'); + INSERT INTO t1(t1) VALUES('merge=1,2'); + } + } {} + + #------------------------------------------------------------------------- + # Test cases 7.* + # + # Test that the value returned by sqlite3_total_changes() increases by + # 1 following a no-op "merge=A,B", or by more than 1 if actual work is + # performed. + # + do_test 7.0 { + reset_db + fts3_build_db_1 -module $mod 1000 + } {} + + do_execsql_test 7.1 { + SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level + } { + 0 {0 1 2 3 4 5 6 7} + 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} + 2 {0 1 2} + } + do_test 7.2 { + set x [db total_changes] + execsql { INSERT INTO t1(t1) VALUES('merge=2,10') } + expr { ([db total_changes] - $x)>1 } + } {1} + do_test 7.3 { + set x [db total_changes] + execsql { INSERT INTO t1(t1) VALUES('merge=200,10') } + expr { ([db total_changes] - $x)>1 } + } {1} + do_test 7.4 { + set x [db total_changes] + execsql { INSERT INTO t1(t1) VALUES('merge=200,10') } + expr { ([db total_changes] - $x)>1 } + } {0} + do_test 7.5 { + set x [db total_changes] + execsql { INSERT INTO t1(t1) VALUES('merge=200,10') } + expr { ([db total_changes] - $x)>1 } + } {0} -do_execsql_test 7.1 { - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level -} { - 0 {0 1 2 3 4 5 6 7} - 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} - 2 {0 1 2} } -do_test 7.2 { - set x [db total_changes] - execsql { INSERT INTO t1(t1) VALUES('merge=2,10') } - expr { ([db total_changes] - $x)>1 } -} {1} -do_test 7.3 { - set x [db total_changes] - execsql { INSERT INTO t1(t1) VALUES('merge=200,10') } - expr { ([db total_changes] - $x)>1 } -} {1} -do_test 7.4 { - set x [db total_changes] - execsql { INSERT INTO t1(t1) VALUES('merge=200,10') } - expr { ([db total_changes] - $x)>1 } -} {0} -do_test 7.5 { - set x [db total_changes] - execsql { INSERT INTO t1(t1) VALUES('merge=200,10') } - expr { ([db total_changes] - $x)>1 } -} {0} finish_test