gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/bestindex4.test (about)

     1  # 2016 November 11
     2  #
     3  # The author disclaims copyright to this source code.  In place of
     4  # a legal notice, here is a blessing:
     5  #
     6  #    May you do good and not evil.
     7  #    May you find forgiveness for yourself and forgive others.
     8  #    May you share freely, never taking more than you give.
     9  #
    10  #***********************************************************************
    11  # Test the virtual table interface. In particular the xBestIndex
    12  # method.
    13  #
    14  
    15  set testdir [file dirname $argv0]
    16  source $testdir/tester.tcl
    17  set testprefix bestindex4
    18  
    19  ifcapable !vtab {
    20    finish_test
    21    return
    22  }
    23  
    24  #-------------------------------------------------------------------------
    25  # Virtual table callback for a virtual table named $tbl.
    26  #
    27  # The table created is:
    28  #
    29  #      "CREATE TABLE t1 (id, host, class)"
    30  #
    31  # The virtual table supports == operators on a subset of its columns. The
    32  # exact subset depends on the value of bitmask paramater $param.
    33  #
    34  #   0x01 - == on "id" supported
    35  #   0x02 - == on "host" supported
    36  #   0x04 - == on "class" supported
    37  #
    38  # $param also supports the following bits:
    39  #
    40  #   0x08 - ignore the "usable" flag (malfunction)
    41  #
    42  #
    43  #  
    44  proc vtab_cmd {param method args} {
    45    switch -- $method {
    46      xConnect {
    47        return "CREATE TABLE t1(id TEXT, host TEXT, class TEXT)"
    48      }
    49  
    50      xBestIndex {
    51        set hdl [lindex $args 0]
    52        set clist [$hdl constraints]
    53        set orderby [$hdl orderby]
    54        set mask [$hdl mask]
    55  
    56        set ret [list]
    57  
    58        set use use
    59  
    60  
    61        for {set i 0} {$i < [llength $clist]} {incr i} {
    62          array unset C
    63          array set C [lindex $clist $i]
    64          if { ($C(usable) || ($param & 0x08)) 
    65            && $C(op)=="eq" && ($param & 1<<$C(column))
    66          } {
    67            lappend ret $use $i
    68            break
    69          }
    70        }
    71  
    72        set score 1000000
    73        if {$ret!=""} {
    74          set score [expr $score / [llength $ret]]
    75        }
    76        lappend ret cost $score rows $score
    77  
    78        return $ret
    79      }
    80  
    81      xFilter {
    82      }
    83    }
    84    return ""
    85  }
    86  
    87  register_tcl_module db
    88  
    89  for {set param1 0} {$param1<16} {incr param1} {
    90    for {set param2 0} {$param2<16} {incr param2} {
    91      reset_db
    92      register_tcl_module db
    93      do_execsql_test 1.$param1.$param2.1 "
    94        CREATE VIRTUAL TABLE t1 USING tcl('vtab_cmd $param1');
    95        CREATE VIRTUAL TABLE t2 USING tcl('vtab_cmd $param2');
    96      "
    97  
    98      foreach {tn sql} {
    99        2 "select t1.id as ID from t1, t2 where t1.id=t2.host and t2.class='xx'"
   100        3 {
   101          select t1.id as ID from t1, t2 where t2.class ='xx' and t2.id = t1.host
   102        }
   103        4 {
   104          select t1.id as ID from t1, t2 where t1.host = t2.id and t2. class ='xx'
   105        }
   106      } {
   107  
   108        if {($param1 & 0x08)==0 && ($param2 & 0x08)==0} {
   109  
   110          do_execsql_test 1.$param1.$param2.$tn.a $sql {}
   111  
   112        } else {
   113          do_test 1.$param1.$param2.$tn.b {
   114            catchsql $sql
   115              set {} {}
   116          } {}
   117        }
   118      }
   119  
   120    }
   121  }
   122  
   123  #-------------------------------------------------------------------------
   124  # Test that a parameter passed to a table-valued function cannot be
   125  # used to drive an index. i.e. that in the following:
   126  #
   127  #   SELECT * FROM tbl, vtab(tbl.x);
   128  #
   129  # The implicit constraint "tbl.x = vtab.hidden" is not optimized using
   130  # an index on tbl.x.
   131  #
   132  reset_db
   133  register_tcl_module db
   134  proc vtab_command {method args} {
   135    switch -- $method {
   136      xConnect {
   137        return "CREATE TABLE t1(a, b, c, d HIDDEN)"
   138      }
   139  
   140      xBestIndex {
   141        set hdl [lindex $args 0]
   142        set clist [$hdl constraints]
   143        set orderby [$hdl orderby]
   144        set mask [$hdl mask]
   145        
   146        if {[llength $clist]!=1} { error "unexpected constraint list" }
   147        catch { array unset C }
   148        array set C [lindex $clist 0]
   149        if {$C(usable)} {
   150          return [list omit 0 idxnum 555 rows 10 cost 100]
   151        }
   152        return [list cost 100000000]
   153      }
   154  
   155    }
   156  
   157    return {}
   158  }
   159  
   160  do_execsql_test 2.0 {
   161    CREATE VIRTUAL TABLE x1 USING tcl(vtab_command);
   162    CREATE TABLE t1 (x INT PRIMARY KEY);
   163  } {}
   164  
   165  do_eqp_test 2.1 {
   166    SELECT * FROM t1, x1 WHERE x1.d=t1.x;
   167  } {
   168    QUERY PLAN
   169    |--SCAN x1 VIRTUAL TABLE INDEX 0:
   170    `--SEARCH t1 USING COVERING INDEX sqlite_autoindex_t1_1 (x=?)
   171  }
   172  
   173  do_eqp_test 2.2 {
   174    SELECT * FROM t1, x1(t1.x)
   175  } {
   176    QUERY PLAN
   177    |--SCAN t1
   178    `--SCAN x1 VIRTUAL TABLE INDEX 555:
   179  }
   180  
   181  
   182  finish_test