When I attempt to interrupt a query to SQLite3 that is busy within SpatiaLite, SpatiaLite can get stuck in an infinite loop. It appears that there are a number of loops that call sqlite3_step()
and do not detect a result of SQLITE_INTERRUPT
correctly.
Here is an example call stack from our application through SQLite and to SpatiaLite that is stuck indefinitely. Because SQLite is in an interrupted state, the call to sqlite3_step()
only ever returns SQLITE_INTERRUPT
, so the SQLITE_DONE
exit never occurs.
This is an important issue for us, so we are going through and updating the code to handle SQLITE_INTERRUPT
. If you are willing to accept code submissions, we would be happy to do so. If you have any other suggestions for implementation, please share.
spatialite.dll!vspidx_check_rtree(sqlite3 * sqlite, const char * db_prefix, const char * table_name, const char * geom_column, char * * real_table, char * * real_geom) Line 277
at C:\dev\vcpkg\buildtrees\libspatialite\x64-windows-rel\src\spatialite\virtualspatialindex.c(277)
spatialite.dll!vspidx_filter(sqlite3_vtab_cursor * pCursor, int idxNum, const char * idxStr, int argc, sqlite3_value * * argv) Line 796
at C:\dev\vcpkg\buildtrees\libspatialite\x64-windows-rel\src\spatialite\virtualspatialindex.c(796)
SQLite3.dll!sqlite3VdbeExec(Vdbe * p) Line 96254
at C:\dev\vcpkg\buildtrees\sqlite3\src\3390200-90a72c9855.clean\sqlite3.c(96254)
SQLite3.dll!sqlite3Step(Vdbe * p) Line 86676
at C:\dev\vcpkg\buildtrees\sqlite3\src\3390200-90a72c9855.clean\sqlite3.c(86676)
SQLite3.dll!sqlite3_step(sqlite3_stmt * pStmt) Line 86737
at C:\dev\vcpkg\buildtrees\sqlite3\src\3390200-90a72c9855.clean\sqlite3.c(86737)
Application.exe!TSQLiteStatement.ExecuteBase() Line 4665
at FireDAC.Phys.SQLiteWrapper.pas(4665)
<...>
while (1)
{
/* scrolling the result set rows */
ret = sqlite3_step (stmt);
// spatialite.dll!vspidx_check_rtree(sqlite3 * sqlite, const char * db_prefix, const char * table_name, const char * geom_column, char * * real_table, char * * real_geom) Line 277
// at C:\dev\vcpkg\buildtrees\libspatialite\x64-windows-rel\src\spatialite\virtualspatialindex.c(277)
if (ret == SQLITE_DONE)
break; /* end of result set */
if (ret == SQLITE_ROW)
{
const char *v = (const char *) sqlite3_column_text (stmt, 0);
int len = sqlite3_column_bytes (stmt, 0);
if (rt)
free (rt);
rt = malloc (len + 1);
strcpy (rt, v);
v = (const char *) sqlite3_column_text (stmt, 1);
len = sqlite3_column_bytes (stmt, 1);
if (rg)
free (rg);
rg = malloc (len + 1);
strcpy (rg, v);
count++;
}
}