Actually, it makes perfect sense to me, but I wonder if the way it
exposes internal implementation details needs to be addressed.

Last spring, I made a change to fts2 to buffer updates within a
transaction, and flush them at commit.  This was a great performance
improvement for the common case of insertions where you allow the
table to pick the docid.  I was just testing some code using a tcl
statement about like this:

   db eval {create virtual table data using fts3;}
...
   for {} {} {} {
     db eval {
        begin;
          delete from data where rowid = $id;
          insert into data (content) values ("This is a test");
        end;
     }
     set id [db last_insert_rowid]
   }

Do you see the error?  Neither did I, until I was elbows-deep
debugging.  The end statement causes the buffered data to be flushed,
which naturally involves insertions, which naturally updates the
results of the last_insert_rowid!  All logical, but unexpected.

One fix would to undo the in-memory buffering code, or to modify it to
somehow turn the inserts into updates.  The former is undesirable (it
was a pretty sizable performance boost), and I'm not entirely sure how
to manage the latter, but it might be doable.  It might be less
error-prone to just expose a way for the virtual-table code to set
lastRowid directly.

A partial fix for _this_ case is to surround the code in vdbeaux.c
which calls virtual-table xSync to preserve db->lastRowid across the
call.  I say partial, because I think the code really would need to be
replicated to all virtual-table entry points (fts will also flush the
in-memory data before running a query).  I like the notion of having
the core take care of the problem, but it complicates all calls into
the virtual-table layer.

Any thoughts out there?

Thanks,
scott

-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to