[Find attached the file I'm using to debug this.]

I think I've found the difference causing this, but I don't understand
why it matters.  It all should apply to fts2, the code in question
didn't change in a way likely to change this.

When an insert is done against an fts1 table, index_insert() is called
with the list of sqlite3_values passed in from sqlite code, which in
turn calls content_insert() with those values, which runs an insert
statement binding each value to the appropriate parameter.  Then
index_insert() calls insertTerms() to tokenize the data and insert the
terms into the fulltext index.

When an update is done, index_update() is called with the list of
sqlite3_values.  Here, it calls insertTerms() to insert the terms into
the fulltext index, then content_update() to write the data into the
content table.

The important point is that insertTerms() calls sqlite3_value_text()
on the values.  This call appears to destructively convert a
UTF16LE-encoded value to a UTF8-encoded value.  So, on insert the
values bound are UTF16 values, while on update the values bound are
UTF8 values.

At this time I don't understand why this would be the case, I would
expect sqlite to convert things as needed (the enc variable in the
sqlite3_value _appears_ to be correct).  But, indeed, if I rearrange
the calls to insertTerms() and content_update() in fts1.c
index_update(), things work as expected.

-scott
#include "sqlite3.h"
#include <assert.h>

static sqlite3* db;

#define S(ret) assert( SQLITE_OK==ret );
#define D(ret) assert( SQLITE_DONE==ret );

void exec_dml(const wchar_t* cmd)
{
  sqlite3_stmt*   vm;

  S(sqlite3_prepare16(db, cmd, -1, &vm, 0));
  D(sqlite3_step(vm));
  S(sqlite3_finalize(vm));
}

void exec_query(const wchar_t* cmd)
{
  sqlite3_stmt*   vm;
  int rc;

  S(sqlite3_prepare16(db, cmd, -1, &vm, 0));
  if ((rc=sqlite3_step(vm)) == SQLITE_ROW)
  {
    wchar_t* result = (wchar_t*)sqlite3_column_text16(vm, 0);
    result=result;
  }
  else
  {
    assert( rc==SQLITE_DONE );
  }

  S(sqlite3_finalize(vm));
}

int main(int argc, char *argv[])
{
  S(sqlite3_open16(L"test.db", &db));
  exec_dml(L"DROP TABLE IF EXISTS t;");
  exec_dml(L"CREATE VIRTUAL TABLE t USING fts1(content);");
  exec_dml(L"INSERT INTO t (rowid, content) VALUES (1, 'this is a test');");

  exec_query(L"SELECT content FROM t WHERE rowid = 1;");
  exec_dml(L"UPDATE t SET content = 'that was a test' WHERE rowid = 1;");
  exec_query(L"SELECT content FROM t WHERE rowid = 1;");

  return 0;
}
-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to