Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | http://www.sqlite.org/cvstrac/tktview?tn=2166,35
Calling UPDATE against an fts table in a UTF-16 database inserts corrupted data into the database. The UTF-8 data is being inserted directly. This appears to happen because sqlite3_ value_text() destructively coerces a value to UTF-8, and it's never converted back when updating the table. This works around the problem by rearranging things so that the update happens before the coercion. (CVS 3596) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4f2ab4b6320ffc621900049b41f50bc3 |
User & Date: | shess 2007-01-19 22:59:57.000 |
2007-01-22
| ||
13:02 | Fix a pragma test so that it works in directories that have spaces in their names. (CVS 3597) (check-in: 071c957a5d user: drh tags: trunk) | |
2007-01-19
| ||
22:59 |
http://www.sqlite.org/cvstrac/tktview?tn=2166,35
Calling UPDATE against an fts table in a UTF-16 database inserts corrupted data into the database. The UTF-8 data is being inserted directly. This appears to happen because sqlite3_ value_text() destructively coerces a value to UTF-8, and it's never converted back when updating the table. This works around the problem by rearranging things so that the update happens before the coercion. (CVS 3596) (check-in: 4f2ab4b632 user: shess tags: trunk) | |
01:06 | Make sure the IS NULL optimization introduced by check-in (3494) correctly handles a LEFT JOIN where the a term from the right table of the join uses an IS NULL constraint. Ticket #2177. This check-in also adds the new test cases that were suppose to have been added with (3494) but which were mistakenly omitted. (CVS 3595) (check-in: 335863e4d1 user: drh tags: trunk) | |
︙ | ︙ | |||
3085 3086 3087 3088 3089 3090 3091 | static int index_update(fulltext_vtab *v, sqlite_int64 iRow, sqlite3_value **pValues, fts1Hash *pTerms){ /* Generate an empty doclist for each term that previously appeared in this * row. */ int rc = deleteTerms(v, pTerms, iRow); if( rc!=SQLITE_OK ) return rc; | < | > | | 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 | static int index_update(fulltext_vtab *v, sqlite_int64 iRow, sqlite3_value **pValues, fts1Hash *pTerms){ /* Generate an empty doclist for each term that previously appeared in this * row. */ int rc = deleteTerms(v, pTerms, iRow); if( rc!=SQLITE_OK ) return rc; rc = content_update(v, pValues, iRow); /* execute an SQL UPDATE */ if( rc!=SQLITE_OK ) return rc; /* Now add positions for terms which appear in the updated row. */ return insertTerms(v, pTerms, iRow, pValues); } /* This function implements the xUpdate callback; it's the top-level entry * point for inserting, deleting or updating a row in a full-text table. */ static int fulltextUpdate(sqlite3_vtab *pVtab, int nArg, sqlite3_value **ppArg, sqlite_int64 *pRowid){ fulltext_vtab *v = (fulltext_vtab *) pVtab; |
︙ | ︙ |
︙ | ︙ | |||
3606 3607 3608 3609 3610 3611 3612 3613 | * %_term table. */ static int index_update(fulltext_vtab *v, sqlite_int64 iRow, sqlite3_value **pValues, fts2Hash *pTerms){ /* Generate an empty doclist for each term that previously appeared in this * row. */ int rc = deleteTerms(v, pTerms, iRow); if( rc!=SQLITE_OK ) return rc; | < | > | | 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 | * %_term table. */ static int index_update(fulltext_vtab *v, sqlite_int64 iRow, sqlite3_value **pValues, fts2Hash *pTerms){ /* Generate an empty doclist for each term that previously appeared in this * row. */ int rc = deleteTerms(v, pTerms, iRow); if( rc!=SQLITE_OK ) return rc; rc = content_update(v, pValues, iRow); /* execute an SQL UPDATE */ if( rc!=SQLITE_OK ) return rc; /* Now add positions for terms which appear in the updated row. */ return insertTerms(v, pTerms, iRow, pValues); } /*******************************************************************/ /* InteriorWriter is used to collect terms and block references into ** interior nodes in %_segments. See commentary at top of file for ** format. */ |
︙ | ︙ |
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | # 2007 January 17 # # The author disclaims copyright to this source code. # #************************************************************************* # This file implements regression tests for SQLite fts1 library. The # focus here is testing handling of UPDATE when using UTF-16-encoded # databases. # # $Id: fts1i.test,v 1.1 2007/01/19 22:59:57 shess Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Return the UTF-16 representation of the supplied UTF-8 string $str. # If $nt is true, append two 0x00 bytes as a nul terminator. # NOTE(shess) Copied from capi3.test. proc utf16 {str {nt 1}} { set r [encoding convertto unicode $str] if {$nt} { append r "\x00\x00" } return $r } db eval { PRAGMA encoding = "UTF-16le"; CREATE VIRTUAL TABLE t1 USING fts1(content); } do_test fts1i-1.0 { execsql {PRAGMA encoding} } {UTF-16le} do_test fts1i-1.1 { execsql {INSERT INTO t1 (rowid, content) VALUES(1, 'one')} execsql {SELECT content FROM t1 WHERE rowid = 1} } {one} do_test fts1i-1.2 { set sql "INSERT INTO t1 (rowid, content) VALUES(2, 'two')" set STMT [sqlite3_prepare $DB $sql -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT execsql {SELECT content FROM t1 WHERE rowid = 2} } {two} do_test fts1i-1.3 { set sql "INSERT INTO t1 (rowid, content) VALUES(3, 'three')" set STMT [sqlite3_prepare $DB $sql -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT set sql "UPDATE t1 SET content = 'trois' WHERE rowid = 3" set STMT [sqlite3_prepare $DB $sql -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT execsql {SELECT content FROM t1 WHERE rowid = 3} } {trois} do_test fts1i-1.4 { set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(4, 'four')}] set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT execsql {SELECT content FROM t1 WHERE rowid = 4} } {four} do_test fts1i-1.5 { set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(5, 'five')}] set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT set sql "UPDATE t1 SET content = 'cinq' WHERE rowid = 5" set STMT [sqlite3_prepare $DB $sql -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT execsql {SELECT content FROM t1 WHERE rowid = 5} } {cinq} finish_test |
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | # 2007 January 17 # # The author disclaims copyright to this source code. # #************************************************************************* # This file implements regression tests for SQLite fts2 library. The # focus here is testing handling of UPDATE when using UTF-16-encoded # databases. # # $Id: fts2i.test,v 1.1 2007/01/19 22:59:57 shess Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl # Return the UTF-16 representation of the supplied UTF-8 string $str. # If $nt is true, append two 0x00 bytes as a nul terminator. # NOTE(shess) Copied from capi3.test. proc utf16 {str {nt 1}} { set r [encoding convertto unicode $str] if {$nt} { append r "\x00\x00" } return $r } db eval { PRAGMA encoding = "UTF-16le"; CREATE VIRTUAL TABLE t1 USING fts2(content); } do_test fts2i-1.0 { execsql {PRAGMA encoding} } {UTF-16le} do_test fts2i-1.1 { execsql {INSERT INTO t1 (rowid, content) VALUES(1, 'one')} execsql {SELECT content FROM t1 WHERE rowid = 1} } {one} do_test fts2i-1.2 { set sql "INSERT INTO t1 (rowid, content) VALUES(2, 'two')" set STMT [sqlite3_prepare $DB $sql -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT execsql {SELECT content FROM t1 WHERE rowid = 2} } {two} do_test fts2i-1.3 { set sql "INSERT INTO t1 (rowid, content) VALUES(3, 'three')" set STMT [sqlite3_prepare $DB $sql -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT set sql "UPDATE t1 SET content = 'trois' WHERE rowid = 3" set STMT [sqlite3_prepare $DB $sql -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT execsql {SELECT content FROM t1 WHERE rowid = 3} } {trois} do_test fts2i-1.4 { set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(4, 'four')}] set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT execsql {SELECT content FROM t1 WHERE rowid = 4} } {four} do_test fts2i-1.5 { set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(5, 'five')}] set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT set sql "UPDATE t1 SET content = 'cinq' WHERE rowid = 5" set STMT [sqlite3_prepare $DB $sql -1 TAIL] sqlite3_step $STMT sqlite3_finalize $STMT execsql {SELECT content FROM t1 WHERE rowid = 5} } {cinq} finish_test |