[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] -----------------------------------------------------------------------------