# 2024 Sep 27 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the FTS5 module. # source [file join [file dirname [info script]] fts5_common.tcl] set testprefix fts5update2 # If SQLITE_ENABLE_FTS5 is not defined, omit this file. ifcapable !fts5 { finish_test return } #------------------------------------------------------------------------- # Test that the various types of UPDATE statement are handled correctly # by different table types. # foreach_detail_mode $testprefix { foreach {tn cu} { 1 0 2 1 } { reset_db do_execsql_test 1.$tn.1 " CREATE VIRTUAL TABLE ft1 USING fts5(a, b UNINDEXED, c UNINDEXED, d, content='', contentless_unindexed=$cu, detail=%DETAIL% ); CREATE VIRTUAL TABLE ft2 USING fts5(a, b UNINDEXED, c UNINDEXED, d, content='', contentless_unindexed=$cu, contentless_delete=1, detail=%DETAIL% ); " do_execsql_test 1.$tn.2 { INSERT INTO ft1(rowid, a, b, c, d) VALUES(1, 'a1', 'b1', 'c1', 'd1'); INSERT INTO ft1(rowid, a, b, c, d) VALUES(2, 'a2', 'b2', 'c2', 'd2'); INSERT INTO ft1(rowid, a, b, c, d) VALUES(3, 'a3', 'b3', 'c3', 'd3'); INSERT INTO ft2(rowid, a, b, c, d) VALUES(1, 'a1', 'b1', 'c1', 'd1'); INSERT INTO ft2(rowid, a, b, c, d) VALUES(2, 'a2', 'b2', 'c2', 'd2'); INSERT INTO ft2(rowid, a, b, c, d) VALUES(3, 'a3', 'b3', 'c3', 'd3'); } # It should be possible to update a subset of the UNINDEXED columns of # a contentless table. Regardless of whether or not contentless_unindexed=1 # or contentless_delete=1 is set. do_execsql_test 1.$tn.3 { UPDATE ft1 SET b=b||'.1'; UPDATE ft2 SET b=b||'.1'; } do_execsql_test 1.$tn.4 { UPDATE ft1 SET b=b||'.2', c=c||'.2'; UPDATE ft2 SET b=b||'.2', c=c||'.2'; } set res(0) { 1 {} {} {} {} 2 {} {} {} {} 3 {} {} {} {} } set res(1) { 1 {} b1.1.2 c1.2 {} 2 {} b2.1.2 c2.2 {} 3 {} b3.1.2 c3.2 {} } do_execsql_test 1.$tn.5 { SELECT rowid, * FROM ft2 } $res($cu) do_execsql_test 1.6.1 { SELECT rowid FROM ft1('a2') } {2} do_execsql_test 1.6.2 { SELECT rowid FROM ft2('a2') } {2} # It should be possible to update all indexed columns (but no other subset) # if the contentless_delete=1 option is set, as it is for "ft2". do_execsql_test 1.$tn.7 { UPDATE ft2 SET a='a22', d='d22' WHERE rowid=2; } do_execsql_test 1.$tn.8 { SELECT rowid FROM ft2('a22 AND d22') } {2} do_execsql_test 1.$tn.9 { UPDATE ft2 SET a='a33', d='d33', b='b3' WHERE rowid=3; } set res(1) { 1 {} b1.1.2 c1.2 {} 2 {} b2.1.2 c2.2 {} 3 {} b3 c3.2 {} } do_execsql_test 1.$tn.10 { SELECT rowid, * FROM ft2 } $res($cu) do_catchsql_test 1.$tn.11 { UPDATE ft2 SET a='a11' WHERE rowid=1 } {1 {cannot UPDATE a subset of columns on fts5 contentless-delete table: ft2}} do_catchsql_test 1.$tn.12 { UPDATE ft2 SET d='d11' WHERE rowid=1 } {1 {cannot UPDATE a subset of columns on fts5 contentless-delete table: ft2}} # It is not possible to update the values of indexed columns if # contentless_delete=1 is not set. do_catchsql_test 1.$tn.13 { UPDATE ft1 SET a='a11' WHERE rowid=1 } {1 {cannot UPDATE contentless fts5 table: ft1}} do_catchsql_test 1.$tn.14 { UPDATE ft1 SET d='d11' WHERE rowid=1 } {1 {cannot UPDATE contentless fts5 table: ft1}} # It should be possible to update the rowid if contentless_delete=1 is # set and all indexed columns are updated. do_execsql_test 1.$tn.15 { UPDATE ft2 SET a='aXone', d='dXone', rowid=11 WHERE rowid=1 } set res(0) { 2 {} {} {} {} 3 {} {} {} {} 11 {} {} {} {} } set res(1) { 2 {} b2.1.2 c2.2 {} 3 {} b3 c3.2 {} 11 {} b1.1.2 c1.2 {} } do_execsql_test 1.$tn.16 { SELECT rowid, * FROM ft2 } $res($cu) # Should not be possible to update the rowid of a contentless_delete=1 # table if no indexed columns are updated. do_catchsql_test 1.$tn.17 { UPDATE ft2 SET rowid=12 WHERE rowid=11 } {1 {cannot UPDATE a subset of columns on fts5 contentless-delete table: ft2}} do_catchsql_test 1.$tn.18 { UPDATE ft1 SET rowid=12 WHERE rowid=1 } {1 {cannot UPDATE contentless fts5 table: ft1}} do_execsql_test 1.$tn.19 { UPDATE ft2 SET a='aXtwo', d='dXtwo', c='newval', rowid=12 WHERE rowid=2 } {} set res(0) { 3 {} {} {} {} 11 {} {} {} {} 12 {} {} {} {} } set res(1) { 3 {} b3 c3.2 {} 11 {} b1.1.2 c1.2 {} 12 {} b2.1.2 newval {} } do_execsql_test 1.$tn.20 { SELECT rowid, * FROM ft2 } $res($cu) do_execsql_test 1.$tn.21 { SELECT rowid, * FROM ft2('aXtwo AND dXtwo') } [lrange $res($cu) 10 end] }} ;# end of [foreach_detail_mode] loop finish_test