/ Artifact Content
Login

Artifact 92dbea5665b6f333dd32886366481aa95ffaeb50:


# 2009 October 22
#
# 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 contains tests to verify that malloc() errors that occur
# within the FTS3 module code are handled correctly. 
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !fts3 { finish_test ; return }
source $testdir/malloc_common.tcl

do_malloc_test fts3_malloc-1.1 -sqlbody {
  CREATE VIRTUAL TABLE ft USING fts3(a, b, c);
}

do_malloc_test fts3_malloc-1.2 -sqlprep {
  CREATE VIRTUAL TABLE ft USING fts3(a, b, c);
} -sqlbody {
  DROP TABLE ft;
}

do_malloc_test fts3_malloc-1.3 -sqlprep {
  CREATE VIRTUAL TABLE ft USING fts3(content);
} -sqlbody {
  INSERT INTO ft VALUES('one two three four');
}

do_malloc_test fts3_malloc-1.4 -tclprep {
  db eval {CREATE VIRTUAL TABLE ft USING fts3(a, b)}
  for {set i 0} {$i<16} {incr i} {
    db eval { INSERT INTO ft VALUES('one two', 'three four') }
  }
} -sqlbody {
  INSERT INTO ft VALUES('one two', 'three four');
}

proc do_write_test {sql} {
  uplevel [list db eval $sql]
}

proc do_read_test {name sql result} {

  if {![info exists ::DO_MALLOC_TEST]} {
    set ::DO_MALLOC_TEST 1
  }

  set answers [list [list 0 $result]]
  if {$::DO_MALLOC_TEST } {
    set answers [list {1 {out of memory}} [list 0 $result]]
    set modes [list 100000 transient 1 persistent]
  } else {
    set modes [list 0 nofail]
  }
  set str [join $answers " OR "]

  foreach {nRepeat zName} $modes {
    for {set iFail 1} 1 {incr iFail} {
      if {$::DO_MALLOC_TEST} {sqlite3_memdebug_fail $iFail -repeat $nRepeat}

      set res [catchsql $sql]
      if {[lsearch $answers $res]>=0} {
        set res $str
      }
      do_test $name.$zName.$iFail [list set {} $res] $str
      set nFail [sqlite3_memdebug_fail -1 -benigncnt nBenign]
      if {$nFail==0} break
    }
  }
}

proc normal_list {l} {
  set ret [list]
  foreach elem $l {lappend ret $elem}
  set ret
}

db close
file delete -force test.db test.db-journal
sqlite3 db test.db
sqlite3_db_config_lookaside db 0 0 0
set sqlite_fts3_enable_parentheses 1


do_test fts3_malloc-2.0 {
  execsql { CREATE VIRTUAL TABLE ft USING fts3(a, b) }
  for {set ii 1} {$ii < 32} {incr ii} {
    set a [list]
    set b [list]
    if {$ii & 0x01} {lappend a one   ; lappend b neung}
    if {$ii & 0x02} {lappend a two   ; lappend b song }
    if {$ii & 0x04} {lappend a three ; lappend b sahm }
    if {$ii & 0x08} {lappend a four  ; lappend b see  }
    if {$ii & 0x10} {lappend a five  ; lappend b hah  }
    execsql { INSERT INTO ft VALUES($a, $b) }
  }
} {}

foreach {tn sql result} {
  1 "SELECT count(*) FROM sqlite_master" {5}
  2 "SELECT * FROM ft WHERE docid = 1"   {one neung}
  3 "SELECT * FROM ft WHERE docid = 2"   {two song}
  4 "SELECT * FROM ft WHERE docid = 3"   {{one two} {neung song}}

  5 "SELECT a FROM ft" {
    {one}                     {two}                 {one two}
    {three}                   {one three}           {two three}     
    {one two three}           {four}                {one four} 
    {two four}                {one two four}        {three four}   
    {one three four}          {two three four}      {one two three four}  
    {five}                    {one five}            {two five}            
    {one two five}            {three five}          {one three five} 
    {two three five}          {one two three five}  {four five}
    {one four five}           {two four five}       {one two four five}
    {three four five}         {one three four five} {two three four five}
    {one two three four five}
  }

  6 "SELECT a FROM ft WHERE a MATCH 'one'" {
    {one} {one two} {one three} {one two three}
    {one four} {one two four} {one three four} {one two three four}
    {one five} {one two five} {one three five} {one two three five}
    {one four five} {one two four five} 
    {one three four five} {one two three four five}
  }

  7 "SELECT a FROM ft WHERE a MATCH 'o*'" {
    {one} {one two} {one three} {one two three}
    {one four} {one two four} {one three four} {one two three four}
    {one five} {one two five} {one three five} {one two three five}
    {one four five} {one two four five} 
    {one three four five} {one two three four five}
  }

  8 "SELECT a FROM ft WHERE a MATCH 'o* t*'" {
    {one two}             {one three}           {one two three} 
    {one two four}        {one three four}      {one two three four} 
    {one two five}        {one three five}      {one two three five} 
    {one two four five}   {one three four five} {one two three four five}
  }

  9 "SELECT a FROM ft WHERE a MATCH '\"o* t*\"'" {
    {one two}             {one three}           {one two three} 
    {one two four}        {one three four}      {one two three four} 
    {one two five}        {one three five}      {one two three five} 
    {one two four five}   {one three four five} {one two three four five}
  }

  10 {SELECT a FROM ft WHERE a MATCH '"o* f*"'} {
    {one four}            {one five}            {one four five}
  }

  11 {SELECT a FROM ft WHERE a MATCH '"one two three"'} {
    {one two three}
    {one two three four}  
    {one two three five}
    {one two three four five}
  }

  12 {SELECT a FROM ft WHERE a MATCH '"two three four"'} {
    {two three four}
    {one two three four}
    {two three four five}
    {one two three four five}
  }

  12 {SELECT a FROM ft WHERE a MATCH '"two three" five'} {
    {two three five}         {one two three five}
    {two three four five}    {one two three four five}
  }

  13 {SELECT a FROM ft WHERE ft MATCH '"song sahm" hah'} {
    {two three five}         {one two three five}
    {two three four five}    {one two three four five}
  }

  14 {SELECT a FROM ft WHERE b MATCH 'neung'} {
    {one}                    {one two} 
    {one three}              {one two three}
    {one four}               {one two four} 
    {one three four}         {one two three four}
    {one five}               {one two five} 
    {one three five}         {one two three five}
    {one four five}          {one two four five} 
    {one three four five}    {one two three four five}
  }

  15 {SELECT a FROM ft WHERE b MATCH '"neung song sahm"'} {
    {one two three}          {one two three four}  
    {one two three five}     {one two three four five}
  }

  16 {SELECT a FROM ft WHERE b MATCH 'hah "song sahm"'} {
    {two three five}         {one two three five}
    {two three four five}    {one two three four five}
  }

  17 {SELECT a FROM ft WHERE b MATCH 'song OR sahm'} {
    {two}                     {one two}             {three}
    {one three}               {two three}           {one two three}
    {two four}                {one two four}        {three four}   
    {one three four}          {two three four}      {one two three four}  
    {two five}                {one two five}        {three five}
    {one three five}          {two three five}      {one two three five}
    {two four five}           {one two four five}   {three four five}
    {one three four five}     {two three four five} {one two three four five}
  }

  18 {SELECT a FROM ft WHERE a MATCH 'three NOT two'} {
    {three}                   {one three}           {three four}   
    {one three four}          {three five}          {one three five}
    {three four five}         {one three four five}
  }

  19 {SELECT a FROM ft WHERE b MATCH 'sahm NOT song'} {
    {three}                   {one three}           {three four}   
    {one three four}          {three five}          {one three five}
    {three four five}         {one three four five}
  }

  20 {SELECT a FROM ft WHERE ft MATCH 'sahm NOT song'} {
    {three}                   {one three}           {three four}   
    {one three four}          {three five}          {one three five}
    {three four five}         {one three four five}
  }

  21 {SELECT a FROM ft WHERE b MATCH 'neung NEAR song NEAR sahm'} {
    {one two three}          {one two three four}  
    {one two three five}     {one two three four five}
  }

} {
  set result [normal_list $result]
  do_read_test fts3_malloc-2.$tn $sql $result
}

do_test fts3_malloc-3.0 {
  execsql BEGIN
  for {set ii 32} {$ii < 1024} {incr ii} {
    set a [list]
    set b [list]
    if {$ii & 0x0001} {lappend a one   ; lappend b neung }
    if {$ii & 0x0002} {lappend a two   ; lappend b song  }
    if {$ii & 0x0004} {lappend a three ; lappend b sahm  }
    if {$ii & 0x0008} {lappend a four  ; lappend b see   }
    if {$ii & 0x0010} {lappend a five  ; lappend b hah   }
    if {$ii & 0x0020} {lappend a six   ; lappend b hok   }
    if {$ii & 0x0040} {lappend a seven ; lappend b jet   }
    if {$ii & 0x0080} {lappend a eight ; lappend b bairt }
    if {$ii & 0x0100} {lappend a nine  ; lappend b gow   }
    if {$ii & 0x0200} {lappend a ten   ; lappend b sip   }
    execsql { INSERT INTO ft VALUES($a, $b) }
  }
  execsql COMMIT
} {}
foreach {tn sql result} {
  1 "SELECT count(*) FROM ft" {1023}
  2 "SELECT a FROM ft WHERE a MATCH 'one two three four five six seven eight'" {
     {one two three four five six seven eight}
     {one two three four five six seven eight nine}
     {one two three four five six seven eight ten}
     {one two three four five six seven eight nine ten}
  }

  3 {SELECT count(*), sum(docid) FROM ft WHERE a MATCH 'o*'} {512 262144}
  4 {SELECT count(*), sum(docid) FROM ft WHERE a MATCH '"two three four"'} {
    128 66368
  }
} {
#set ::DO_MALLOC_TEST 0
  set result [normal_list $result]
  do_read_test fts3_malloc-3.$tn $sql $result
}

finish_test