D. Richard Hipp wrote: > "Ulrich Telle" wrote: >> Sure, it would be nice if SQLITE_SCHEMA errors could be handled >> internally by SQLite, but I think it's a non-trivial task to handle >> this kind of error. >> >> When I created my SQLite C++ wrapper wxSQLite3 I thought about handling >> SCHEMA errors, but decided against it due to the complexities involved. > > Isn't that really the whole point of a wrapper - to deal with > complexities so that the user doesn't have to.
Of course a wrapper should hide as much of the complexities as possible. And be assured my wrapper wxSQLite3 hides a lot of them. > If you are passing all of the complexities up to the user, > why use you wrapper at all? Just call SQLite directly. Have I written somewhere my wrapper passes *all* complexities up to the user??? Definitely not! If I understood it right each of sqlite3_prepare/sqlite3_step/sqlite3_finalize may return a SQLITE_SCHEMA error. At least for a SELECT statement sqlite3_prepare is called *once* _before_ the data of *each row* are fetched using sqlite3_step and sqlite3_finalize is called *once* after all rows have been processed. A wrapper will seldom hide this kind of processing. So the wrapper can not know whether the application is processing the data of each row or collecting the data for later processing elsewhere. If the SQLITE_SCHEMA error occurs for example after already 10 rows were processed. What should the wrapper - or SQLite (if you decide to handle SCHEMA errors internally) - do? If you recompile the statement calling sqlite3_prepare wouldn't you refetch *all* rows again (unless you have counted the number of rows already fetched and now skip this number of rows before returning)? And what does it mean if the SQLITE_SCHEMA error occurs for the first time when calling sqlite3_finalize? Then you have already processed all rows. How on earth a wrapper could hide this from the user? If it is trivial to handle SQLITE_SCHEMA errors then SQLIte should do it. If not, why and how should a wrapper do it? >> For INSERT, UPDATE or DELETE a simple retry might be a good choice. But >> how often should the retry take place? The SQLite FAQ code example >> contains an endless loop! > > Not. OK, I guess in theory, if another process were updating the > schema at just the right rate so that the schema was different every > times you retried, you could get an infinite loop. But in practice, > the loop never runs more than twice - 3 times in the extreme. Coding infinite loops should be avoided even if there is only a theoretical possibility it will ever loop forever. >> In case of a SELECT statement the situation is still more complex. The >> SCHEMA error could happen after reading several result rows. > > No. SCHEMA errors happen prior to reading any data. You mean a SQLITE_SCHEMA error can only occur when you try to read the data of the *first* row of a SELECT query? And if you were able to read the first row you will be able to read *all* rows? Hard to believe but if that is truly the case then definitely SQLite should handle this error internally. At least the documentation should be more explicit about when a SQLITE_SCHEMA error may occur. >> When retrying a query another problem arises if the SQL statement >> contains bind variables. You would have to rebind the variables. To >> handle this automatically would induce a lot of extra house keeping, >> wouldn't it? > > See the sqlite3_transfer_bindings() API. If SQLite already keeps track of all bindings it should keep a copy of the SQL statement string, too. Regards, Ulrich Telle