SQLite Forum

sqlite3_finalize after sqlite3_prepare_v2 error?

sqlite3_finalize after sqlite3_prepare_v2 error?

(1) By John Boncek (jboncek) on 2023-11-17 17:00:57 [source]

Using SQLite in C++. I can find no statement in the documentation about whether sqlite3_finalize should still be called if sqlite3_prepare_v2 returns an error (I don't know what would cause sqlite3_prepare_v2 to fail, but I want to handle it properly if it does). If sqlite3_prepare_v2 always leaves the prepared statement as null in that case, then it doesn't matter. Thanks for any assistance or a pointer to additional documentation about this.

(2.1) By Stephan Beal (stephan) on 2023-11-17 17:09:44 edited from 2.0 in reply to 1 [link] [source]

(I don't know what would cause sqlite3_prepare_v2 to fail

Passing a NULL to finalize() is perfectly legal and harmless, but passing an uninitalized pointer invokes undefined behavior.

The very first thing the prepare() variants do is assign *ppStmt to NULL and they only assign *ppStmt to non-NULL if they succeed. Thus if, after they return, that pointer is not NULL then (A) it succeeded and (B) you need to pass it to finalize().

There is one odd corner case: prepare() will succeed (return 0) for empty inputs (e.g. just comments or spaces) but *ppStmt will be NULL for that case. It's safe to pass that NULL to finalize() but it's not safe to assume that success equates to a non-NULL statement handle.

Edit: Citation: reading the source code. We'll get the docs updated to clarify this behavior.

(3) By Stephan Beal (stephan) on 2023-11-17 17:17:38 in reply to 2.1 [link] [source]

We'll get the docs updated to clarify this behavior.

Not necessary. The docs currently say:

*ppStmt is left pointing to a compiled prepared statement that can be executed using sqlite3_step(). If there is an error, *ppStmt is set to NULL. If the input text contains no SQL (if the input is an empty string or a comment) then *ppStmt is set to NULL. The calling procedure is responsible for deleting the compiled SQL statement using sqlite3_finalize() after it has finished with it. ppStmt may not be NULL.

Which seems to address all of the cases. finalize()'s own docs clarify that:

Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.

(4.1) By John Boncek (jboncek) on 2023-11-17 17:51:27 edited from 4.0 in reply to 3 [link] [source]

Thanks, missed the first doc reference.