/ Check-in [3126754c]
Login

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

Overview
Comment:Fix a floating-point exception that can occur when an FTS4 query contains a large number of tokens connected by AND or NEAR operators.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3126754c72351c724be29d75a194bfc3e7b67205
User & Date: dan 2011-10-18 12:44:04
References
2011-10-18
12:49
Cherrypick patch [3126754c72] from the trunk into the content= branch. check-in: f9b5b217 user: dan tags: fts4-content
Context
2011-10-18
18:10
Improved handling of USING and NATURAL JOIN in 3-way and higher joins. Ticket [3338b3fa19ac4ab] check-in: 551ce407 user: drh tags: trunk
12:44
Fix a floating-point exception that can occur when an FTS4 query contains a large number of tokens connected by AND or NEAR operators. check-in: 3126754c user: dan tags: trunk
2011-10-17
23:15
Change the OP_JournalMode implementation so that it works even if a substitute sqlite3PagerFilename() that might return NULL is used. check-in: 491ff5fb user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3.c.

3962
3963
3964
3965
3966
3967
3968



3969

3970
3971
3972
3973
3974
3975
3976
      ** that will be loaded if all subsequent tokens are deferred.
      */
      Fts3PhraseToken *pToken = pTC->pToken;
      rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol);
      fts3SegReaderCursorFree(pToken->pSegcsr);
      pToken->pSegcsr = 0;
    }else{



      nLoad4 = nLoad4*4;

      if( ii==0 || pTC->pPhrase->nToken>1 ){
        /* Either this is the cheapest token in the entire query, or it is
        ** part of a multi-token phrase. Either way, the entire doclist will
        ** (eventually) be loaded into memory. It may as well be now. */
        Fts3PhraseToken *pToken = pTC->pToken;
        int nList = 0;
        char *pList = 0;







>
>
>
|
>







3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
      ** that will be loaded if all subsequent tokens are deferred.
      */
      Fts3PhraseToken *pToken = pTC->pToken;
      rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol);
      fts3SegReaderCursorFree(pToken->pSegcsr);
      pToken->pSegcsr = 0;
    }else{
      /* Set nLoad4 to the value of (4^nOther) for the next iteration of the
      ** for-loop. Except, limit the value to 2^24 to prevent it from 
      ** overflowing the 32-bit integer it is stored in. */
      if( ii<12 ) nLoad4 = nLoad4*4;

      if( ii==0 || pTC->pPhrase->nToken>1 ){
        /* Either this is the cheapest token in the entire query, or it is
        ** part of a multi-token phrase. Either way, the entire doclist will
        ** (eventually) be loaded into memory. It may as well be now. */
        Fts3PhraseToken *pToken = pTC->pToken;
        int nList = 0;
        char *pList = 0;

Changes to test/fts3defer.test.

444
445
446
447
448
449
450
451

452



























453
  );
  INSERT INTO x1(x1) VALUES('optimize');
"

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






























finish_test








>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
  );
  INSERT INTO x1(x1) VALUES('optimize');
"

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

# At one point the following was causing a floating-point exception.
#
do_execsql_test 4.1 {
  CREATE VIRTUAL TABLE x2 USING FTS4(x);
  BEGIN;
  INSERT INTO x2 VALUES('m m m m m m m m m m m m m m m m m m m m m m m m m m');
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 SELECT * FROM x2;
  INSERT INTO x2 VALUES('a b c d e f g h i j k l m n o p q r s t u v w x y m');
  COMMIT;
}
do_execsql_test 4.2 {
  SELECT * FROM x2 WHERE x2 MATCH 'a b c d e f g h i j k l m n o p q r s';
} {{a b c d e f g h i j k l m n o p q r s t u v w x y m}}


finish_test