From acf28fbdd8b232d8ba69c5ad65f51ecc48490a91 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 4 Dec 2009 14:11:33 +0000 Subject: [PATCH] Modify [2ad1461f25] to avoid leaving a prepared statement in "active" state following an OOM error in FTS3. FossilOrigin-Name: 69c21ee46aeeb624fd8638b17ff7259a3e5f9a46 --- ext/fts3/fts3.c | 13 +++++++++++-- manifest | 26 ++++++++----------------- manifest.uuid | 2 +- test/fts3rnd.test | 48 ++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 63 insertions(+), 26 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 980304dadc..e1a84cfdc0 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -1557,14 +1557,23 @@ static int fts3TermSelect( */ rc = sqlite3Fts3SegReaderNew(p, iAge, 0, 0, 0, zRoot, nRoot, &pNew); }else{ - sqlite3_int64 i1; + int rc2; /* Return value of sqlite3Fts3ReadBlock() */ + sqlite3_int64 i1; /* Blockid of leaf that may contain zTerm */ rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &i1); if( rc==SQLITE_OK ){ sqlite3_int64 i2 = sqlite3_column_int64(pStmt, 2); rc = sqlite3Fts3SegReaderNew(p, iAge, i1, i2, 0, 0, 0, &pNew); } + + /* The following call to ReadBlock() serves to reset the SQL statement + ** used to retrieve blocks of data from the %_segments table. If it is + ** not reset here, then it may remain classified as an active statement + ** by SQLite, which may lead to "DROP TABLE" or "DETACH" commands + ** failing. + */ + rc2 = sqlite3Fts3ReadBlock(p, 0, 0, 0); if( rc==SQLITE_OK ){ - rc = sqlite3Fts3ReadBlock(p, 0, 0, 0); + rc = rc2; } } iAge++; diff --git a/manifest b/manifest index 88f6e71557..91225bb534 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Fix\san\sFTS3\sproblem\swhere\san\sOOM\serror\swas\snot\sbeing\spropagated\sback\nout\sto\sthe\stop-level\sinterface. -D 2009-12-04T13:43:00 +C Modify\s[2ad1461f25]\sto\savoid\sleaving\sa\sprepared\sstatement\sin\s"active"\sstate\sfollowing\san\sOOM\serror\sin\sFTS3. +D 2009-12-04T14:11:34 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -59,7 +56,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 fb2459bc19dfc3594ee66b3155444ca05f7ca903 +F ext/fts3/fts3.c da95f0191c2a016a78d12334ccfed76769043952 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h cc716c74afa7da8e0f8ef39404f33ea62a823eb3 F ext/fts3/fts3_expr.c c18794a62c257d3456d3314c5a18e348ae0d84bd @@ -405,7 +402,7 @@ F test/fts3expr.test 05dab77387801e4900009917bb18f556037d82da F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a F test/fts3malloc.test d02ee86b21edd2b43044e0d6dfdcd26cb6efddcb F test/fts3near.test dc196dd17b4606f440c580d45b3d23aa975fd077 -F test/fts3rnd.test 45beb753dfdde39f40aae8e3467e8bfe7e94cfe0 +F test/fts3rnd.test 65f534898c5f7cce3f51b2c2dfc179e2287346b2 F test/func.test af106ed834001738246d276659406823e35cde7b F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/fuzz.test a4174c3009a3e2c2e14b31b364ebf7ddb49de2c9 @@ -779,14 +776,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e8ae7e98977ff2a47237ad64f8a9a800a6d2797c -R 0e758f5e47d04871f42083bba7a7b4d8 -U drh -Z 836c78b8bfb06ee08ae63949c0d6547b ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFLGRHnoxKgR168RlERAlDOAKCBM26yhl/CHQAH9C/zrnwkIo3gxwCfUCC4 -tNbW8OhAD6vpZUfnJqfu1UI= -=oqsH ------END PGP SIGNATURE----- +P 2ad1461f255c2499367b706a5ec65b44c1fc1618 +R 434ac8eeb95fc4fd25e48da71a4aeaab +U dan +Z 61ea5bb3c9293e72eaba32fbcf09b0bf diff --git a/manifest.uuid b/manifest.uuid index a117cd44ba..efae3f5f76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2ad1461f255c2499367b706a5ec65b44c1fc1618 \ No newline at end of file +69c21ee46aeeb624fd8638b17ff7259a3e5f9a46 \ No newline at end of file diff --git a/test/fts3rnd.test b/test/fts3rnd.test index ca7122d82d..85141e62b4 100644 --- a/test/fts3rnd.test +++ b/test/fts3rnd.test @@ -79,6 +79,20 @@ proc simple_term {zTerm} { lsort -integer $ret } +proc simple_prefix {zPrefix} { + set ret [list] + set pattern [format "*%s%s*" $zPrefix [ + string repeat {[a-z]} [expr {3-[string length $zPrefix]}] + ]] + foreach {key value} [array get ::t1] { + if {[string match $pattern $value]} { lappend ret $key } + } + lsort -integer $ret +} + +proc simple_near {termlist nNear} { +} + foreach nodesize {50 500 1000 2000} { catch { array unset ::t1 } @@ -116,19 +130,31 @@ foreach nodesize {50 500 1000 2000} { # is the same as the result obtained by scanning the contents of the Tcl # array for each term. # - set n [expr {$iTest % ([llength $::lVocab]-10)}] - foreach term [lrange $::lVocab $n [expr $n+10]] { - do_test fts3rnd-1.$nodesize.$iTest.$term { + for {set i 0} {$i < 10} {incr i} { + set term [random_term] + do_test fts3rnd-1.$nodesize.$iTest.1.$i { execsql { SELECT docid FROM t1 WHERE t1 MATCH $term } } [simple_term $term] } + # This time, use the first two characters of each term as a term prefix + # to query for. Test that querying the Tcl array produces the same results + # as querying the FTS3 table for the prefix. + # + for {set i 0} {$i < 10} {incr i} { + set prefix [string range [random_term] 0 1] + set match "${prefix}*" + do_test fts3rnd-1.$nodesize.$iTest.2.$i { + execsql { SELECT docid FROM t1 WHERE t1 MATCH $match } + } [simple_prefix $prefix] + } + # Similar to the above, except for phrase queries. # for {set i 0} {$i < 10} {incr i} { set term [list [random_term] [random_term]] set match "\"$term\"" - do_test fts3rnd-1.$nodesize.$iTest.$match { + do_test fts3rnd-1.$nodesize.$iTest.3.$i { execsql { SELECT docid FROM t1 WHERE t1 MATCH $match } } [simple_term $term] } @@ -138,10 +164,22 @@ foreach nodesize {50 500 1000 2000} { for {set i 0} {$i < 10} {incr i} { set term [list [random_term] [random_term] [random_term]] set match "\"$term\"" - do_test fts3rnd-1.$nodesize.$iTest.$match { + do_test fts3rnd-1.$nodesize.$iTest.4.$i { execsql { SELECT docid FROM t1 WHERE t1 MATCH $match } } [simple_term $term] } + + # A NEAR query with terms as the arguments. + # +if 0 { + for {set i 0} {$i < 10} {incr i} { + set terms [list [random_term] [random_term]] + set match [join $terms " NEAR "] + do_test fts3rnd-1.$nodesize.$iTest.5.$i { + execsql { SELECT docid FROM t1 WHERE t1 MATCH $match } + } [simple_near $terms 10] + } +} } }