fts5update2.test 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. # 2024 Sep 27
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #*************************************************************************
  11. # This file implements regression tests for SQLite library. The
  12. # focus of this script is testing the FTS5 module.
  13. #
  14. source [file join [file dirname [info script]] fts5_common.tcl]
  15. set testprefix fts5update2
  16. # If SQLITE_ENABLE_FTS5 is not defined, omit this file.
  17. ifcapable !fts5 {
  18. finish_test
  19. return
  20. }
  21. #-------------------------------------------------------------------------
  22. # Test that the various types of UPDATE statement are handled correctly
  23. # by different table types.
  24. #
  25. foreach_detail_mode $testprefix {
  26. foreach {tn cu} {
  27. 1 0
  28. 2 1
  29. } {
  30. reset_db
  31. do_execsql_test 1.$tn.1 "
  32. CREATE VIRTUAL TABLE ft1 USING fts5(a, b UNINDEXED, c UNINDEXED, d,
  33. content='',
  34. contentless_unindexed=$cu,
  35. detail=%DETAIL%
  36. );
  37. CREATE VIRTUAL TABLE ft2 USING fts5(a, b UNINDEXED, c UNINDEXED, d,
  38. content='',
  39. contentless_unindexed=$cu, contentless_delete=1,
  40. detail=%DETAIL%
  41. );
  42. "
  43. do_execsql_test 1.$tn.2 {
  44. INSERT INTO ft1(rowid, a, b, c, d) VALUES(1, 'a1', 'b1', 'c1', 'd1');
  45. INSERT INTO ft1(rowid, a, b, c, d) VALUES(2, 'a2', 'b2', 'c2', 'd2');
  46. INSERT INTO ft1(rowid, a, b, c, d) VALUES(3, 'a3', 'b3', 'c3', 'd3');
  47. INSERT INTO ft2(rowid, a, b, c, d) VALUES(1, 'a1', 'b1', 'c1', 'd1');
  48. INSERT INTO ft2(rowid, a, b, c, d) VALUES(2, 'a2', 'b2', 'c2', 'd2');
  49. INSERT INTO ft2(rowid, a, b, c, d) VALUES(3, 'a3', 'b3', 'c3', 'd3');
  50. }
  51. # It should be possible to update a subset of the UNINDEXED columns of
  52. # a contentless table. Regardless of whether or not contentless_unindexed=1
  53. # or contentless_delete=1 is set.
  54. do_execsql_test 1.$tn.3 {
  55. UPDATE ft1 SET b=b||'.1';
  56. UPDATE ft2 SET b=b||'.1';
  57. }
  58. do_execsql_test 1.$tn.4 {
  59. UPDATE ft1 SET b=b||'.2', c=c||'.2';
  60. UPDATE ft2 SET b=b||'.2', c=c||'.2';
  61. }
  62. set res(0) {
  63. 1 {} {} {} {}
  64. 2 {} {} {} {}
  65. 3 {} {} {} {}
  66. }
  67. set res(1) {
  68. 1 {} b1.1.2 c1.2 {}
  69. 2 {} b2.1.2 c2.2 {}
  70. 3 {} b3.1.2 c3.2 {}
  71. }
  72. do_execsql_test 1.$tn.5 {
  73. SELECT rowid, * FROM ft2
  74. } $res($cu)
  75. do_execsql_test 1.6.1 { SELECT rowid FROM ft1('a2') } {2}
  76. do_execsql_test 1.6.2 { SELECT rowid FROM ft2('a2') } {2}
  77. # It should be possible to update all indexed columns (but no other subset)
  78. # if the contentless_delete=1 option is set, as it is for "ft2".
  79. do_execsql_test 1.$tn.7 {
  80. UPDATE ft2 SET a='a22', d='d22' WHERE rowid=2;
  81. }
  82. do_execsql_test 1.$tn.8 { SELECT rowid FROM ft2('a22 AND d22') } {2}
  83. do_execsql_test 1.$tn.9 {
  84. UPDATE ft2 SET a='a33', d='d33', b='b3' WHERE rowid=3;
  85. }
  86. set res(1) {
  87. 1 {} b1.1.2 c1.2 {}
  88. 2 {} b2.1.2 c2.2 {}
  89. 3 {} b3 c3.2 {}
  90. }
  91. do_execsql_test 1.$tn.10 {
  92. SELECT rowid, * FROM ft2
  93. } $res($cu)
  94. do_catchsql_test 1.$tn.11 {
  95. UPDATE ft2 SET a='a11' WHERE rowid=1
  96. } {1 {cannot UPDATE a subset of columns on fts5 contentless-delete table: ft2}}
  97. do_catchsql_test 1.$tn.12 {
  98. UPDATE ft2 SET d='d11' WHERE rowid=1
  99. } {1 {cannot UPDATE a subset of columns on fts5 contentless-delete table: ft2}}
  100. # It is not possible to update the values of indexed columns if
  101. # contentless_delete=1 is not set.
  102. do_catchsql_test 1.$tn.13 {
  103. UPDATE ft1 SET a='a11' WHERE rowid=1
  104. } {1 {cannot UPDATE contentless fts5 table: ft1}}
  105. do_catchsql_test 1.$tn.14 {
  106. UPDATE ft1 SET d='d11' WHERE rowid=1
  107. } {1 {cannot UPDATE contentless fts5 table: ft1}}
  108. # It should be possible to update the rowid if contentless_delete=1 is
  109. # set and all indexed columns are updated.
  110. do_execsql_test 1.$tn.15 {
  111. UPDATE ft2 SET a='aXone', d='dXone', rowid=11 WHERE rowid=1
  112. }
  113. set res(0) {
  114. 2 {} {} {} {}
  115. 3 {} {} {} {}
  116. 11 {} {} {} {}
  117. }
  118. set res(1) {
  119. 2 {} b2.1.2 c2.2 {}
  120. 3 {} b3 c3.2 {}
  121. 11 {} b1.1.2 c1.2 {}
  122. }
  123. do_execsql_test 1.$tn.16 {
  124. SELECT rowid, * FROM ft2
  125. } $res($cu)
  126. # Should not be possible to update the rowid of a contentless_delete=1
  127. # table if no indexed columns are updated.
  128. do_catchsql_test 1.$tn.17 {
  129. UPDATE ft2 SET rowid=12 WHERE rowid=11
  130. } {1 {cannot UPDATE a subset of columns on fts5 contentless-delete table: ft2}}
  131. do_catchsql_test 1.$tn.18 {
  132. UPDATE ft1 SET rowid=12 WHERE rowid=1
  133. } {1 {cannot UPDATE contentless fts5 table: ft1}}
  134. do_execsql_test 1.$tn.19 {
  135. UPDATE ft2 SET a='aXtwo', d='dXtwo', c='newval', rowid=12 WHERE rowid=2
  136. } {}
  137. set res(0) {
  138. 3 {} {} {} {}
  139. 11 {} {} {} {}
  140. 12 {} {} {} {}
  141. }
  142. set res(1) {
  143. 3 {} b3 c3.2 {}
  144. 11 {} b1.1.2 c1.2 {}
  145. 12 {} b2.1.2 newval {}
  146. }
  147. do_execsql_test 1.$tn.20 {
  148. SELECT rowid, * FROM ft2
  149. } $res($cu)
  150. do_execsql_test 1.$tn.21 {
  151. SELECT rowid, * FROM ft2('aXtwo AND dXtwo')
  152. } [lrange $res($cu) 10 end]
  153. }} ;# end of [foreach_detail_mode] loop
  154. finish_test