On , Dan <[email protected]> wrote:

>> My doubt is the following: if from the progress callback (set with
>> sqlite3_progress_handler) I return non 0 and therefore I get
>> SQLITE_INTERRUPT from the call to sqlite3_step, is the sqlite3_stmt
>> object still in a valid state and will the query resume normally if I
>> pass the same sqlite3_stmt object back to sqlite3_step again ?
>
> No. Next call on the statement handle should be sqlite3_reset() or
> sqlite3_finalize().
>

I have tested it and I clearly confirm your comment :)

On , Roger Binns <[email protected]> wrote:

> Why don't you call the main message loop from within the progress
> handler callback?
>

Unfortunately, it's not that simple. The message loop loops both UI messages 
and customs messages internal to the application. For instance, I keep track of 
a sql statement in a object. The statement evolves after that object being 
affected a few times by execution messages. This way everything has their share 
of CPU and the ui works, while not relying on threading, because threading 
would require architectural and design changes in the application.
However, this is also one of the downfalls. I can have an arbitrary amount of 
sqlite databases open, and if I run the message loop inside the progress 
handler, I can theoretically have infinite reentrancy, where one progress 
handler executes something on a different database, being in practice limited 
by stack size, which would cause a crash.
Also, requesting the message loop to run has its performance penalty, so it 
lags the query a bit more than what's ideal.

Thank you for those suggestions, but I have though of many other options, those 
included.


So, today I was looking around the sqlite code and try to make this a reality, 
which is after interrupting a statement with a progress callback, leaving the 
sqlite3_stmt object in a state that can be resumed with another sqlite3_step 
call.
It turned out a few lines of code fix, but however it had a side effect. 
Internally, sqlite uses sqlite3_exec function and editing the code around those 
calls to store state to allow sqlite3_exec to be suspendable as well is not 
trivial nor simple. But I'm not using sqlite3_exec on my application, so I just 
editied this function on my local tree to set the progress handler to null and 
restore it in the end.

I code I needed to change to allow sqlite3_step to resume was just the 
following in file vdbe.c around line 5285, in function sqlite3VdbeExec:

   vdbe_error_halt:
     assert( rc );
     p->rc = rc;
+   if (rc != SQLITE_INTERRUPT){
       sqlite3VdbeHalt(p);
-
+   }
+   else
+   {
+       p->nCallback++;
+       p->pc = pc;
+   }
     if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
     rc = SQLITE_ERROR;


This is probably not enough, and could even had some side effects, none of 
which I encountered, because I have my own test suite for my own cases.

The question then becomes, would sqlite be able to support such thing in the 
future (suspending/resuming) ?

Thank you for your attention.
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to