fts5fault9.test 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. # 2015 September 3
  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. #
  12. # This file is focused on OOM errors.
  13. #
  14. source [file join [file dirname [info script]] fts5_common.tcl]
  15. source $testdir/malloc_common.tcl
  16. set testprefix fts5fault9
  17. # If SQLITE_ENABLE_FTS3 is defined, omit this file.
  18. ifcapable !fts5 {
  19. finish_test
  20. return
  21. }
  22. foreach_detail_mode $testprefix {
  23. if {"%DETAIL%" != "none"} continue
  24. fts5_aux_test_functions db
  25. do_execsql_test 1.0 {
  26. CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%);
  27. INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
  28. WITH seq(s) AS ( SELECT 1 UNION ALL SELECT s+1 FROM seq WHERE s<50)
  29. INSERT INTO t1 SELECT 'x x x y y y', 'a b c d e f' FROM seq;
  30. }
  31. do_faultsim_test 1 -faults oom-* -body {
  32. execsql { SELECT count(*) FROM t1('x AND y') }
  33. } -test {
  34. faultsim_test_result {0 50}
  35. }
  36. do_execsql_test 2.0 {
  37. CREATE VIRTUAL TABLE t2 USING fts5(a, b, detail=%DETAIL%);
  38. INSERT INTO t2(t2, rank) VALUES('pgsz', 32);
  39. INSERT INTO t2 VALUES('abc cba', 'cba abc');
  40. INSERT INTO t2 VALUES('abc cba', 'cba abc');
  41. INSERT INTO t2 VALUES('abc cba', 'cba abc');
  42. INSERT INTO t2 VALUES('axy cyx', 'cyx axy');
  43. INSERT INTO t2 VALUES('axy cyx', 'cyx axy');
  44. INSERT INTO t2 VALUES('axy cyx', 'cyx axy');
  45. }
  46. do_faultsim_test 2 -faults oom-* -body {
  47. execsql { SELECT count(*) FROM t2('a* AND c*') }
  48. } -test {
  49. faultsim_test_result {0 6}
  50. }
  51. do_execsql_test 3.0 {
  52. CREATE VIRTUAL TABLE t3 USING fts5(a, detail=%DETAIL%);
  53. INSERT INTO t3 VALUES('a x x a x a a a');
  54. INSERT INTO t3 VALUES('x a a x a x x x');
  55. }
  56. do_faultsim_test 3.1 -faults oom-* -body {
  57. execsql { SELECT highlight(t3, 0, '[', ']') FROM t3('a') }
  58. } -test {
  59. faultsim_test_result {0 {{[a] x x [a] x [a] [a] [a]} {x [a] [a] x [a] x x x}}}
  60. }
  61. do_faultsim_test 3.2 -faults oom-t* -body {
  62. execsql { SELECT fts5_test_poslist2(t3) FROM t3('x') }
  63. } -test {
  64. faultsim_test_result \
  65. {0 {{0.0.1 0.0.2 0.0.4} {0.0.0 0.0.3 0.0.5 0.0.6 0.0.7}}} \
  66. {1 SQLITE_NOMEM}
  67. }
  68. #-------------------------------------------------------------------------
  69. # Test OOM injection with the xPhraseFirstColumn() API and a tokenizer
  70. # uses query synonyms.
  71. #
  72. fts5_tclnum_register db
  73. do_execsql_test 4.0 {
  74. CREATE VIRTUAL TABLE t4 USING fts5(x, y, z, detail=%DETAIL%, tokenize=tclnum);
  75. INSERT INTO t4 VALUES('one two three', '1 2 3', 'i ii iii');
  76. INSERT INTO t4 VALUES('1 2 3', 'i ii iii', 'one two three');
  77. INSERT INTO t4 VALUES('i ii iii', 'one two three', 'i ii iii');
  78. INSERT INTO t4 VALUES('a1 a2 a3', 'a4 a5 a6', 'a7 a8 a9');
  79. INSERT INTO t4 VALUES('b1 b2 b3', 'b4 b5 b6', 'b7 b8 b9');
  80. INSERT INTO t4 VALUES('c1 c2 c3', 'c4 c5 c6', 'c7 c8 c9');
  81. }
  82. do_faultsim_test 4.1 -faults oom-t* -body {
  83. execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('2') }
  84. } -test {
  85. faultsim_test_result \
  86. {0 {1 {0.0 0.1 0.2} 2 {0.0 0.1 0.2} 3 {0.0 0.1 0.2}}} \
  87. {1 SQLITE_NOMEM} {1 SQLITE_ERROR} {1 {SQL logic error}}
  88. }
  89. do_faultsim_test 4.2 -faults oom-t* -body {
  90. execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('a5 OR b5 OR c5') }
  91. } -test {
  92. faultsim_test_result \
  93. {0 {4 {0.0 0.1 0.2} 5 {1.0 1.1 1.2} 6 {2.0 2.1 2.2}}} \
  94. {1 SQLITE_NOMEM} {1 SQLITE_ERROR} {1 {SQL logic error}}
  95. }
  96. #-------------------------------------------------------------------------
  97. # An OOM within an "ORDER BY rank" query.
  98. #
  99. db func rnddoc fts5_rnddoc
  100. do_execsql_test 5.0 {
  101. CREATE VIRTUAL TABLE xx USING fts5(x, y, detail=%DETAIL%);
  102. INSERT INTO xx VALUES ('def', 'abc ' || rnddoc(10));
  103. INSERT INTO xx VALUES ('def', 'abc abc' || rnddoc(9));
  104. INSERT INTO xx VALUES ('def', 'abc abc abc' || rnddoc(8));
  105. } {}
  106. faultsim_save_and_close
  107. do_faultsim_test 5 -faults oom-* -prep {
  108. faultsim_restore_and_reopen
  109. execsql { SELECT * FROM xx }
  110. } -body {
  111. execsql { SELECT rowid FROM xx('abc AND def') ORDER BY rank }
  112. } -test {
  113. faultsim_test_result [list 0 {3 2 1}]
  114. }
  115. set doc [string repeat "xyz " 500]
  116. do_execsql_test 6.0 {
  117. CREATE VIRTUAL TABLE yy USING fts5(y, detail=%DETAIL%);
  118. INSERT INTO yy(yy, rank) VALUES('pgsz', 64);
  119. INSERT INTO yy VALUES ($doc);
  120. INSERT INTO yy VALUES ('1 2 3');
  121. INSERT INTO yy VALUES ('xyz');
  122. UPDATE yy SET y = y WHERE rowid = 1;
  123. UPDATE yy SET y = y WHERE rowid = 1;
  124. UPDATE yy SET y = y WHERE rowid = 1;
  125. UPDATE yy SET y = y WHERE rowid = 1;
  126. } {}
  127. do_faultsim_test 6 -faults oom-* -body {
  128. execsql { SELECT rowid FROM yy('xyz') }
  129. } -test {
  130. faultsim_test_result [list 0 {1 3}]
  131. }
  132. } ;# foreach_detail_mode...
  133. finish_test