SQLite User Forum

Tips for debugging a ”SQL logic error”?
Login

Tips for debugging a "SQL logic error"?

(1.1) By Simon Willison (simonw) on 2022-09-19 16:43:38 edited from 1.0 [link] [source]

I'm getting a strange error trying to query a SQLite database that uses FTS4.

I've published the database file here: https://static.simonwillison.net/static/2022/optimizedIndex.dsidx - it's 484KB.

I made the database using this tool: https://github.com/hynek/doc2dash

Here's the error:

% sqlite3 optimizedIndex.dsidx                       
SQLite version 3.37.0 2021-12-09 01:34:53
Enter ".help" for usage hints.
sqlite> select * from sqlite_master;
table|searchIndex|searchIndex|2|CREATE TABLE searchIndex(rowid INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT, titleDescription TEXT)
table|queryIndex|queryIndex|0|CREATE VIRTUAL TABLE queryIndex USING FTS4 (content="", perfect, prefix, suffixes, titleDescriptionPerfect, titleDescriptionPrefix, titleDescriptionSuffixes, matchinfo=fts3, tokenize=simple XX [* ])
table|queryIndex_segments|queryIndex_segments|3|CREATE TABLE 'queryIndex_segments'(blockid INTEGER PRIMARY KEY, block BLOB)
table|queryIndex_segdir|queryIndex_segdir|4|CREATE TABLE 'queryIndex_segdir'(level INTEGER,idx INTEGER,start_block INTEGER,leaves_end_block INTEGER,end_block INTEGER,root BLOB,PRIMARY KEY(level, idx))
index|sqlite_autoindex_queryIndex_segdir_1|queryIndex_segdir|5|
table|queryIndex_stat|queryIndex_stat|6|CREATE TABLE 'queryIndex_stat'(id INTEGER PRIMARY KEY, value BLOB)
view|wholeIndex|wholeIndex|0|CREATE VIEW wholeIndex AS SELECT queryIndex.rowid AS rowid, name, type, path, titleDescription, perfect, prefix, suffixes, titleDescriptionPerfect, titleDescriptionPrefix, titleDescriptionSuffixes FROM searchIndex JOIN queryIndex ON searchIndex.rowid = queryIndex.rowid
trigger|index_insert|wholeIndex|0|CREATE TRIGGER index_insert INSTEAD OF INSERT ON wholeIndex
BEGIN
INSERT INTO searchIndex (name, type, path, titleDescription) VALUES (NEW.name, NEW.type, NEW.path, NEW.titleDescription);
INSERT INTO queryIndex (rowid, perfect, prefix, suffixes, titleDescriptionPerfect, titleDescriptionPrefix, titleDescriptionSuffixes) VALUES (last_insert_rowid(), NEW.perfect, NEW.prefix, NEW.suffixes, NEW.titleDescriptionPerfect, NEW.titleDescriptionPrefix, NEW.titleDescriptionSuffixes);
END
sqlite> select * from wholeIndex;
Error: stepping, SQL logic error (1)

Any idea how I can go about understanding and working around this error?

(2) By Alex Garcia (alexgarciaxyz) on 2022-09-19 19:23:30 in reply to 1.1 [link] [source]

I've only seen SQL logic error whenever I'm querying a virtual table wrong, or when the virtual table has a bug. I'm sure that same error happens elsewhere too, but since your DB is working with fts4 virtual tables, I'm guessing it's that.

wholeIndex is a view for this query:

CREATE VIEW wholeIndex AS 
  SELECT 
    queryIndex.rowid AS rowid, 
    name, 
    type, 
    path, 
    titleDescription, 
    perfect, 
    prefix, 
    suffixes, 
    titleDescriptionPerfect, 
    titleDescriptionPrefix, 
    titleDescriptionSuffixes 
  FROM searchIndex 
  JOIN queryIndex ON searchIndex.rowid = queryIndex.rowid

searchIndex is a normal table, queryIndex is a fts4 virtual table:

CREATE VIRTUAL TABLE queryIndex USING FTS4 (content="", perfect, prefix, suffixes, titleDescriptionPerfect, titleDescriptionPrefix, titleDescriptionSuffixes, matchinfo=fts3, tokenize=simple XX [* ])
/* queryIndex(perfect,prefix,suffixes,titleDescriptionPerfect,titleDescriptionPrefix,titleDescriptionSuffixes) */;

In fact, querying queryIndex directly also throws a logic error:

sqlite> select * from queryIndex;
Runtime error: SQL logic error

Although adding a match makes the query work, but I can't get it to return anything in your DB:

sqlite> select * from queryIndex where titleDescriptionPrefix match 'the';
[nothing returned]

If I had to guess, queryIndex is probably corrupted/is not inserting data correctly. I can't find an alternative error message (because it's probably the fts4 module complaining about something but not giving a correct error message). I'd recommend reviewing how that queryIndex virtual table gets created/populated

(3.2) By Simon Willison (simonw) on 2022-09-20 03:30:54 edited from 3.1 in reply to 2 [source]

That gave me the idea to try this:

sqlite> PRAGMA integrity_check;
ok
sqlite> insert into queryIndex(queryIndex) values ('integrity-check');
Error: stepping, SQL logic error (1)
sqlite> insert into queryIndex(queryIndex) values ('rebuild');
Error: stepping, SQL logic error (1)
Using the integrity-check and rebuild commands from https://www.sqlite.org/fts3.html#commands - but as you can see they didn't help here.

This suggests that queryIndex should have some content in it:

sqlite> sqlite count(*) from queryIndex_segments;
43

This is weird... I'm trying to find the place in the https://github.com/hynek/doc2dash code that creates the FTS virtual table and I can't see it anywhere - I can only see code that inserts into the searchIndex table, but I can't find anything in there that would cause the FTS tables to be created or populated.