From 8786f7f589adf8edd686d03fc0297891b3b48766 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 Sep 2010 15:28:41 +0000 Subject: [PATCH] Have all FTS3 queries obtain a read or write table-lock at the shared-cache level before doing anything else. FossilOrigin-Name: 018e82c775d0fb8c0d90cddf7a87c20c8c8172a9 --- ext/fts3/fts3.c | 3 +++ ext/fts3/fts3Int.h | 1 + ext/fts3/fts3_write.c | 30 ++++++++++++++++++++++++++++++ manifest | 28 +++++++++------------------- manifest.uuid | 2 +- 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index bbb1b945a6..5323a5c1ae 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -2203,6 +2203,9 @@ static int fts3FilterMethod( return rc; } + rc = sqlite3Fts3ReadLock(p); + if( rc!=SQLITE_OK ) return rc; + rc = evalFts3Expr(p, pCsr->pExpr, &pCsr->aDoclist, &pCsr->nDoclist, 0); pCsr->pNextId = pCsr->aDoclist; pCsr->iPrevId = 0; diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h index c5be598e14..8ed31aedd8 100644 --- a/ext/fts3/fts3Int.h +++ b/ext/fts3/fts3Int.h @@ -273,6 +273,7 @@ int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char const**, int*); int sqlite3Fts3AllSegdirs(Fts3Table*, sqlite3_stmt **); int sqlite3Fts3MatchinfoDocsizeLocal(Fts3Cursor*, u32*); int sqlite3Fts3MatchinfoDocsizeGlobal(Fts3Cursor*, u32*); +int sqlite3Fts3ReadLock(Fts3Table *); /* Flags allowed as part of the 4th argument to SegmentReaderIterate() */ #define FTS3_SEGMENT_REQUIRE_POS 0x00000001 diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index cc3c362c8e..e434360953 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -322,6 +322,36 @@ int sqlite3Fts3ReadBlock( return SQLITE_OK; } +/* +** This function ensures that the caller has obtained a shared-cache +** table-lock on the %_content table. This is required before reading +** data from the fts3 table. If this lock is not acquired first, then +** the caller may end up holding read-locks on the %_segments and %_segdir +** tables, but no read-lock on the %_content table. If this happens +** a second connection will be able to write to the fts3 table, but +** attempting to commit those writes might return SQLITE_LOCKED or +** SQLITE_LOCKED_SHAREDCACHE (because the commit attempts to obtain +** write-locks on the %_segments and %_segdir ** tables). +** +** We try to avoid this because if FTS3 returns any error when committing +** a transaction, the whole transaction will be rolled back. And this is +** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can +** still happen if the user reads data directly from the %_segments or +** %_segdir tables instead of going through FTS3 though. +*/ +int sqlite3Fts3ReadLock(Fts3Table *p){ + int rc; /* Return code */ + sqlite3_stmt *pStmt; /* Statement used to obtain lock */ + + rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_null(pStmt, 1); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + } + return rc; +} + /* ** Set *ppStmt to a statement handle that may be used to iterate through ** all rows in the %_segdir table, from oldest to newest. If successful, diff --git a/manifest b/manifest index fde65b1722..4104052df4 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Completely\sremove\sall\strace\sof\sctype.h\sfrom\sFTS2. -D 2010-09-17T01:07:54 +C Have\sall\sFTS3\squeries\sobtain\sa\sread\sor\swrite\stable-lock\sat\sthe\sshared-cache\slevel\sbefore\sdoing\sanything\selse. +D 2010-09-17T15:28:42 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -64,9 +61,9 @@ 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 f6436b3bcd67f8638f2acd80583d26d3fcd81de5 +F ext/fts3/fts3.c 03be86c59ac1a60d448c6eda460a8975ff2f170d F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe -F ext/fts3/fts3Int.h 70528ba8c33991699f96ecc64112122833cdbdb5 +F ext/fts3/fts3Int.h b4f0b05ccafe1e5b4be2f052e9840dbd78a0395f F ext/fts3/fts3_expr.c 42d5697731cd30fbeabd081bb3e6d3df5531f606 F ext/fts3/fts3_hash.c 3c8f6387a4a7f5305588b203fa7c887d753e1f1c F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec @@ -76,7 +73,7 @@ F ext/fts3/fts3_snippet.c 2c4c921155e4b6befd272041fb903d999ac07d30 F ext/fts3/fts3_tokenizer.c b4f2d01c24573852755bc92864816785dae39318 F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3 F ext/fts3/fts3_tokenizer1.c 6e5cbaa588924ac578263a598e4fb9f5c9bb179d -F ext/fts3/fts3_write.c 4b21a0c6f2772b261f14e3a2e80e1e3e849268b0 +F ext/fts3/fts3_write.c 97a583b9e1d23d5af4278f3ee3c16a37c3e077f4 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9 F ext/icu/icu.c 850e9a36567bbcce6bd85a4b68243cad8e3c2de2 @@ -860,14 +857,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 9b272ed46fc704cb818b71d18ae8ee73a752a881 -R ec9abff0e1e30c45c3aa3ccb3e02d4e5 -U drh -Z eaed35cb764a960456de79e5b47e09e6 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFMkr9toxKgR168RlERAqDrAJ0UIliZKF7boeq4kfRQpga7FkaNtACfdx1m -EV1qqSjczz5T1tIS01ADlXI= -=CBtt ------END PGP SIGNATURE----- +P 876845661a944ec1c841d1e2486d070efb76e5cd +R 401b1a82d59ba178c1657b3c6769d891 +U dan +Z abafac0893458198170055470419f700 diff --git a/manifest.uuid b/manifest.uuid index f03abcb4c6..a1a5e14c13 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -876845661a944ec1c841d1e2486d070efb76e5cd \ No newline at end of file +018e82c775d0fb8c0d90cddf7a87c20c8c8172a9 \ No newline at end of file -- 2.47.2