/ Check-in [7e0aa964]
Login

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

Overview
Comment:Coverage improvements for where.c. (CVS 3764)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:7e0aa964129612e2bad6fa45139d124f19cacd48
User & Date: danielk1977 2007-03-30 14:56:34
Original User & Date: danielk1977 2007-03-30 14:56:35
Context
2007-03-30
14:56
Coverage improvements for where.c. (CVS 3765) check-in: df64894b user: danielk1977 tags: trunk
14:56
Coverage improvements for where.c. (CVS 3764) check-in: 7e0aa964 user: danielk1977 tags: trunk
14:46
Tease apart the two phases of pager commit. (CVS 3763) check-in: e5f17078 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test8.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the virtual table interfaces.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test8.c,v 1.44 2007/01/03 23:37:29 drh Exp $
           16  +** $Id: test8.c,v 1.45 2007/03/30 14:56:35 danielk1977 Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include "os.h"
    21     21   #include <stdlib.h>
    22     22   #include <string.h>
    23     23   
    24     24   #ifndef SQLITE_OMIT_VIRTUALTABLE
    25     25   
    26     26   typedef struct echo_vtab echo_vtab;
    27     27   typedef struct echo_cursor echo_cursor;
    28     28   
    29     29   /*
    30         -** The test module defined in this file uses two global Tcl variables to
           30  +** The test module defined in this file uses four global Tcl variables to
    31     31   ** commicate with test-scripts:
    32     32   **
    33     33   **     $::echo_module
    34     34   **     $::echo_module_sync_fail
    35     35   **     $::echo_module_begin_fail
           36  +**     $::echo_module_cost
    36     37   **
    37     38   ** The variable ::echo_module is a list. Each time one of the following
    38     39   ** methods is called, one or more elements are appended to the list.
    39     40   ** This is used for automated testing of virtual table modules.
    40     41   **
    41     42   ** The ::echo_module_sync_fail variable is set by test scripts and read
    42     43   ** by code in this file. If it is set to the name of a real table in the
................................................................................
   623    624     int ii;
   624    625     char *zQuery = 0;
   625    626     char *zNew;
   626    627     int nArg = 0;
   627    628     const char *zSep = "WHERE";
   628    629     echo_vtab *pVtab = (echo_vtab *)tab;
   629    630     sqlite3_stmt *pStmt = 0;
          631  +  Tcl_Interp *interp = pVtab->interp;
   630    632   
   631    633     int nRow;
   632    634     int useIdx = 0;
   633    635     int rc = SQLITE_OK;
          636  +  int useCost = 0;
          637  +  double cost;
   634    638   
   635    639     /* Determine the number of rows in the table and store this value in local
   636    640     ** variable nRow. The 'estimated-cost' of the scan will be the number of
   637    641     ** rows in the table for a linear scan, or the log (base 2) of the 
   638    642     ** number of rows if the proposed scan uses an index.  
   639    643     */
   640         -  zQuery = sqlite3_mprintf("SELECT count(*) FROM %Q", pVtab->zTableName);
   641         -  rc = sqlite3_prepare(pVtab->db, zQuery, -1, &pStmt, 0);
   642         -  sqlite3_free(zQuery);
   643         -  if( rc!=SQLITE_OK ){
   644         -    return rc;
   645         -  }
   646         -  sqlite3_step(pStmt);
   647         -  nRow = sqlite3_column_int(pStmt, 0);
   648         -  rc = sqlite3_finalize(pStmt);
   649         -  if( rc!=SQLITE_OK ){
   650         -    return rc;
          644  +  if( Tcl_GetVar(interp, "echo_module_cost", TCL_GLOBAL_ONLY) ){
          645  +    cost = atof(Tcl_GetVar(interp, "echo_module_cost", TCL_GLOBAL_ONLY));
          646  +    useCost = 1;
          647  +  } else {
          648  +    zQuery = sqlite3_mprintf("SELECT count(*) FROM %Q", pVtab->zTableName);
          649  +    rc = sqlite3_prepare(pVtab->db, zQuery, -1, &pStmt, 0);
          650  +    sqlite3_free(zQuery);
          651  +    if( rc!=SQLITE_OK ){
          652  +      return rc;
          653  +    }
          654  +    sqlite3_step(pStmt);
          655  +    nRow = sqlite3_column_int(pStmt, 0);
          656  +    rc = sqlite3_finalize(pStmt);
          657  +    if( rc!=SQLITE_OK ){
          658  +      return rc;
          659  +    }
   651    660     }
   652    661   
   653    662     zQuery = sqlite3_mprintf("SELECT rowid, * FROM %Q", pVtab->zTableName);
   654    663     for(ii=0; ii<pIdxInfo->nConstraint; ii++){
   655    664       const struct sqlite3_index_constraint *pConstraint;
   656    665       struct sqlite3_index_constraint_usage *pUsage;
   657    666       int iCol;
................................................................................
   713    722   
   714    723     appendToEchoModule(pVtab->interp, "xBestIndex");;
   715    724     appendToEchoModule(pVtab->interp, zQuery);
   716    725   
   717    726     pIdxInfo->idxNum = hashString(zQuery);
   718    727     pIdxInfo->idxStr = zQuery;
   719    728     pIdxInfo->needToFreeIdxStr = 1;
   720         -  if( useIdx ){
          729  +  if (useCost) {
          730  +    pIdxInfo->estimatedCost = cost;
          731  +  } else if( useIdx ){
   721    732       /* Approximation of log2(nRow). */
   722    733       for( ii=0; ii<(sizeof(int)*8); ii++ ){
   723    734         if( nRow & (1<<ii) ){
   724    735           pIdxInfo->estimatedCost = (double)ii;
   725    736         }
   726    737       }
   727    738     } else {

Changes to src/where.c.

    12     12   ** This module contains C code that generates VDBE code used to process
    13     13   ** the WHERE clause of SQL statements.  This module is reponsible for
    14     14   ** generating the code that loops through a table looking for applicable
    15     15   ** rows.  Indices are selected and used to speed the search when doing
    16     16   ** so is applicable.  Because this module is responsible for selecting
    17     17   ** indices, you might also think of this module as the "query optimizer".
    18     18   **
    19         -** $Id: where.c,v 1.243 2007/03/30 09:13:14 danielk1977 Exp $
           19  +** $Id: where.c,v 1.244 2007/03/30 14:56:35 danielk1977 Exp $
    20     20   */
    21     21   #include "sqliteInt.h"
    22     22   
    23     23   /*
    24     24   ** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
    25     25   */
    26     26   #define BMS  (sizeof(Bitmask)*8)
................................................................................
  1828   1828   static void whereInfoFree(WhereInfo *pWInfo){
  1829   1829     if( pWInfo ){
  1830   1830       int i;
  1831   1831       for(i=0; i<pWInfo->nLevel; i++){
  1832   1832         sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo;
  1833   1833         if( pInfo ){
  1834   1834           if( pInfo->needToFreeIdxStr ){
         1835  +          /* Coverage: Don't think this can be reached. By the time this
         1836  +          ** function is called, the index-strings have been passed
         1837  +          ** to the vdbe layer for deletion.
         1838  +          */
  1835   1839             sqlite3_free(pInfo->idxStr);
  1836   1840           }
  1837   1841           sqliteFree(pInfo);
  1838   1842         }
  1839   1843       }
  1840   1844       sqliteFree(pWInfo);
  1841   1845     }

Changes to test/misc7.test.

     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   #
    13         -# $Id: misc7.test,v 1.5 2007/03/30 13:01:32 drh Exp $
           13  +# $Id: misc7.test,v 1.6 2007/03/30 14:56:35 danielk1977 Exp $
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   
    18     18   do_test misc7-1 {
    19     19     c_misuse_test
    20     20   } {}
................................................................................
   160    160       SELECT * 
   161    161       FROM (SELECT name+1 AS one FROM sqlite_master LIMIT 1 OFFSET 1) 
   162    162       WHERE one LIKE 'hello%';
   163    163     }
   164    164   } {}
   165    165   
   166    166   #--------------------------------------------------------------------
   167         -# Improve reported coverage by running some debugging code:
          167  +# Improve coverage for vtab code.
   168    168   #
   169    169   ifcapable vtab {
          170  +  # Run some debug code to improve reported coverage
          171  +  #
          172  +
          173  +  # set sqlite_where_trace 1
   170    174     do_test misc7-10 {
   171    175       register_echo_module [sqlite3_connection_pointer db]
   172    176       execsql {
   173    177         CREATE VIRTUAL TABLE t1 USING echo(abc);
   174    178         SELECT a FROM t1 WHERE a = 1 ORDER BY b;
   175    179       }
   176    180     } {1}
          181  +  set sqlite_where_trace 0
          182  +
          183  +  # Specify an ORDER BY clause that cannot be indexed.
          184  +  do_test misc7-11 {
          185  +    execsql {
          186  +      SELECT t1.a, t2.a FROM t1, t1 AS t2 ORDER BY 2 LIMIT 1;
          187  +    }
          188  +  } {1 1}
          189  +
          190  +  # The whole point of this is to test an error code other than
          191  +  # SQLITE_NOMEM from the vtab xBestIndex callback.
          192  +  #
          193  +  do_ioerr_test misc7-12 -tclprep {
          194  +    sqlite3 db2 test.db
          195  +    register_echo_module [sqlite3_connection_pointer db2]
          196  +    db2 eval {
          197  +      CREATE TABLE abc(a PRIMARY KEY, b, c);
          198  +      INSERT INTO abc VALUES(1, 2, 3);
          199  +      CREATE VIRTUAL TABLE t1 USING echo(abc);
          200  +    }
          201  +    db2 close
          202  +  } -tclbody {
          203  +    register_echo_module [sqlite3_connection_pointer db]
          204  +    execsql {SELECT * FROM t1 WHERE a = 1;}
          205  +  } 
          206  +
          207  +  # The case where the virtual table module returns a very large number
          208  +  # as the cost of a scan (greater than SQLITE_BIG_DOUBLE in the code).
          209  +  #
          210  +  do_test misc7-13 {
          211  +    sqlite3 db test.db
          212  +    register_echo_module [sqlite3_connection_pointer db]
          213  +    set ::echo_module_cost 2.0e+99
          214  +    execsql {SELECT * FROM t1 WHERE a = 1;}
          215  +  } {1 2 3}
          216  +  unset ::echo_module_cost
   177    217   }
          218  +
   178    219   
   179    220   finish_test

Changes to test/vtab1.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is creating and dropping virtual tables.
    13     13   #
    14         -# $Id: vtab1.test,v 1.41 2007/03/02 08:12:23 danielk1977 Exp $
           14  +# $Id: vtab1.test,v 1.42 2007/03/30 14:56:35 danielk1977 Exp $
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19     19   ifcapable !vtab||!schema_pragmas {
    20     20     finish_test
    21     21     return
................................................................................
   553    553       CREATE INDEX i1 ON t2(d);
   554    554     }
   555    555   
   556    556     db close
   557    557     sqlite3 db test.db
   558    558     register_echo_module [sqlite3_connection_pointer db]
   559    559   
   560         -  set echo_module ""
          560  +  set ::echo_module ""
   561    561     execsql {
   562    562       SELECT * FROM et1, et2 WHERE et2.d = 2;
   563    563     }
   564    564   } [list \
   565    565     1 red green 2 hearts diamonds  \
   566    566     2 blue black 2 hearts diamonds \
   567    567   ]
   568    568   do_test vtab1-5-7 {
   569         -  filter $echo_module
          569  +  filter $::echo_module
   570    570   } [list \
   571    571     xFilter {SELECT rowid, * FROM 't2' WHERE d = ?} \
   572    572     xFilter {SELECT rowid, * FROM 't1'}             \
   573    573   ]
   574    574   
   575    575   execsql {
   576    576     DROP TABLE t1;