From 64799df78b14a12084d1def91c561abdcbcd8773 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Tue, 8 Sep 2020 15:18:12 -0700 Subject: [PATCH] .optimize() no longer cleans up _docsize This isn't necessary any more since the new .rebuild_fts() method can achieve the same thing. Refs #155, #153 --- docs/python-api.rst | 8 ++++---- sqlite_utils/db.py | 14 -------------- tests/test_fts.py | 18 ++++++++++++++++++ tests/test_optimize.py | 20 -------------------- 4 files changed, 22 insertions(+), 38 deletions(-) delete mode 100644 tests/test_optimize.py diff --git a/docs/python-api.rst b/docs/python-api.rst index d29133e..2564376 100644 --- a/docs/python-api.rst +++ b/docs/python-api.rst @@ -1228,6 +1228,10 @@ This method can be called on a table that has been configured for full-text sear db["dogs_fts"].rebuild_fts() +This runs the following SQL:: + + INSERT INTO dogs_fts (dogs_fts) VALUES ("rebuild"); + Optimizing a full-text search table =================================== @@ -1240,10 +1244,6 @@ Once you have populated a FTS table you can optimize it to dramatically reduce i This runs the following SQL:: INSERT INTO dogs_fts (dogs_fts) VALUES ("optimize"); - DELETE FROM [dogs_fts_docsize] WHERE id NOT IN ( - SELECT rowid FROM [dogs_fts]); - -That ``DELETE`` statement cleans up rows that may have been created by `an obscure bug `__ in previous versions of ``sqlite-utils``. Creating indexes ================ diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index e077231..c03530f 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -951,20 +951,6 @@ class Table(Queryable): table=fts_table ) ) - self.db.execute( - textwrap.dedent( - """ - DELETE FROM [{table}_docsize] WHERE {column} NOT IN ( - SELECT rowid FROM [{table}]); - """ - ) - .strip() - .format( - # FTS5 uses 'id' but FTS4 uses 'docid' - column=self.db["{}_docsize".format(fts_table)].columns[0].name, - table=fts_table, - ) - ) return self def search(self, q): diff --git a/tests/test_fts.py b/tests/test_fts.py index e0b5475..fb94a2e 100644 --- a/tests/test_fts.py +++ b/tests/test_fts.py @@ -1,4 +1,5 @@ import pytest +from sqlite_utils import Database from sqlite_utils.utils import sqlite3 search_records = [ @@ -199,3 +200,20 @@ def test_rebuild_fts_invalid(fresh_db, invalid_table): # Raise OperationalError on invalid table with pytest.raises(sqlite3.OperationalError): fresh_db[invalid_table].rebuild_fts() + + +@pytest.mark.parametrize("fts_version", ["FTS4", "FTS5"]) +def test_rebuild_removes_junk_docsize_rows(tmpdir, fts_version): + # Recreating https://github.com/simonw/sqlite-utils/issues/149 + path = tmpdir / "test.db" + db = Database(str(path), recursive_triggers=False) + licenses = [{"key": "apache2", "name": "Apache 2"}, {"key": "bsd", "name": "BSD"}] + db["licenses"].insert_all(licenses, pk="key", replace=True) + db["licenses"].enable_fts(["name"], create_triggers=True, fts_version=fts_version) + assert db["licenses_fts_docsize"].count == 2 + # Bug: insert with replace increases the number of rows in _docsize: + db["licenses"].insert_all(licenses, pk="key", replace=True) + assert db["licenses_fts_docsize"].count == 4 + # rebuild should fix this: + db["licenses_fts"].rebuild_fts() + assert db["licenses_fts_docsize"].count == 2 diff --git a/tests/test_optimize.py b/tests/test_optimize.py deleted file mode 100644 index 302532c..0000000 --- a/tests/test_optimize.py +++ /dev/null @@ -1,20 +0,0 @@ -import pytest -from sqlite_utils import Database -import sqlite3 - - -@pytest.mark.parametrize("fts_version", ["FTS4", "FTS5"]) -def test_optimizes_removes_junk_docsize_rows(tmpdir, fts_version): - # Recreating https://github.com/simonw/sqlite-utils/issues/149 - path = tmpdir / "test.db" - db = Database(str(path), recursive_triggers=False) - licenses = [{"key": "apache2", "name": "Apache 2"}, {"key": "bsd", "name": "BSD"}] - db["licenses"].insert_all(licenses, pk="key", replace=True) - db["licenses"].enable_fts(["name"], create_triggers=True, fts_version=fts_version) - assert db["licenses_fts_docsize"].count == 2 - # Bug: insert with replace increases the number of rows in _docsize: - db["licenses"].insert_all(licenses, pk="key", replace=True) - assert db["licenses_fts_docsize"].count == 4 - # Optimize should fix this: - db["licenses_fts"].optimize() - assert db["licenses_fts_docsize"].count == 2