View Ticket
Not logged in
Ticket Hash: d1fe66d9cc3c7f33c6d6eaaf2a556199c0424099
Title: sqlite3_interrupt() can cause spatialite to enter infinite loop
Status: Open Type: Code_Defect
Severity: Severe Priority:
Subsystem: Resolution:
Last Modified: 2024-05-29 15:09:37
Version Found In: 5.1.0
User Comments:
anonymous added on 2024-05-29 15:09:37:

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++;
	    }
      }