SQLite

Check-in [918b609290]
Login

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

Overview
Comment:Further improvements to coverage of fts3.c. Fixes for bugs revealed by the same.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: 918b609290127f54326c638d82837d117398eade
User & Date: dan 2010-10-25 19:01:25.000
Context
2010-10-26
07:14
More coverage tests for fts3.c. (check-in: 7a2f286400 user: dan tags: experimental)
2010-10-25
19:01
Further improvements to coverage of fts3.c. Fixes for bugs revealed by the same. (check-in: 918b609290 user: dan tags: experimental)
12:47
Test coverage improvements for fts3.c. (check-in: a8b1d99899 user: dan tags: experimental)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/fts3/fts3.c.
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
static int fts3CreateTables(Fts3Table *p){
  int rc = SQLITE_OK;             /* Return code */
  int i;                          /* Iterator variable */
  char *zContentCols;             /* Columns of %_content table */
  sqlite3 *db = p->db;            /* The database connection */

  /* Create a list of user columns for the content table */
  if( p->bHasContent ){
    zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY");
    for(i=0; zContentCols && i<p->nColumn; i++){
      char *z = p->azColumn[i];
      zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z);
    }
    if( zContentCols==0 ) rc = SQLITE_NOMEM;

    /* Create the content table */
    fts3DbExec(&rc, db, 
       "CREATE TABLE %Q.'%q_content'(%s)",
       p->zDb, p->zName, zContentCols
    );
    sqlite3_free(zContentCols);
  }
  /* Create other tables */
  fts3DbExec(&rc, db, 
      "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);",
      p->zDb, p->zName
  );
  fts3DbExec(&rc, db, 
      "CREATE TABLE %Q.'%q_segdir'("







<
|
|
|
|
|
|

|
|
|
|
|
|
<







556
557
558
559
560
561
562

563
564
565
566
567
568
569
570
571
572
573
574
575

576
577
578
579
580
581
582
static int fts3CreateTables(Fts3Table *p){
  int rc = SQLITE_OK;             /* Return code */
  int i;                          /* Iterator variable */
  char *zContentCols;             /* Columns of %_content table */
  sqlite3 *db = p->db;            /* The database connection */

  /* Create a list of user columns for the content table */

  zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY");
  for(i=0; zContentCols && i<p->nColumn; i++){
    char *z = p->azColumn[i];
    zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z);
  }
  if( zContentCols==0 ) rc = SQLITE_NOMEM;

  /* Create the content table */
  fts3DbExec(&rc, db, 
     "CREATE TABLE %Q.'%q_content'(%s)",
     p->zDb, p->zName, zContentCols
  );
  sqlite3_free(zContentCols);

  /* Create other tables */
  fts3DbExec(&rc, db, 
      "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);",
      p->zDb, p->zName
  );
  fts3DbExec(&rc, db, 
      "CREATE TABLE %Q.'%q_segdir'("
1099
1100
1101
1102
1103
1104
1105

1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120

1121

1122
1123
1124
1125
1126
1127
1128
  int rc;                         /* Return code */
  int iHeight;                    /* Height of this node in tree */

  assert( piLeaf || piLeaf2 );

  sqlite3Fts3GetVarint32(zNode, &iHeight);
  rc = fts3ScanInteriorNode(p, zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2);

  
  if( rc==SQLITE_OK && iHeight>1 ){
    char *zBlob = 0;              /* Blob read from %_segments table */
    int nBlob;                    /* Size of zBlob in bytes */

    if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){
      rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob);
      if( rc==SQLITE_OK ){
        rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0);
      }
      sqlite3_free(zBlob);
      piLeaf = 0;
      zBlob = 0;
    }


    rc = sqlite3Fts3ReadBlock(p, piLeaf ? *piLeaf : *piLeaf2, &zBlob, &nBlob);

    if( rc==SQLITE_OK ){
      rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2);
    }
    sqlite3_free(zBlob);
  }

  return rc;







>
|














>
|
>







1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
  int rc;                         /* Return code */
  int iHeight;                    /* Height of this node in tree */

  assert( piLeaf || piLeaf2 );

  sqlite3Fts3GetVarint32(zNode, &iHeight);
  rc = fts3ScanInteriorNode(p, zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2);
  assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) );

  if( rc==SQLITE_OK && iHeight>1 ){
    char *zBlob = 0;              /* Blob read from %_segments table */
    int nBlob;                    /* Size of zBlob in bytes */

    if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){
      rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob);
      if( rc==SQLITE_OK ){
        rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0);
      }
      sqlite3_free(zBlob);
      piLeaf = 0;
      zBlob = 0;
    }

    if( rc==SQLITE_OK ){
      rc = sqlite3Fts3ReadBlock(p, piLeaf ? *piLeaf : *piLeaf2, &zBlob, &nBlob);
    }
    if( rc==SQLITE_OK ){
      rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2);
    }
    sqlite3_free(zBlob);
  }

  return rc;
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
  ** into a single doclist.
  */
  for(i=0; i<SizeofArray(pTS->aaOutput); i++){
    if( pTS->aaOutput[i] ){
      if( !aOut ){
        aOut = pTS->aaOutput[i];
        nOut = pTS->anOutput[i];
        pTS->aaOutput[0] = 0;
      }else{
        int nNew = nOut + pTS->anOutput[i];
        char *aNew = sqlite3_malloc(nNew);
        if( !aNew ){
          sqlite3_free(aOut);
          return SQLITE_NOMEM;
        }







|







1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
  ** into a single doclist.
  */
  for(i=0; i<SizeofArray(pTS->aaOutput); i++){
    if( pTS->aaOutput[i] ){
      if( !aOut ){
        aOut = pTS->aaOutput[i];
        nOut = pTS->anOutput[i];
        pTS->aaOutput[i] = 0;
      }else{
        int nNew = nOut + pTS->anOutput[i];
        char *aNew = sqlite3_malloc(nNew);
        if( !aNew ){
          sqlite3_free(aOut);
          return SQLITE_NOMEM;
        }
2250
2251
2252
2253
2254
2255
2256

2257
2258
2259
2260
2261
2262
2263
    if( isFirst ){
      pOut = pList;
      nOut = nList;
      if( pCsr->eEvalmode==FTS3_EVAL_FILTER && pPhrase->nToken>1 ){
        nDoc = fts3DoclistCountDocids(1, pOut, nOut);
      }
      isFirst = 0;

    }else{
      /* Merge the new term list and the current output. */
      char *aLeft, *aRight;
      int nLeft, nRight;
      int nDist;
      int mt;








>







2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
    if( isFirst ){
      pOut = pList;
      nOut = nList;
      if( pCsr->eEvalmode==FTS3_EVAL_FILTER && pPhrase->nToken>1 ){
        nDoc = fts3DoclistCountDocids(1, pOut, nOut);
      }
      isFirst = 0;
      iPrevTok = iTok;
    }else{
      /* Merge the new term list and the current output. */
      char *aLeft, *aRight;
      int nLeft, nRight;
      int nDist;
      int mt;

2271
2272
2273
2274
2275
2276
2277

2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
      assert( iPrevTok!=iTok );
      if( iPrevTok<iTok ){
        aLeft = pOut;
        nLeft = nOut;
        aRight = pList;
        nRight = nList;
        nDist = iTok-iPrevTok;

      }else{
        aRight = pOut;
        nRight = nOut;
        aLeft = pList;
        nLeft = nList;
        nDist = iPrevTok-iTok;
      }
      pOut = aRight;
      fts3DoclistMerge(
          mt, nDist, 0, pOut, &nOut, aLeft, nLeft, aRight, nRight, &nDoc
      );
      sqlite3_free(aLeft);
    }
    assert( nOut==0 || pOut!=0 );

    iPrevTok = iTok;
  }

  if( rc==SQLITE_OK ){
    if( ii!=pPhrase->nToken ){
      assert( pCsr->eEvalmode==FTS3_EVAL_FILTER && isReqPos==0 );
      fts3DoclistStripPositions(pOut, &nOut);
    }







>














<
<







2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294


2295
2296
2297
2298
2299
2300
2301
      assert( iPrevTok!=iTok );
      if( iPrevTok<iTok ){
        aLeft = pOut;
        nLeft = nOut;
        aRight = pList;
        nRight = nList;
        nDist = iTok-iPrevTok;
        iPrevTok = iTok;
      }else{
        aRight = pOut;
        nRight = nOut;
        aLeft = pList;
        nLeft = nList;
        nDist = iPrevTok-iTok;
      }
      pOut = aRight;
      fts3DoclistMerge(
          mt, nDist, 0, pOut, &nOut, aLeft, nLeft, aRight, nRight, &nDoc
      );
      sqlite3_free(aLeft);
    }
    assert( nOut==0 || pOut!=0 );


  }

  if( rc==SQLITE_OK ){
    if( ii!=pPhrase->nToken ){
      assert( pCsr->eEvalmode==FTS3_EVAL_FILTER && isReqPos==0 );
      fts3DoclistStripPositions(pOut, &nOut);
    }
Changes to test/fts3cov.test.
15
16
17
18
19
20
21

22
23
24
25
26
27
28
# If this build does not include FTS3, skip the tests in this file.
#
ifcapable !fts3 { finish_test ; return }
source $testdir/fts3_common.tcl
source $testdir/malloc_common.tcl

set DO_MALLOC_TEST 0


#--------------------------------------------------------------------------
# When it first needs to read a block from the %_segments table, the FTS3 
# module compiles an SQL statement for that purpose. The statement is 
# stored and reused each subsequent time a block is read. This test case 
# tests the effects of an OOM error occuring while compiling the statement.
#







>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# If this build does not include FTS3, skip the tests in this file.
#
ifcapable !fts3 { finish_test ; return }
source $testdir/fts3_common.tcl
source $testdir/malloc_common.tcl

set DO_MALLOC_TEST 0
set testprefix fts3cov

#--------------------------------------------------------------------------
# When it first needs to read a block from the %_segments table, the FTS3 
# module compiles an SQL statement for that purpose. The statement is 
# stored and reused each subsequent time a block is read. This test case 
# tests the effects of an OOM error occuring while compiling the statement.
#
364
365
366
367
368
369
370
371















































372
  INSERT INTO t13 VALUES('scalar two functions');
  INSERT INTO t13 VALUES('functions scalar two');
} -sqlbody {
  SELECT snippet(t13, '%%', '%%', '#') FROM t13 WHERE t13 MATCH 'two';
  SELECT snippet(t13, '%%', '%%') FROM t13 WHERE t13 MATCH 'two';
  SELECT snippet(t13, '%%') FROM t13 WHERE t13 MATCH 'two';
}
















































finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
  INSERT INTO t13 VALUES('scalar two functions');
  INSERT INTO t13 VALUES('functions scalar two');
} -sqlbody {
  SELECT snippet(t13, '%%', '%%', '#') FROM t13 WHERE t13 MATCH 'two';
  SELECT snippet(t13, '%%', '%%') FROM t13 WHERE t13 MATCH 'two';
  SELECT snippet(t13, '%%') FROM t13 WHERE t13 MATCH 'two';
}

do_execsql_test 14.0 {
  CREATE VIRTUAL TABLE t14 USING fts4(a, b);
  INSERT INTO t14 VALUES('one two three', 'one three four');
  INSERT INTO t14 VALUES('a b c', 'd e a');
}
do_execsql_test 14.1 {
  SELECT rowid FROM t14 WHERE t14 MATCH '"one two three"'
} {1}
do_execsql_test 14.2 {
  SELECT rowid FROM t14 WHERE t14 MATCH '"one four"'
} {}
do_execsql_test 14.3 {
  SELECT rowid FROM t14 WHERE t14 MATCH '"e a"'
} {2}
do_execsql_test 14.5 {
  SELECT rowid FROM t14 WHERE t14 MATCH '"e b"'
} {}
do_catchsql_test 14.6 {
  SELECT rowid FROM t14 WHERE rowid MATCH 'one'
} {1 {unable to use function MATCH in the requested context}}
do_catchsql_test 14.7 {
  SELECT rowid FROM t14 WHERE docid MATCH 'one'
} {1 {unable to use function MATCH in the requested context}}

do_execsql_test 15.0 {
  CREATE VIRTUAL TABLE t15 USING fts4(a, b, c);
  INSERT INTO t15 VALUES('abc def ghi', 'abc2 def2 ghi2', 'abc3 def3 ghi3');
  INSERT INTO t15 VALUES('abc2 def2 ghi2', 'abc2 def2 ghi2', 'abc def3 ghi3');
}
do_execsql_test 15.1 {
  SELECT rowid FROM t15 WHERE t15 MATCH '"abc* def2"'
} {1 2}

# Test a corruption case.
#
do_execsql_test 16.1 {
  CREATE VIRTUAL TABLE t16 USING fts4;
  INSERT INTO t16 VALUES('theoretical work to examine the relationship');
  INSERT INTO t16 VALUES('solution of our problems on the invisible');
  DELETE FROM t16_content WHERE rowid = 2;
}
do_catchsql_test 16.2 {
  SELECT * FROM t16 WHERE t16 MATCH 'invisible'
} {1 {database disk image is malformed}}



finish_test
Changes to test/fts3defer.test.
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
  }
  2 {
    set dmt_modes 0
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4 }
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
  }
  3 {
    set dmt_modes {0 1 2}
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4 }
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
    execsql $zero_long_doclists
  }
  4 {
    set dmt_modes 0
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4 }







|







206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
  }
  2 {
    set dmt_modes 0
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4 }
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
  }
  3 {
    #set dmt_modes {0 1 2}
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4 }
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
    execsql $zero_long_doclists
  }
  4 {
    set dmt_modes 0
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4 }
256
257
258
259
260
261
262










263
264
265
266
267
268
269
  } {12 13 29 30 40 47 48 52 63 92 93}
  do_select_test 1.8 {
    SELECT rowid FROM t1 WHERE t1 MATCH 'zm eh'
  } {68 100}
  do_select_test 1.9 {
    SELECT rowid FROM t1 WHERE t1 MATCH 'zm ubwrfqnbjf'
  } {7 70 98}











  do_select_test 2.1 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"zm agmckuiu"'
  } {3 24 52 53}
  do_select_test 2.2 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"zm zf"'
  } {33 53 75 88 101}







>
>
>
>
>
>
>
>
>
>







256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
  } {12 13 29 30 40 47 48 52 63 92 93}
  do_select_test 1.8 {
    SELECT rowid FROM t1 WHERE t1 MATCH 'zm eh'
  } {68 100}
  do_select_test 1.9 {
    SELECT rowid FROM t1 WHERE t1 MATCH 'zm ubwrfqnbjf'
  } {7 70 98}
  do_select_test 1.10 {
    SELECT rowid FROM t1 WHERE t1 MATCH 'z* vgsld'
  } {10 13 17 31 35 51 58 88 89 90 93 100}
  do_select_test 1.11 {
    SELECT rowid FROM t1 
    WHERE t1 MATCH '(
      zdu OR zexh OR zf OR zhbrzadb OR zidhxhbtv OR 
      zk OR zkhdvkw OR zm OR zsmhnf
    ) vgsld'
  } {10 13 17 31 35 51 58 88 89 90 93 100}

  do_select_test 2.1 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"zm agmckuiu"'
  } {3 24 52 53}
  do_select_test 2.2 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"zm zf"'
  } {33 53 75 88 101}
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  } {16 53}
  do_select_test 2.6 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"xh jk jk"'
  } {18}
  do_select_test 2.7 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"zm jk vgsld"'
  } {13 17}

  do_select_test 2.8 {
    SELECT rowid FROM t1 WHERE t1 MATCH 'z* vgsld'
  } {10 13 17 31 35 51 58 88 89 90 93 100}
  do_select_test 2.9 {
    SELECT rowid FROM t1 
    WHERE t1 MATCH '(
      zdu OR zexh OR zf OR zhbrzadb OR zidhxhbtv OR 
      zk OR zkhdvkw OR zm OR zsmhnf
    ) vgsld'
  } {10 13 17 31 35 51 58 88 89 90 93 100}

  do_select_test 3.1 {
    SELECT snippet(t1, '[', ']') FROM t1 WHERE t1 MATCH '"zm agmckuiu"'
  } {
    {zm [zm] [agmckuiu] uhzq nsab jk rrkx duszemmzl hyq jk} 
    {jk [zm] [agmckuiu] urvysbnykk jk jk zm zm jk jk} 
    {[zm] [agmckuiu] zexh fibokdry jk uhzq bu tugflixoex xnxhf sk} 







<

|
<
|
<
<
<
<
<
<







288
289
290
291
292
293
294

295
296

297






298
299
300
301
302
303
304
  } {16 53}
  do_select_test 2.6 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"xh jk jk"'
  } {18}
  do_select_test 2.7 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"zm jk vgsld"'
  } {13 17}

  do_select_test 2.8 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"zm jk vgsld lkjlkjlkj"'

  } {}







  do_select_test 3.1 {
    SELECT snippet(t1, '[', ']') FROM t1 WHERE t1 MATCH '"zm agmckuiu"'
  } {
    {zm [zm] [agmckuiu] uhzq nsab jk rrkx duszemmzl hyq jk} 
    {jk [zm] [agmckuiu] urvysbnykk jk jk zm zm jk jk} 
    {[zm] [agmckuiu] zexh fibokdry jk uhzq bu tugflixoex xnxhf sk} 
385
386
387
388
389
390
391









392





















393
394
395
    set DO_MALLOC_TEST 0
  }

  do_select_test 6.1 {
    SELECT rowid FROM t1 
    WHERE t1 MATCH 'vgsld (hrlipdm OR (aayxpmve duszemmzl))'
  } {10}









}























finish_test







>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
    set DO_MALLOC_TEST 0
  }

  do_select_test 6.1 {
    SELECT rowid FROM t1 
    WHERE t1 MATCH 'vgsld (hrlipdm OR (aayxpmve duszemmzl))'
  } {10}
  do_select_test 6.2.1 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"jk jcpiwj"'
  } {39 40}
  do_select_test 6.2.2 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"zm xnxhf"'
  } {40 47}
  do_select_test 6.2.3 {
    SELECT rowid FROM t1 WHERE t1 MATCH '"jk jcpiwj" OR "zm xnxhf"'
  } {39 40 47}
}

set testprefix fts3defer

do_execsql_test 3.1 {
  CREATE VIRTUAL TABLE x1 USING fts4(a, b);
  INSERT INTO x1 VALUES('a b c', 'd e f');
  INSERT INTO x1 SELECT * FROM x1;
  INSERT INTO x1 SELECT * FROM x1;
  INSERT INTO x1 SELECT * FROM x1;
  INSERT INTO x1 SELECT * FROM x1;
}
do_execsql_test 3.2 "
  INSERT INTO x1 VALUES(
    '[string repeat {d } 3000]', '[string repeat {f } 30000]'
  );
  INSERT INTO x1(x1) VALUES('optimize');
"

do_execsql_test 3.3 {
  SELECT count(*) FROM x1 WHERE x1 MATCH '"d e f"'
} {16}


finish_test
Added test/fts3fault.test.


































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# 2010 June 15
#
# 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.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

set ::testprefix fts3fault

# Test error handling in the sqlite3Fts3Init() function. This is the 
# function that registers the FTS3 module and various support functions
# with SQLite.
#
do_faultsim_test 1 -body { 
  sqlite3 db test.db 
  expr 0
} -test {
  catch { db close }
}

# Test error handling in an "ALTER TABLE ... RENAME TO" statement on an
# FTS3 table. Specifically, test renaming the table within a transaction
# after it has been written to.
#
faultsim_delete_and_reopen
do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE t1 USING fts3;
  INSERT INTO t1 VALUES('test renaming the table');
  INSERT INTO t1 VALUES(' after it has been written');
}
do_faultsim_test 2 -prep { 
  sqlite3 db test.db
  execsql {
    BEGIN;
      INSERT INTO t1 VALUES('registers the FTS3 module');
      INSERT INTO t1 VALUES('various support functions');
  }
} -body {
  execsql { ALTER TABLE t1 RENAME TO t2 }
} -test {
  faultsim_test_result {0 {}} 
}

# Test error handling in the special case where a single prefix query 
# matches terms that reside on a large range of leaf nodes.
#
do_test fts3fault-3.0 {
  sqlite3 db test.db
  execsql { CREATE VIRTUAL TABLE t3 USING fts4; }
  execsql { INSERT INTO t3(t3) VALUES('nodesize=50') }
  execsql { BEGIN }
  for {set i 0} {$i < 1000} {incr i} {
    execsql { INSERT INTO t3 VALUES('aaa' || $i) }
  }
  execsql { COMMIT }
} {}

do_faultsim_test 3 -faults oom-transient -prep { 
  sqlite3 db test.db
  execsql { SELECT * FROM t3 WHERE t3 MATCH 'x' }
} -body {
  execsql { SELECT count(rowid) FROM t3 WHERE t3 MATCH 'aa*' }
} -test {
  faultsim_test_result {0 1000} 
}

do_test fts3fault-4.0 {
  faultsim_delete_and_reopen
  execsql { 
    CREATE VIRTUAL TABLE t4 USING fts4; 
    INSERT INTO t4 VALUES('The British Government called on');
    INSERT INTO t4 VALUES('as pesetas then became much');
  }
} {}
faultsim_save_and_close
do_faultsim_test 4 -prep { 
  faultsim_restore_and_reopen
  execsql { SELECT content FROM t4 }
} -body {
  execsql { SELECT optimize(t4) FROM t4 LIMIT 1 }
} -test {
  faultsim_test_result {0 {{Index optimized}}}
}

do_test fts3fault-5.0 {
  faultsim_delete_and_reopen
  execsql { 
    CREATE VIRTUAL TABLE t5 USING fts4; 
    INSERT INTO t5 VALUES('The British Government called on');
    INSERT INTO t5 VALUES('as pesetas then became much');
  }
} {}
faultsim_save_and_close
do_faultsim_test 5 -prep { 
  faultsim_restore_and_reopen
  execsql { 
    BEGIN;
      INSERT INTO t5 VALUES('influential in shaping his future outlook');
      INSERT INTO t5 VALUES('might be acceptable to the British electorate');
  }
} -body {
  execsql { SELECT rowid FROM t5 WHERE t5 MATCH 'british' }
} -test {
  faultsim_test_result {0 {1 4}}
}

do_test fts3fault-6.0 {
  faultsim_delete_and_reopen
  execsql { CREATE VIRTUAL TABLE t6 USING fts4 }
} {}
faultsim_save_and_close
do_faultsim_test 6 -prep { 
  faultsim_restore_and_reopen
  execsql { SELECT rowid FROM t6 }
} -body {
  execsql { DROP TABLE t6 }
} -test {
  faultsim_test_result {0 {}}
}

finish_test
Changes to test/fts3query.test.
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

# Test the snippet() function with 1 to 6 arguments.
# 
do_execsql_test 6.1 {
  CREATE VIRTUAL TABLE t3 USING FTS4(a, b);
  INSERT INTO t3 VALUES('no gestures', 'another intriguing discovery by observing the hand gestures (called beats) people make while speaking. Research has shown that such gestures do more than add visual emphasis to our words (many people gesture while they''re on the telephone, for example); it seems they actually help our brains find words');
}

do_select_tests 6.2 {
  1 "SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'gestures'"
  {{<b>...</b>hand <b>gestures</b> (called beats) people make while speaking. Research has shown that such <b>gestures</b> do<b>...</b>}}

  2 "SELECT snippet(t3, 'XXX') FROM t3 WHERE t3 MATCH 'gestures'" 
  {{<b>...</b>hand XXXgestures</b> (called beats) people make while speaking. Research has shown that such XXXgestures</b> do<b>...</b>}}








<







169
170
171
172
173
174
175

176
177
178
179
180
181
182

# Test the snippet() function with 1 to 6 arguments.
# 
do_execsql_test 6.1 {
  CREATE VIRTUAL TABLE t3 USING FTS4(a, b);
  INSERT INTO t3 VALUES('no gestures', 'another intriguing discovery by observing the hand gestures (called beats) people make while speaking. Research has shown that such gestures do more than add visual emphasis to our words (many people gesture while they''re on the telephone, for example); it seems they actually help our brains find words');
}

do_select_tests 6.2 {
  1 "SELECT snippet(t3) FROM t3 WHERE t3 MATCH 'gestures'"
  {{<b>...</b>hand <b>gestures</b> (called beats) people make while speaking. Research has shown that such <b>gestures</b> do<b>...</b>}}

  2 "SELECT snippet(t3, 'XXX') FROM t3 WHERE t3 MATCH 'gestures'" 
  {{<b>...</b>hand XXXgestures</b> (called beats) people make while speaking. Research has shown that such XXXgestures</b> do<b>...</b>}}

192
193
194
195
196
197
198

199
200
201

  6 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 0) FROM t3 WHERE t3 MATCH 'gestures'" 
  {{no XXXgesturesYYY}}

  7 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 1, 5) FROM t3 WHERE t3 MATCH 'gestures'" 
  {{ZZZthe hand XXXgesturesYYY (called beatsZZZ}}
}


finish_test








>



191
192
193
194
195
196
197
198
199
200
201

  6 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 0) FROM t3 WHERE t3 MATCH 'gestures'" 
  {{no XXXgesturesYYY}}

  7 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 1, 5) FROM t3 WHERE t3 MATCH 'gestures'" 
  {{ZZZthe hand XXXgesturesYYY (called beatsZZZ}}
}


finish_test