From: danielk1977 Date: Mon, 2 Jul 2007 10:16:49 +0000 (+0000) Subject: Modify handling of SQLITE_SCHEMA in fts2 code. An SQLITE_SCHEMA error may cause SQLit... X-Git-Tag: version-3.4.1~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ab9749ebb9a1b11ad4e1d719314a6b283e3e5402;p=thirdparty%2Fsqlite.git Modify handling of SQLITE_SCHEMA in fts2 code. An SQLITE_SCHEMA error may cause SQLite to reload the internal schema, deleting and recreating v-table objects. So the sqlite3_vtab structure can be deleted out from under a v-table implementation. (CVS 4151) FossilOrigin-Name: dee1a0fd28e8341af6523ab0c5628b671d7d2811 --- diff --git a/ext/fts2/fts2.c b/ext/fts2/fts2.c index b410febd21..fd7bc7971c 100644 --- a/ext/fts2/fts2.c +++ b/ext/fts2/fts2.c @@ -1947,20 +1947,15 @@ static int sql_step_statement(fulltext_vtab *v, fulltext_statement iStmt, if( rc==SQLITE_BUSY ) continue; if( rc!=SQLITE_ERROR ) return rc; - rc = sqlite3_reset(s); - if( rc!=SQLITE_SCHEMA ) return SQLITE_ERROR; - - v->pFulltextStatements[iStmt] = NULL; /* Still in s */ - rc = sql_get_statement(v, iStmt, &pNewStmt); - if( rc!=SQLITE_OK ) goto err; - *ppStmt = pNewStmt; - - rc = sqlite3_transfer_bindings(s, pNewStmt); - if( rc!=SQLITE_OK ) goto err; - + /* If an SQLITE_SCHEMA error has occured, then finalizing this + * statement is going to delete the fulltext_vtab structure. If + * the statement just executed is in the pFulltextStatements[] + * array, it will be finalized twice. So remove it before + * calling sqlite3_finalize(). + */ + v->pFulltextStatements[iStmt] = NULL; rc = sqlite3_finalize(s); - if( rc!=SQLITE_OK ) return rc; - s = pNewStmt; + break; } return rc; @@ -2018,25 +2013,17 @@ static int sql_step_leaf_statement(fulltext_vtab *v, int idx, if( rc==SQLITE_BUSY ) continue; if( rc!=SQLITE_ERROR ) return rc; - rc = sqlite3_reset(s); - if( rc!=SQLITE_SCHEMA ) return SQLITE_ERROR; - - v->pLeafSelectStmts[idx] = NULL; /* Still in s */ - rc = sql_get_leaf_statement(v, idx, &pNewStmt); - if( rc!=SQLITE_OK ) goto err; - *ppStmt = pNewStmt; - - rc = sqlite3_transfer_bindings(s, pNewStmt); - if( rc!=SQLITE_OK ) goto err; - + /* If an SQLITE_SCHEMA error has occured, then finalizing this + * statement is going to delete the fulltext_vtab structure. If + * the statement just executed is in the pLeafSelectStmts[] + * array, it will be finalized twice. So remove it before + * calling sqlite3_finalize(). + */ + v->pLeafSelectStmts[idx] = NULL; rc = sqlite3_finalize(s); - if( rc!=SQLITE_OK ) return rc; - s = pNewStmt; + break; } - return rc; - err: - sqlite3_finalize(s); return rc; } diff --git a/manifest b/manifest index 3b079d1bee..019fa240ca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\stemporary\svariable\sfor\sclarity\sof\spresentation\sin\na\sloop\sthat\sGCC\s4.2.0\sis\smiscompiling.\s\sTicket\s#2469.\s\sGCC\s4.2.0\smiscompiles\nthis\sloop\sregardless\sof\swhether\sor\snot\sthe\stemporary\svariable\sis\sused,\sbut\nby\sremoving\sthe\svariable,\swe\shope\sto\smake\sit\seasier\sto\sexplain\sthe\sproblem\nto\sGCC\smaintainers.\s\sThe\serror\sonly\sappears\sif\s-ftree-vrp\sis\sused\s(which\nis\sturned\son\sby\s-O2).\s(CVS\s4150) -D 2007-07-01T21:18:40 +C Modify\shandling\sof\sSQLITE_SCHEMA\sin\sfts2\scode.\sAn\sSQLITE_SCHEMA\serror\smay\scause\sSQLite\sto\sreload\sthe\sinternal\sschema,\sdeleting\sand\srecreating\sv-table\sobjects.\sSo\sthe\ssqlite3_vtab\sstructure\scan\sbe\sdeleted\sout\sfrom\sunder\sa\sv-table\simplementation.\s(CVS\s4151) +D 2007-07-02T10:16:50 F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -37,7 +37,7 @@ F ext/fts1/simple_tokenizer.c 1844d72f7194c3fd3d7e4173053911bf0661b70d F ext/fts1/tokenizer.h 0c53421b832366d20d720d21ea3e1f6e66a36ef9 F ext/fts2/README.tokenizers 2ff290e0a130f6e7611f2e608cb3b5aaea721abc F ext/fts2/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts2/fts2.c 4a177d5f296727f43df0ae315a850de8023ac5c5 +F ext/fts2/fts2.c 41a63f6e375c5b38ab126205a8d44656e2a15bf2 F ext/fts2/fts2.h da5f76c65163301d1068a971fd32f4119e3c95fa F ext/fts2/fts2_hash.c cafebb4620d19684c4c9872530012441df60f503 F ext/fts2/fts2_hash.h e283308156018329f042816eb09334df714e105e @@ -255,7 +255,7 @@ F test/fts2k.test 222d0b3bc8667753f18406aaea9906a6098ea016 F test/fts2l.test 4c53c89ce3919003765ff4fd8d98ecf724d97dd3 F test/fts2m.test 4b30142ead6f3ed076e880a2a464064c5ad58c51 F test/fts2n.test a70357e72742681eaebfdbe9007b87ff3b771638 -F test/fts2o.test ceac3203cd5d62c0402dcce89d5e28bae5d7481e +F test/fts2o.test c6a79567d85403dc4d15b89f3f9799a0a0aef065 F test/fts2token.test d8070b241a15ff13592a9ae4a8b7c171af6f445a F test/func.test 605989453d1b42cec1d05c17aa232dc98e3e04e6 F test/fuzz.test 62fc19dd36a427777fd671b569df07166548628a @@ -517,7 +517,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P cc2105176563c352a6dccef89a429a76b6f3adf5 -R 5ab68d3d21b1ac3447f261afad19b81e -U drh -Z cc964195494be17bba33eb2f44687e4f +P 35ae398bd37e4abbe362b0b780fc51153145b43d +R 2df8ed56393bd9b520dd9a9b5001f0a9 +U danielk1977 +Z ce1561116c719f1082e5e2fdc681fecd diff --git a/manifest.uuid b/manifest.uuid index 1302818867..ffb977b914 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -35ae398bd37e4abbe362b0b780fc51153145b43d \ No newline at end of file +dee1a0fd28e8341af6523ab0c5628b671d7d2811 \ No newline at end of file diff --git a/test/fts2o.test b/test/fts2o.test index d571ea81d0..5a33c45518 100644 --- a/test/fts2o.test +++ b/test/fts2o.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script is testing the FTS2 module. # -# $Id: fts2o.test,v 1.3 2007/06/27 17:09:25 danielk1977 Exp $ +# $Id: fts2o.test,v 1.4 2007/07/02 10:16:50 danielk1977 Exp $ # set testdir [file dirname $argv0] @@ -100,6 +100,70 @@ do_test fts2o-2.12 { execsql COMMIT execsql {SELECT a FROM fts_t1} } {{one three four} {one two three}} +do_test fts2o-2.12 { + execsql { SELECT a, b, c FROM fts_t1 WHERE c MATCH 'four'; } +} {{one three four} {one four} {one four two}} -finish_test +#------------------------------------------------------------------- +# Close, delete and reopen the database. The following test should +# be run on an initially empty db. +# +db close +file delete -force test.db test.db-journal +sqlite3 db test.db + +do_test fts2o-3.1 { + execsql { + CREATE VIRTUAL TABLE t1 USING fts2(a, b, c); + INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one two'); + SELECT a, b, c FROM t1 WHERE c MATCH 'two'; + } +} {{one three four} {one four} {one two}} + +# This test was crashing at one point. +# +do_test fts2o-3.2 { + execsql { + SELECT a, b, c FROM t1 WHERE c MATCH 'two'; + CREATE TABLE t3(a, b, c); + SELECT a, b, c FROM t1 WHERE c MATCH 'two'; + } +} {{one three four} {one four} {one two} {one three four} {one four} {one two}} + +#--------------------------------------------------------------------- +# Test that it is possible to rename an fts2 table in an attached +# database. +# +file delete -force test2.db test2.db-journal + +do_test fts2o-3.1 { + execsql { + ATTACH 'test2.db' AS aux; + CREATE VIRTUAL TABLE aux.t1 USING fts2(a, b, c); + INSERT INTO aux.t1(a, b, c) VALUES( + 'neung song sahm', 'neung see', 'neung see song' + ); + } +} {} + +do_test fts2o-3.2 { + execsql { SELECT a, b, c FROM aux.t1 WHERE a MATCH 'song'; } +} {{neung song sahm} {neung see} {neung see song}} +do_test fts2o-3.3 { + execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; } +} {{one three four} {one four} {one two}} + +do_test fts2o-3.4 { + execsql { ALTER TABLE aux.t1 RENAME TO t2 } +} {} + +do_test fts2o-3.2 { + execsql { SELECT a, b, c FROM t2 WHERE a MATCH 'song'; } +} {{neung song sahm} {neung see} {neung see song}} + +do_test fts2o-3.3 { + execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; } +} {{one three four} {one four} {one two}} + +finish_test