/ Check-in [a0ca4ddb]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Fix the fts5 xBestIndex method so that it is not confused by "IS", "!=", "REGEXP", "GLOB" or "LIKE" operators. Fix for ticket [2b8aed9f].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a0ca4ddbbf179b8f0a5f30c127f2f8c92b6d45a08be3e1ef2194e44ebcc28120
User & Date: dan 2018-04-09 14:26:44
Original Comment: Fix the fts5 xBestIndex method so that it is not confused by "IS", "!=", "REGEXP", "GLOB" or "LIKE" operators.
Context
2018-04-09
15:57
Enhance the query planner so that it detects when the xBestIndex method of a virtual table gives out-of-sequence argvIndex values and reports an error. Secondary fix for ticket [2b8aed9f7c9e6]. check-in: 9506ec14 user: drh tags: trunk
14:26
Fix the fts5 xBestIndex method so that it is not confused by "IS", "!=", "REGEXP", "GLOB" or "LIKE" operators. Fix for ticket [2b8aed9f]. check-in: a0ca4ddb user: dan tags: trunk
13:58
Improvements to ".wheretrace" output. check-in: ea2e5b34 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/fts5/fts5_main.c.

530
531
532
533
534
535
536






537
538
539
540
541
542
543
...
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
                                    FTS5_BI_ROWID_GE, 0, 0, -1},
  };

  int aColMap[3];
  aColMap[0] = -1;
  aColMap[1] = nCol;
  aColMap[2] = nCol+1;







  /* Set idxFlags flags for all WHERE clause terms that will be used. */
  for(i=0; i<pInfo->nConstraint; i++){
    struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
    int iCol = p->iColumn;

    if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
................................................................................
        aConstraint[0].iConsIndex = i;
      }else{
        /* As there exists an unusable MATCH constraint this is an 
        ** unusable plan. Set a prohibitively high cost. */
        pInfo->estimatedCost = 1e50;
        return SQLITE_OK;
      }
    }else{
      int j;
      for(j=1; j<ArraySize(aConstraint); j++){
        struct Constraint *pC = &aConstraint[j];
        if( iCol==aColMap[pC->iCol] && p->op & pC->op && p->usable ){
          pC->iConsIndex = i;
          idxFlags |= pC->fts5op;
        }
      }
    }
  }








>
>
>
>
>
>







 







|



|







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
...
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
                                    FTS5_BI_ROWID_GE, 0, 0, -1},
  };

  int aColMap[3];
  aColMap[0] = -1;
  aColMap[1] = nCol;
  aColMap[2] = nCol+1;

  assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH );
  assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH );
  assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );
  assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH );
  assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );

  /* Set idxFlags flags for all WHERE clause terms that will be used. */
  for(i=0; i<pInfo->nConstraint; i++){
    struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
    int iCol = p->iColumn;

    if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
................................................................................
        aConstraint[0].iConsIndex = i;
      }else{
        /* As there exists an unusable MATCH constraint this is an 
        ** unusable plan. Set a prohibitively high cost. */
        pInfo->estimatedCost = 1e50;
        return SQLITE_OK;
      }
    }else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){
      int j;
      for(j=1; j<ArraySize(aConstraint); j++){
        struct Constraint *pC = &aConstraint[j];
        if( iCol==aColMap[pC->iCol] && (p->op & pC->op) && p->usable ){
          pC->iConsIndex = i;
          idxFlags |= pC->fts5op;
        }
      }
    }
  }

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

586
587
588
589
590
591
592












593
594
595
596
597
    INSERT INTO t9(rowid, x) VALUES(3, 'bbb');
  COMMIT;
}

do_execsql_test 22.1 {
  SELECT rowid FROM t9('a*')
} {1}













}

expand_all_sql db
finish_test







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





586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
    INSERT INTO t9(rowid, x) VALUES(3, 'bbb');
  COMMIT;
}

do_execsql_test 22.1 {
  SELECT rowid FROM t9('a*')
} {1}

#-------------------------------------------------------------------------
do_execsql_test 23.0 {
  CREATE VIRTUAL TABLE t10 USING fts5(x, detail=%DETAIL%);
  CREATE TABLE t11(x);
}
do_execsql_test 23.1 {
  SELECT * FROM t11, t10 WHERE t11.x = t10.x AND t10.rowid IS NULL;
}
do_execsql_test 23.2 {
  SELECT * FROM t11, t10 WHERE t10.rowid IS NULL;
}

}

expand_all_sql db
finish_test