1
0
mirror of https://github.com/sqlite/sqlite.git synced 2026-01-06 08:01:16 +03:00

Do not allow the 'delete' command to be used on contentless_delete=1 fts5 tables.

FossilOrigin-Name: cc694b83408ccb5d42204cb624145c76e95329cbe1d1fe8815c70a7a00af231a
This commit is contained in:
dan
2023-07-17 17:59:58 +00:00
parent 24433bea19
commit 55e0fd4a9d
7 changed files with 54 additions and 34 deletions

View File

@@ -536,8 +536,8 @@ int sqlite3Fts5IndexReset(Fts5Index *p);
int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
int sqlite3Fts5IndexGetLocation(Fts5Index *p, i64 *piLoc);
int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iLoc, i64 iRowid);
int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin);
int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid);
/*
** End of interface to code in fts5_index.c.

View File

@@ -96,8 +96,8 @@
**
** Then, for V2 structures only:
**
** + lower location counter value,
** + upper location counter value
** + lower origin counter value,
** + upper origin counter value
**
** 2. The Averages Record:
**
@@ -337,7 +337,7 @@ struct Fts5DoclistIter {
** nOriginCntr:
** This value is set to non-zero for structure records created for
** contentlessdelete=1 tables only. In that case it represents the
** location value to apply to the next top-level segment created.
** origin value to apply to the next top-level segment created.
*/
struct Fts5StructureSegment {
int iSegid; /* Segment id */
@@ -4509,7 +4509,7 @@ static void fts5IndexMergeLevel(
/* Read input from all segments in the input level */
nInput = pLvl->nSeg;
/* Set the range of locations that will go into the output segment */
/* Set the range of origins that will go into the output segment */
if( pStruct->nOriginCntr>0 ){
pSeg->iOrigin1 = pLvl->aSeg[0].iOrigin1;
pSeg->iOrigin2 = pLvl->aSeg[pLvl->nSeg-1].iOrigin2;
@@ -6411,11 +6411,11 @@ int sqlite3Fts5IndexLoadConfig(Fts5Index *p){
return fts5IndexReturn(p);
}
int sqlite3Fts5IndexGetLocation(Fts5Index *p, i64 *piLoc){
int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin){
Fts5Structure *pStruct;
pStruct = fts5StructureRead(p);
if( pStruct ){
*piLoc = pStruct->nOriginCntr;
*piOrigin = pStruct->nOriginCntr;
fts5StructureRelease(pStruct);
}
return fts5IndexReturn(p);
@@ -6684,9 +6684,9 @@ static void fts5IndexTombstoneAdd(
/*
** Add iRowid to the tombstone list of the segment or segments that contain
** rows from location iLoc.
** rows from origin iOrigin.
*/
int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iLoc, i64 iRowid){
int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid){
Fts5Structure *pStruct;
pStruct = fts5StructureRead(p);
if( pStruct ){
@@ -6695,7 +6695,7 @@ int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iLoc, i64 iRowid){
int iSeg;
for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
if( pSeg->iOrigin1<=(u64)iLoc && pSeg->iOrigin2>=(u64)iLoc ){
if( pSeg->iOrigin1<=(u64)iOrigin && pSeg->iOrigin2>=(u64)iOrigin ){
fts5IndexTombstoneAdd(p, pSeg, iRowid);
}
}

View File

@@ -1653,7 +1653,14 @@ static int fts5UpdateMethod(
if( pConfig->eContent!=FTS5_CONTENT_NORMAL
&& 0==sqlite3_stricmp("delete", z)
){
rc = fts5SpecialDelete(pTab, apVal);
if( pConfig->bContentlessDelete ){
fts5SetVtabError(pTab,
"'delete' may not be used with a contentless_delete=1 table"
);
rc = SQLITE_ERROR;
}else{
rc = fts5SpecialDelete(pTab, apVal);
}
}else{
rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
}

View File

@@ -136,7 +136,7 @@ static int fts5StorageGetStmt(
case FTS5_STMT_LOOKUP_DOCSIZE:
zSql = sqlite3_mprintf(azStmt[eStmt],
(pC->bContentlessDelete ? ",location" : ""),
(pC->bContentlessDelete ? ",origin" : ""),
pC->zDb, pC->zName
);
break;
@@ -332,7 +332,7 @@ int sqlite3Fts5StorageOpen(
if( rc==SQLITE_OK && pConfig->bColumnsize ){
const char *zCols = "id INTEGER PRIMARY KEY, sz BLOB";
if( pConfig->bContentlessDelete ){
zCols = "id INTEGER PRIMARY KEY, sz BLOB, location INTEGER";
zCols = "id INTEGER PRIMARY KEY, sz BLOB, origin INTEGER";
}
rc = sqlite3Fts5CreateTable(pConfig, "docsize", zCols, 0, pzErr);
}
@@ -472,7 +472,7 @@ static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){
assert( p->pConfig->bContentlessDelete );
assert( p->pConfig->eContent==FTS5_CONTENT_NONE );
/* Look up the location of the document in the %_docsize table. Store
/* Look up the origin of the document in the %_docsize table. Store
** this in stack variable iLoc. */
rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
if( rc==SQLITE_OK ){
@@ -510,9 +510,9 @@ static int fts5StorageInsertDocsize(
if( rc==SQLITE_OK ){
sqlite3_bind_int64(pReplace, 1, iRowid);
if( p->pConfig->bContentlessDelete ){
i64 iLoc = 0;
rc = sqlite3Fts5IndexGetLocation(p->pIndex, &iLoc);
sqlite3_bind_int64(pReplace, 3, iLoc);
i64 iOrigin = 0;
rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin);
sqlite3_bind_int64(pReplace, 3, iOrigin);
}
if( rc==SQLITE_OK ){
sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);

View File

@@ -51,7 +51,7 @@ foreach {tn sql bError} {
execsql { ROLLBACK }
}
# Check that if contentless_delete=1 is specified, then the "location"
# Check that if contentless_delete=1 is specified, then the "origin"
# column is added to the %_docsize table.
reset_db
do_execsql_test 3.0 {
@@ -62,7 +62,7 @@ do_execsql_test 3.1 {
SELECT sql FROM sqlite_schema WHERE name IN ('x1_docsize', 'x2_docsize');
} {
{CREATE TABLE 'x1_docsize'(id INTEGER PRIMARY KEY, sz BLOB)}
{CREATE TABLE 'x2_docsize'(id INTEGER PRIMARY KEY, sz BLOB, location INTEGER)}
{CREATE TABLE 'x2_docsize'(id INTEGER PRIMARY KEY, sz BLOB, origin INTEGER)}
}
do_execsql_test 3.2.1 {
@@ -77,7 +77,7 @@ do_execsql_test 3.3 {
INSERT INTO x2 VALUES('second text');
}
do_execsql_test 3.4 {
SELECT id, location FROM x2_docsize
SELECT id, origin FROM x2_docsize
} {1 1 2 2}
do_execsql_test 3.5 {
SELECT level, segment, loc1, loc2 FROM fts5_structure(
@@ -247,5 +247,18 @@ do_test 7.2 {
do_execsql_test 7.3 { SELECT rowid FROM ft('one'); } {}
do_execsql_test 7.4 { SELECT rowid FROM ft('two'); } $lRowid
#-------------------------------------------------------------------------
reset_db
reset_db
do_execsql_test 8.0 {
CREATE VIRTUAL TABLE ft USING fts5(x, content='', contentless_delete=1);
INSERT INTO ft VALUES('hello world');
}
do_catchsql_test 8.1 {
INSERT INTO ft(ft, rowid, x) VALUES('delete', 1, 'hello world');
} {1 {'delete' may not be used with a contentless_delete=1 table}}
finish_test

View File

@@ -1,5 +1,5 @@
C Merge\strunk\schanges\sinto\sthis\sbranch.
D 2023-07-17T11:47:42.362
C Do\snot\sallow\sthe\s'delete'\scommand\sto\sbe\sused\son\scontentless_delete=1\sfts5\stables.
D 2023-07-17T17:59:58.252
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -86,15 +86,15 @@ F ext/fts3/unicode/mkunicode.tcl d5aebf022fa4577ee8cdf27468f0d847879993959101f6d
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
F ext/fts5/fts5.h c132a9323f22a972c4c93a8d5a3d901113a6e612faf30ca8e695788438c5ca2a
F ext/fts5/fts5Int.h 40a234875f9bddd43b4b4281d946303d227de943773b9e84505a0d6f0419c16a
F ext/fts5/fts5Int.h fa9dd8ecbda6340f406c6f21b9b524b4666817aa89850e60a42937eea87cef6a
F ext/fts5/fts5_aux.c 572d5ec92ba7301df2fea3258576332f2f4d2dfd66d8263afd157d9deceac480
F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b729225eeaf6a5
F ext/fts5/fts5_config.c 010fabcc0aaa0dfa76b19146e8bddf7de368933eeac01e294af6607447500caa
F ext/fts5/fts5_expr.c 2473c13542f463cae4b938c498d6193c90d38ea1a2a4f9849c0479736e50d24d
F ext/fts5/fts5_hash.c d4fb70940359f2120ccd1de7ffe64cc3efe65de9e8995b822cd536ff64c96982
F ext/fts5/fts5_index.c c38e8892905e9e57e22ca4441cb6fdb519f188d786efe541e9d4df24c34e9197
F ext/fts5/fts5_main.c c036530bbd39935b4b91fddb9d1b9d456e95c3685509aa975c87fc35445a9722
F ext/fts5/fts5_storage.c 9a84d28154cb570773b26eb9645f8670089dee45c95afebf7a041e414266b3c3
F ext/fts5/fts5_index.c 8e5fd1f1eb9489f1ba2eff2d3667ffd78a8d936c1180d284ccc6c37f25953a8f
F ext/fts5/fts5_main.c ede405f0f11db562653b988d043a531daa66093b46c1b35b8fcddb54819cba84
F ext/fts5/fts5_storage.c ee69d6c8195d2bf584ac8c5433e5c685812f39b48c7464f8aa76d9ed8b489119
F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
F ext/fts5/fts5_test_tok.c a2bed8edb25f6432e8cdb62aad5916935c19dba8dac2b8324950cfff397e25ff
@@ -132,7 +132,7 @@ F ext/fts5/test/fts5config.test 60094712debc59286c59aef0e6cf511c37d866802776a825
F ext/fts5/test/fts5conflict.test 655925678e630d3cdf145d18725a558971806416f453ac8410ca8c04d934238d
F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c073e19b3ae9126b2f4
F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283
F ext/fts5/test/fts5contentless.test 08af7954537cf89acbdef4fd79f39b3a36f382683a1eb98d5c827c187f51e113
F ext/fts5/test/fts5contentless.test 063249b7d0e92dc7ea54b4a179c466828927d720ee054031cbf6e06009c972bf
F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe
F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f
F ext/fts5/test/fts5corrupt3.test 7da9895dafa404efd20728f66ff4b94399788bdc042c36fe2689801bba2ccd78
@@ -535,8 +535,8 @@ F ext/wasm/index.html b768e8659b4fe311912e54d42906449d51c0f84b7f036cca47ec1f93bf
F ext/wasm/jaccwabyt/jaccwabyt.js 1264710db3cfbcb6887d95665b7aeba60c1126eaef789ca4cf1a4a17d5bc7f54
F ext/wasm/jaccwabyt/jaccwabyt.md 37911f00db12cbcca73aa1ed72594430365f30aafae2fa9c886961de74e5e0eb
F ext/wasm/module-symbols.html 841de62fc198988b8330e238c260e70ec93028b096e1a1234db31b187a899d10
F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96 w ext/wasm/scratchpad-wasmfs-main.html
F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63 w ext/wasm/scratchpad-wasmfs-main.js
F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96
F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63
F ext/wasm/speedtest1-wasmfs.html 0e9d335a9b5b5fafe6e1bc8dc0f0ca7e22e6eb916682a2d7c36218bb7d67379d
F ext/wasm/speedtest1-wasmfs.mjs ac5cadbf4ffe69e9eaac8b45e8523f030521e02bb67d654c6eb5236d9c456cbe
F ext/wasm/speedtest1-worker.html 97c2bf5f8534091ce718de05801090d5a80c3f13575996f095ba23638e1bdca0
@@ -2044,8 +2044,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 4410e60d0c76e057ee962124f9239c6e17fd5ccafdbb4d9b703448eabd7781e3 984d491eb3fe06f714bf07d6873321f3992a072812b46508e599bfefd39dff3e
R 3a33d523b0a231ecfa8d84bbc59989ba
P c4fb2f2ea0afe638fd7cffd89fbdb0a91589577c6f8299c7bbc17ac121be518b
R 461e0bbee60dbc3aadc58386c3f130fe
U dan
Z cf32871cae7a0d476c03b4d509e36da6
Z 81dd61cf0a290b6d176bc4273c289b56
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
c4fb2f2ea0afe638fd7cffd89fbdb0a91589577c6f8299c7bbc17ac121be518b
cc694b83408ccb5d42204cb624145c76e95329cbe1d1fe8815c70a7a00af231a