According to the documentation of Virtual Tables and Opcodes:

xBegin( table ) is called to announce that SQlite intends to write to the 
table. There is no cursor involved. Do whatever is necessary to write to the 
backing store and set any VT implementation specific information in the table 
structure (e.g. a file handle enabled for writing)

xUpdate( table, rowid[, values] ) is called to perform a change (write to) the 
VT. Insert, delete or rewrite the record, or at least save whatever is required 
to actually perform the changes when xCommit is called.

xSync( table ) is called on ALL virtual tables involved in a transaction that 
is READY to commit. If anything is known that would cause a commit to fail, 
tell SQLite about that NOW.

xCommit( table ) resp. xRollback( table ) is called to instruct the VT to 
commit resp. rollback all the changes (made via xUpdate) since the last call to 
xBegin.


xOpen( table, cursor) is called to announce that SQLite intends to read from a 
table. A cursor cannot be used to write to a table. Do whatever is necessary to 
read from the backing store and set any VT implementation specific fields in 
the cursor structure (e.g. a file handle enabled for reading)

xFilter( cursor ) is called to set the cursor to the first row of data. If ths 
VT is in an inner loop (RH side, after reordering by the quera planner) of a 
join, xFilter may be called multiple times for the same cursor.

xRowid( cursor ), xColumn( cursor, field number ) return the unique(!!) rowid 
or the contents of the specfiied field of the current record

xNext( cursor ) advance to the next row

xEof( cursor ) query if there is a "current row"

xClose( cursor ) is called when SQLite no longer requires the cursor. NOTE: If 
you are using posix advisory locks in your VT implementation, it would be wise 
to postpone closing the file handle until the end of the transaction. Closing 
ANY file handle on a certain file in ANY thread will cause ALL the locks on 
that file held by ANY thread in the whole process to be released.


To avoid anomalies when changing "key fields", SQLite will scan through the 
whole cursor first, saving the rowids and new contents of the record(s) 
satisfying the WHERE clause. It will then close the cursor and call xUpdate for 
the affected records. The main sequence is:

xBegin()  - xOpen() - xFilter() - xNext()... - xClose() - xUpdate()... - 
xSync() - xCommit()



-----Ursprüngliche Nachricht-----
Von: sqlite-users [mailto:[email protected]] Im 
Auftrag von Dan Kennedy
Gesendet: Mittwoch, 29. März 2017 10:03
An: [email protected]
Betreff: Re: [sqlite] VT table behavior change between 3.10 and 3.17

On 03/29/2017 02:48 AM, Bob Friesenhahn wrote:
> We are trying to update from sqlite3 3.10 to 3.17. Our virtual table
> modules are encountering problems with 3.17 since the 'xOpen' callback
> is now being called for value change and row deletion operations.
> Previously it was only being called for read-only queries.

Something else is going on I think. There has never been a version of SQLite 
that could do an UPDATE or DELETE on a virtual table without invoking xOpen() 
to create a cursor. It needs the cursor to determine which rows are matched by 
the WHERE clause.

>
> We are using reader/writer locks and there is not a convenient way to
> transition from being a reader to being a writer.  A file is opened by
> the 'xOpen' callback and we need to know if the file should be opened
> read only, or read/write.
>
> The change in behavior can only work with virtual table modules which
> are able to smoothly transition between the state established by
> 'xOpen' to the 'xUpdate' call or know the intent when 'xOpen' is
> called.  This did not seem to be a requirement before.
>
> In what sqlite3 version did this behavior change?
>
> Is there a way to know when the 'xOpen' callback is called if it is to
> support an update transaction (i.e. 'xUpdate' callback will be called)?

When a write-transaction is opened on a virtual table the xBegin method is 
called. xCommit() or xRollback() to end the transaction. Any xOpen() that is 
part of an UPDATE or DELETE operation will occur within a transaction, and any 
xOpen() outside of a transaction must be a read-only query. But within an open 
transaction there is no way to tell whether a specific xOpen() call is part of 
a read-only or read-write statement.

Dan.

_______________________________________________
sqlite-users mailing list
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


___________________________________________
 Gunter Hick
Software Engineer
Scientific Games International GmbH
FN 157284 a, HG Wien
Klitschgasse 2-4, A-1130 Vienna, Austria
Tel: +43 1 80100 0
E-Mail: [email protected]

This communication (including any attachments) is intended for the use of the 
intended recipient(s) only and may contain information that is confidential, 
privileged or legally protected. Any unauthorized use or dissemination of this 
communication is strictly prohibited. If you have received this communication 
in error, please immediately notify the sender by return e-mail message and 
delete all copies of the original communication. Thank you for your cooperation.


_______________________________________________
sqlite-users mailing list
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to