Eduardo wrote:
At 14:27 06/11/2005, you wrote:
Eduardo
<[EMAIL PROTECTED]>
wrote:
Isn't better lock the database while a transaction that can make a
SQLITE_SCHEMA error, as is done with writes? A change in database is
always a change. Also that way you don't waste time in rerunning the
affected transactions.

It is indeed locked as you describe. The problem is as follows:
1. One db handle performs sqlite3_prepare. This does not in itself
start a transaction, but the resulting data structure (the prepared
statement) relies on details of the schema at the time of prepare.
E.g. "select * " query captures the list of columns when the
statement is prepared.
2. Another db handle performs a transaction that modifies the schema.
3. sqlite3_step is called on the statement prepared at #1. It is at
this point that the schema modification is discovered. Currently,
SQLite reports SQLITE_SCHEMA error in this situation. The proprosal
is for the statement to keep the text of the query, so the engine
can re-prepare the satement and try to step again, transparently to
the caller. 4. Once the first sqlite3_step succeeds, an implicit transaction is
started (I assume there are no explicit transactions in effect), so
the schema can no longer change unexpectedly.

Well, the write was an example.  So, a lock_schema wouldn't do the
work at the prepare phase? The schema begins locked and when a
transaction needs to do a change, sends a signal to gain exclusive,
unlock, make the changes and lock it again. Don't know how many cpu
cycles can this take but in a heavy scenario it may be less than
re-prepare, in some cases reparse, the other threaded transactions.

I don't quite follow how exactly this is supposed to help. Are you saying that there should be some kind of a lock from the moment the statement is prepared to the moment it is finalized, and no schema change should occur while this lock is held? I don't think this would be desirable - I beleve many applications now prepare certain often-used queries up front when the database handle is opened, and keep prepared statements around until it's time to close the database. Think of them as poor man's stored procedures.

You seem to think that the problem occurs when schema changes right in the middle of sqlite3_prepare call. This is not the case. The problem is that a prepared statement may sit around for a long time before it is actually used in a sqlite3_step call. At this point the engine may find out that the schema now differs from what it was when the statement was prepared, so the internal data structures are no longer valid. How do you propose to handle this situation, other than re-prepare? Would you prefer disabling any and all schema modifications for as long as there exists a single prepared statement?

Must add that doing this way you don't need to modify the API.

Must add that doing it the way Dr. Hipp proposed doesn't modify the API either. It simply makes one error code obsolete - the engine never reports it where it could be reported before. Fully backward compatible.

Igor Tandetnik

Reply via email to