sqlite3_exec: Any way to validate the first argument?
Is there a way to validate (check whether it exists) the first argument to sqlite3_exec?
(2) By Mark Benningfield (mbenningfield1) on 2021-09-30 16:15:22 in reply to 1 [link] [source]
Well, the first arg is an open database handle, which you would have had to call
sqlite3_open() to get, so presumably you know if it's valid or not??
If I open multiple databases, I can track the handles:
The last database that I open figures in the list of attached databases.
It is quite easy to transpose the digits in the handles of opened databases.
- a.When an 'invalid' handle is specified, there is no result.
- b. When there are no rows returned, there is no result.
The point in asking the question is simply to be able to distinguish between a & b.
Also, is there a (default) handle I can specify to coerce SQLite3 to check whether I have specified a schema in my SQL
e.g. select * from main.sales limit 10;
and to return the results?
I'm having difficulty understanding the difference between a "valid" database ("handle") and one that is not "valid". What does that mean, objectively? (I would have guessed as Mark did until your post 3, and given a similarly snark-inducing response.)
Guessing that it means "the one I want, which can be so verified by having certain schema elements", I recommend that you query the sqlite_schema table.
I don't think sqlite3_execute() has a helpful "check if my DB pointer is good" return mode, but almost every other function that takes the DB pointer will fail hard if wrong (fail how is hard to say, depends if the pointer points to valid but uninitialized memory, or invalid memory, etc.)
A test I usually do is simply prepare a statement with query: SELECT 2 * 3;
then check it returns SQLITE_OK, then step it, see the return value is good and check the single returned field is 6. Anything that isn't in perfect working order, from the SQLite DB engine to the DB being open or my own pointers, will cause that chain to fail, and it costs very few cycles.
I doubt that this is news to Ryan; I say the following to avoid any interpretation that seems to condone any invitation to undefined behavior.
If a sqlite3 pointer was returned (as an out parameter) by the sqlite3_open*() family of APIs, then a test such as Ryan's simple SELECR is fine (but pretty much useless with respect to proving anything reasonably in doubt.)
However, if you have something that you suspect is not a return from one of the sqlite3_open*() functions, passing it to any SQLite library API which expects a sqlite3 pointer, in lieu of such a pointer, is a very bad practice and should never be done in released code held out as the creation of any responsible programmer(s). Such folk do not court undefined behavior and strive to avoid it. Yet, that is exactly what such a "test" invites.
To emphasize what Larry said (lest someone thinks we represent different schools of thought), Larry's contention is absolutely correct and the test I have is used in pre-production code and the return values are used in ASSERT() statements for sanity checks. I sometimes get involved with the question to the point one forgets to also convey sane programming practices.
There is a very big difference between testing code for a pointer you obtained by valid means yourself and is sure where it comes from but unsure whether it is still valid during the test phase of your software - and - "trying" operations on memory pointers which you do not own or know where you got it from, even during testing. Such a programmer should be taken outside and shot.
Also, the entire notion of you ending up at a point where you do not know if a pointer you are using is still good, is a sign of serious incompleteness of your program - which is ok in development and testing, but atrocious in production.