SQLite Forum

How to check if sqlite3_stmt is done?
Login

How to check if sqlite3_stmt is done?

(1) By Baruch (baruch) on 2022-01-20 10:49:38 [link] [source]

How can I get the result of the latest call to sqlite3_step for a given sqlite3_stmt* without resetting? I want to check if the given statement ran to completion, but I don't want to have to keep the result code along with it

(2) By anonymous on 2022-01-20 11:14:47 in reply to 1 [link] [source]

int sqlite3_stmt_busy(sqlite3_stmt*);
The sqlite3_stmt_busy(S) interface returns true (non-zero) if the prepared statement S has been stepped at least once using sqlite3_step(S) but has neither run to completion (returned SQLITE_DONE from sqlite3_step(S)) nor been reset using sqlite3_reset(S)

(3) By Baruch (baruch) on 2022-01-20 12:27:31 in reply to 2 [link] [source]

If it was not stepped yet at all then this will give true even though it has not finished

(4) By Larry Brasfield (larrybr) on 2022-01-20 12:45:38 in reply to 3 [link] [source]

(Referring to a prepared statment, Baruch wrote:)

If it was not stepped yet at all then this will give true even though it has not finished

That assertion is contrary to what the API doc says. What leads you to say that?

(5) By Keith Medcalf (kmedcalf) on 2022-01-20 23:30:43 in reply to 4 [source]

It also contradicts the code for the function.

The code does exactly what the label on the tin says: it reports non-zero (true) if the referenced VDBE statement is "executing" (that is, the state is RUNNING and the PC (program counter) is non-zero. If the VDBE statement is not executing, then it returns zero (false).

A VDBE program does not enter the RUNNING state until it is stepped the first time. It stays in RUNNING state until it either completes (signals SQLITE_DONE) or it is de-rugged (has its execution context pulled out from underneath it by performing an sqlite3_reset on the statement, thus causing the statement to no longer have a "RUNNING" context -- similar to sending, for example, SIG_ABORT/SIG_KILL to an executing program).

Like any other executable, compiling the source code (sqlite3_prepare) does not cause the output executable to be executed. You have to cause the execution to begin (by, for example typing the name of the file containing the compiler output on the command line which is merely syntactic sugar for passing the executable blob to the loader for loading and execution). You must use the sqlite3_step against the VDBE statement (output of the sqlite3_prepare compiler) to put the "blob of executable code" into an executing state.

(6) By Baruch (baruch) on 2022-01-24 13:56:59 in reply to 4 [link] [source]

Sorry, my mistake. What I meant is that if I use this function to try to find out if a prepared statement ran to completion, I will get a false positive (i.e. my isDone() function will return true) in the case where it has not run at all.
sqlite3_stmt_busy itself will of course return false

(7) By Larry Brasfield (larrybr) on 2022-01-24 14:11:57 in reply to 6 [link] [source]

That is consistent with what the docs say. It appears a reread is due.

(8) By Baruch (baruch) on 2022-01-24 15:05:41 in reply to 7 [link] [source]

But it still doesn't solve my problem. How can I check if a statement is done? Or in other words, how can I check if it is safe to call step on it?

(10) By Larry Brasfield (larrybr) on 2022-01-24 16:45:59 in reply to 8 [link] [source]

how can I check if it is safe to call step on it?

It seems to be a problem of your own devising. ("I want to check if the given statement ran to completion, but I don't want to have to keep the result code along with it") If you are willing to preserve just 1 bit along with your sqlite3_statement pointer, to record whether it is "ready to run" or "has been run to completion", your problem is solved. But you are asking for some way to get at the execution state that is not presently exposed by the API, except by the dubious means of trying to step it and assessing the result in light of this doc.

I think you need to just bite the bullet and keep track of whether SQLITE_DONE has yet been returned without an intervening sqlite3_reset() call.

(11) By Keith Medcalf (kmedcalf) on 2022-01-24 17:01:02 in reply to 8 [link] [source]

You can also find the statement in the output of select * from sqlite_stmt which will return a bunch of data to you about each prepared statement on the connection including whether it is currently busy or not, and whether it has been run and how many times.

(9) By Keith Medcalf (kmedcalf) on 2022-01-24 16:45:00 in reply to 6 [link] [source]

This is true, because you are conflating the concept of doneness with the concept of being active. There is no API call to check that a statement has completed execution, only whether it is active or not.

How is it that you do not know if a statement has begun execution since it is only you that can make it so.