/ Check-in [f45a0dc0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add extra fault injection tests to fts5.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | fts5
Files: files | file ages | folders
SHA1: f45a0dc0a8911c8aac5a1028ac4f543a709656e7
User & Date: dan 2015-01-20 20:34:17
Context
2015-01-21
06:36
Merge latest trunk changes with this branch. check-in: b3348b1e user: dan tags: fts5
2015-01-20
20:34
Add extra fault injection tests to fts5. check-in: f45a0dc0 user: dan tags: fts5
2015-01-19
11:15
Handle the case where a tokenizer determines that there are zero tokens in an fts5 query term. check-in: 75f3d17f user: dan tags: fts5
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts5/fts5_index.c.

   704    704         Fts5Config *pConfig = p->pConfig;
   705    705         rc = sqlite3_blob_open(pConfig->db, 
   706    706             pConfig->zDb, p->zDataTbl, "block", iRowid, 0, &p->pReader
   707    707         );
   708    708       }
   709    709   
   710    710       if( rc==SQLITE_OK ){
          711  +      u8 *aOut;                   /* Read blob data into this buffer */
   711    712         int nByte = sqlite3_blob_bytes(p->pReader);
   712    713         if( pBuf ){
   713    714           fts5BufferZero(pBuf);
   714         -        if( SQLITE_OK==fts5BufferGrow(&rc, pBuf, nByte) ){
   715         -          rc = sqlite3_blob_read(p->pReader, pBuf->p, nByte, 0);
   716         -          if( rc==SQLITE_OK ) pBuf->n = nByte;
          715  +        fts5BufferGrow(&rc, pBuf, nByte);
          716  +        aOut = pBuf->p;
          717  +        pBuf->n = nByte;
          718  +      }else{
          719  +        pRet = (Fts5Data*)sqlite3Fts5MallocZero(&rc, nByte+sizeof(Fts5Data));
          720  +        if( pRet ){
          721  +          pRet->n = nByte;
          722  +          aOut = pRet->p = (u8*)&pRet[1];
          723  +          pRet->nRef = 1;
   717    724           }
   718         -      }else{
   719         -        pRet = (Fts5Data*)fts5IdxMalloc(p, sizeof(Fts5Data) + nByte);
   720         -        if( !pRet ) return 0;
          725  +      }
   721    726   
   722         -        pRet->n = nByte;
   723         -        pRet->p = (u8*)&pRet[1];
   724         -        pRet->nRef = 1;
   725         -        rc = sqlite3_blob_read(p->pReader, pRet->p, nByte, 0);
   726         -        if( rc!=SQLITE_OK ){
   727         -          sqlite3_free(pRet);
   728         -          pRet = 0;
   729         -        }
          727  +      if( rc==SQLITE_OK ){
          728  +        rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0);
          729  +      }
          730  +      if( rc!=SQLITE_OK ){
          731  +        sqlite3_free(pRet);
          732  +        pRet = 0;
   730    733         }
   731    734       }
   732    735       p->rc = rc;
   733    736       p->nRead++;
   734    737     }
   735    738   
   736    739     return pRet;
................................................................................
  2977   2980       /* Extend the Fts5Structure object as required to ensure the output
  2978   2981       ** segment exists. */
  2979   2982       if( iLvl==pStruct->nLevel-1 ){
  2980   2983         fts5StructureAddLevel(&p->rc, ppStruct);
  2981   2984         pStruct = *ppStruct;
  2982   2985       }
  2983   2986       fts5StructureExtendLevel(&p->rc, pStruct, iLvl+1, 1, 0);
         2987  +    if( p->rc ) return;
  2984   2988       pLvl = &pStruct->aLevel[iLvl];
  2985   2989       pLvlOut = &pStruct->aLevel[iLvl+1];
  2986   2990   
  2987   2991       fts5WriteInit(p, &writer, iIdx, iSegid);
  2988   2992   
  2989   2993       /* Add the new segment to the output level */
  2990   2994       if( iLvl+1==pStruct->nLevel ) pStruct->nLevel++;

Changes to ext/fts5/test/fts5aa.test.

    17     17   
    18     18   # If SQLITE_ENABLE_FTS3 is defined, omit this file.
    19     19   ifcapable !fts5 {
    20     20     finish_test
    21     21     return
    22     22   }
    23     23   
    24         -if 0 {
    25         -
    26     24   do_execsql_test 1.0 {
    27     25     CREATE VIRTUAL TABLE t1 USING fts5(a, b, c);
    28     26     SELECT name, sql FROM sqlite_master;
    29     27   } {
    30     28     t1 {CREATE VIRTUAL TABLE t1 USING fts5(a, b, c)}
    31     29     t1_data {CREATE TABLE 't1_data'(id INTEGER PRIMARY KEY, block BLOB)}
    32     30     t1_content {CREATE TABLE 't1_content'(id INTEGER PRIMARY KEY, c0, c1, c2)}
................................................................................
   298    296   } {1 {unknown special query: stuff}}
   299    297   
   300    298   do_test 12.3 {
   301    299     set res [db one { SELECT t2 FROM t2 WHERE t2 MATCH '* reads ' }]
   302    300     string is integer $res
   303    301   } {1}
   304    302   
   305         -}
   306         -
   307    303   #-------------------------------------------------------------------------
   308    304   #
   309    305   reset_db
   310    306   do_execsql_test 13.1 {
   311    307     CREATE VIRTUAL TABLE t1 USING fts5(x);
   312    308     INSERT INTO t1(rowid, x) VALUES(1, 'o n e'), (2, 't w o');
   313    309   } {}

Changes to ext/fts5/test/fts5fault1.test.

    25     25   # Simple tests:
    26     26   #
    27     27   #   1: CREATE VIRTUAL TABLE
    28     28   #   2: INSERT statement
    29     29   #   3: DELETE statement
    30     30   #   4: MATCH expressions
    31     31   #
           32  +#
    32     33   
    33     34   if 1 {
    34     35   
    35     36   faultsim_save_and_close
    36     37   do_faultsim_test 1 -prep {
    37     38     faultsim_restore_and_reopen
    38     39   } -body {
................................................................................
    66     67     faultsim_restore_and_reopen
    67     68   } -body {
    68     69     execsql { DELETE FROM t1 }
    69     70   } -test {
    70     71     faultsim_test_result {0 {}} 
    71     72   }
    72     73   
    73         -}
    74         -
    75     74   reset_db
    76     75   do_execsql_test 4.0 {
    77     76     CREATE VIRTUAL TABLE t2 USING fts5(a, b);
    78     77     INSERT INTO t2 VALUES('m f a jj th q jr ar',   'hj n h h sg j i m');
    79     78     INSERT INTO t2 VALUES('nr s t g od j kf h',    'sb h aq rg op rb n nl');
    80     79     INSERT INTO t2 VALUES('do h h pb p p q fr',    'c rj qs or cr a l i');
    81     80     INSERT INTO t2 VALUES('lk gp t i lq mq qm p',  'h mr g f op ld aj h');
................................................................................
   103    102       faultsim_restore_and_reopen
   104    103     } -body "
   105    104       execsql { SELECT rowid FROM t2 WHERE t2 MATCH '$expr' }
   106    105     " -test "
   107    106       faultsim_test_result {[list 0 $res]}
   108    107     "
   109    108   }
          109  +
          110  +#-------------------------------------------------------------------------
          111  +# The following tests use a larger database populated with random data.
          112  +#
          113  +# The database page size is set to 512 bytes and the FTS5 page size left
          114  +# at the default 1000 bytes. This means that reading a node may require
          115  +# pulling an overflow page from disk, which is an extra opportunity for
          116  +# an error to occur.
          117  +#
          118  +reset_db
          119  +do_execsql_test 5.0.1 { 
          120  +  PRAGMA main.page_size = 512;
          121  +  CREATE VIRTUAL TABLE x1 USING fts5(a, b);
          122  +  PRAGMA main.page_size;
          123  +} {512}
          124  +
          125  +proc rnddoc {n} {
          126  +  set map [list 0 a  1 b  2 c  3 d  4 e  5 f  6 g  7 h  8 i  9 j]
          127  +  set doc [list]
          128  +  for {set i 0} {$i < $n} {incr i} {
          129  +    lappend doc [string map $map [format %.3d [expr int(rand()*1000)]]]
          130  +  }
          131  +  set doc
          132  +}
          133  +db func rnddoc rnddoc
          134  +
          135  +do_execsql_test 5.0.2 {
          136  +  WITH r(a, b) AS (
          137  +    SELECT rnddoc(6), rnddoc(6) UNION ALL
          138  +    SELECT rnddoc(6), rnddoc(6) FROM r
          139  +  )
          140  +  INSERT INTO x1 SELECT * FROM r LIMIT 10000;
          141  +}
          142  +
          143  +set res [db one {
          144  +  SELECT count(*) FROM x1 WHERE x1.a LIKE '%abc%' OR x1.b LIKE '%abc%'}
          145  +]
          146  +
          147  +do_faultsim_test 5.1 -faults oom* -body {
          148  +  execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'abc' }
          149  +} -test {
          150  +  faultsim_test_result [list 0 $::res]
          151  +}
          152  +do_faultsim_test 5.2 -faults oom* -body {
          153  +  execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'abcd' }
          154  +} -test {
          155  +  faultsim_test_result [list 0 0]
          156  +}
          157  +
          158  +proc test_astar {a b} {
          159  +  return [expr { [regexp {a[^ ][^ ]} $a] || [regexp {a[^ ][^ ]} $b] }]
          160  +}
          161  +db func test_astar test_astar
          162  +
          163  +set res [db one { SELECT count(*) FROM x1 WHERE test_astar(a, b) } ]
          164  +do_faultsim_test 5.3 -faults oom* -body {
          165  +  execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'a*' }
          166  +} -test {
          167  +  faultsim_test_result [list 0 $::res]
          168  +}
          169  +
          170  +do_faultsim_test 5.4 -faults oom* -prep {
          171  +  db close
          172  +  sqlite3 db test.db
          173  +} -body {
          174  +  execsql { INSERT INTO x1 VALUES('a b c d', 'e f g h') }
          175  +} -test {
          176  +  faultsim_test_result [list 0 {}]
          177  +}
          178  +
          179  +}
          180  +
          181  +#-------------------------------------------------------------------------
          182  +#
          183  +reset_db
          184  +do_execsql_test 6.0 {
          185  +  CREATE VIRTUAL TABLE x1 USING fts5(x);
          186  +  INSERT INTO x1(x1, rank) VALUES('automerge', 0);
          187  +
          188  +  INSERT INTO x1 VALUES('a b c'); -- 1
          189  +  INSERT INTO x1 VALUES('a b c'); -- 2
          190  +  INSERT INTO x1 VALUES('a b c'); -- 3
          191  +  INSERT INTO x1 VALUES('a b c'); -- 4
          192  +  INSERT INTO x1 VALUES('a b c'); -- 5
          193  +  INSERT INTO x1 VALUES('a b c'); -- 6
          194  +  INSERT INTO x1 VALUES('a b c'); -- 7
          195  +  INSERT INTO x1 VALUES('a b c'); -- 8
          196  +  INSERT INTO x1 VALUES('a b c'); -- 9
          197  +  INSERT INTO x1 VALUES('a b c'); -- 10
          198  +  INSERT INTO x1 VALUES('a b c'); -- 11
          199  +  INSERT INTO x1 VALUES('a b c'); -- 12
          200  +  INSERT INTO x1 VALUES('a b c'); -- 13
          201  +  INSERT INTO x1 VALUES('a b c'); -- 14
          202  +  INSERT INTO x1 VALUES('a b c'); -- 15
          203  +
          204  +  SELECT count(*) FROM x1_data;
          205  +} {17}
          206  +
          207  +faultsim_save_and_close
          208  +
          209  +do_faultsim_test 6.1 -faults oom-tr* -prep {
          210  +  faultsim_restore_and_reopen
          211  +} -body {
          212  +  execsql { INSERT INTO x1 VALUES('d e f') }
          213  +} -test {
          214  +  faultsim_test_result [list 0 {}]
          215  +  if {$testrc==0} {
          216  +    set nCnt [db one {SELECT count(*) FROM x1_data}]
          217  +    if {$nCnt!=3} { error "expected 3 entries but there are $nCnt" }
          218  +  }
          219  +}
   110    220   
   111    221   finish_test
   112    222