xref: /sqlite-3.40.0/test/vtabH.test (revision 7c2321fd)
107bdba86Sdan# 2015 Nov 24
207bdba86Sdan#
307bdba86Sdan# The author disclaims copyright to this source code.  In place of
407bdba86Sdan# a legal notice, here is a blessing:
507bdba86Sdan#
607bdba86Sdan#    May you do good and not evil.
707bdba86Sdan#    May you find forgiveness for yourself and forgive others.
807bdba86Sdan#    May you share freely, never taking more than you give.
907bdba86Sdan#
1007bdba86Sdan#***********************************************************************
1143970dd7Sdan# This file implements regression tests for SQLite library. Specifically,
1243970dd7Sdan# it tests that the GLOB, LIKE and REGEXP operators are correctly exposed
1343970dd7Sdan# to virtual table implementations.
1407bdba86Sdan#
1507bdba86Sdan
1607bdba86Sdanset testdir [file dirname $argv0]
1707bdba86Sdansource $testdir/tester.tcl
1807bdba86Sdanset testprefix vtabH
1907bdba86Sdan
2007bdba86Sdanifcapable !vtab {
2107bdba86Sdan  finish_test
2207bdba86Sdan  return
2307bdba86Sdan}
2407bdba86Sdan
2507bdba86Sdanregister_echo_module db
2607bdba86Sdan
2707bdba86Sdando_execsql_test 1.0 {
2807bdba86Sdan  CREATE TABLE t6(a, b TEXT);
2907bdba86Sdan  CREATE INDEX i6 ON t6(b, a);
3007bdba86Sdan  CREATE VIRTUAL TABLE e6 USING echo(t6);
3107bdba86Sdan}
3207bdba86Sdan
33*7c2321fdSdanifcapable !icu {
3407bdba86Sdan  foreach {tn sql expect} {
351c84bd47Sdrh    1 "SELECT * FROM e6 WHERE b LIKE '8abc'" {
36060b7fa9Sdrh      xBestIndex
37060b7fa9Sdrh         {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?}
38060b7fa9Sdrh      xFilter
39060b7fa9Sdrh         {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?}
40060b7fa9Sdrh         8ABC 8abd 8abc
4107bdba86Sdan    }
4207bdba86Sdan
431c84bd47Sdrh    2 "SELECT * FROM e6 WHERE b GLOB '8abc'" {
44060b7fa9Sdrh       xBestIndex
45060b7fa9Sdrh         {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?}
46060b7fa9Sdrh       xFilter
47060b7fa9Sdrh         {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?}
48060b7fa9Sdrh         8abc 8abd 8abc
49060b7fa9Sdrh    }
50060b7fa9Sdrh    3 "SELECT * FROM e6 WHERE b LIKE '8e/'" {
51060b7fa9Sdrh      xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?}
52060b7fa9Sdrh      xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8e/
53060b7fa9Sdrh    }
54060b7fa9Sdrh    4 "SELECT * FROM e6 WHERE b GLOB '8e/'" {
551acb539fSdan      xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?}
56060b7fa9Sdrh      xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8e/
5707bdba86Sdan    }
5807bdba86Sdan  } {
5907bdba86Sdan    do_test 1.$tn {
6007bdba86Sdan      set echo_module {}
6107bdba86Sdan      execsql $sql
6207bdba86Sdan      set ::echo_module
6307bdba86Sdan    } [list {*}$expect]
6407bdba86Sdan  }
65*7c2321fdSdan}
6607bdba86Sdan
6743970dd7Sdan
6843970dd7Sdan#--------------------------------------------------------------------------
6943970dd7Sdan
7043970dd7Sdanregister_tclvar_module db
7143970dd7Sdanset ::xyz 10
7243970dd7Sdando_execsql_test 2.0 {
7343970dd7Sdan  CREATE VIRTUAL TABLE vars USING tclvar;
744dd176eaSdrh  SELECT name, arrayname, value FROM vars WHERE name = 'xyz';
7543970dd7Sdan} {xyz {} 10}
7643970dd7Sdan
7743970dd7Sdanset x1 aback
7843970dd7Sdanset x2 abaft
7943970dd7Sdanset x3 abandon
8043970dd7Sdanset x4 abandonint
8143970dd7Sdanset x5 babble
8243970dd7Sdanset x6 baboon
8343970dd7Sdanset x7 backbone
8443970dd7Sdanset x8 backarrow
8543970dd7Sdanset x9 castle
8643970dd7Sdan
8733d09da1Sdandb func glob -argcount 2 gfunc
8843970dd7Sdanproc gfunc {a b} {
8943970dd7Sdan  incr ::gfunc
9043970dd7Sdan  return 1
9143970dd7Sdan}
9243970dd7Sdan
9333d09da1Sdandb func like -argcount 2 lfunc
9443970dd7Sdanproc lfunc {a b} {
9543970dd7Sdan  incr ::gfunc 100
9643970dd7Sdan  return 1
9743970dd7Sdan}
9843970dd7Sdan
9933d09da1Sdandb func regexp -argcount 2 rfunc
10043970dd7Sdanproc rfunc {a b} {
10143970dd7Sdan  incr ::gfunc 10000
10243970dd7Sdan  return 1
10343970dd7Sdan}
10443970dd7Sdan
10543970dd7Sdanforeach ::tclvar_set_omit {0 1} {
10643970dd7Sdan  foreach {tn expr res cnt} {
10743970dd7Sdan    1 {value GLOB 'aban*'} {x3 abandon x4 abandonint} 2
10843970dd7Sdan    2 {value LIKE '%ac%'}  {x1 aback x7 backbone x8 backarrow} 300
10943970dd7Sdan    3 {value REGEXP '^......$'}  {x5 babble x6 baboon x9 castle} 30000
11043970dd7Sdan  } {
11143970dd7Sdan    db cache flush
11243970dd7Sdan    set ::gfunc 0
11343970dd7Sdan    if {$::tclvar_set_omit} {set cnt 0}
11443970dd7Sdan
11543970dd7Sdan    do_test 2.$tclvar_set_omit.$tn.1 {
11643970dd7Sdan      execsql "SELECT name, value FROM vars WHERE name MATCH 'x*' AND $expr"
11743970dd7Sdan    } $res
11843970dd7Sdan
11943970dd7Sdan    do_test 2.$tclvar_set_omit.$tn.2 {
12043970dd7Sdan      set ::gfunc
12143970dd7Sdan    } $cnt
12243970dd7Sdan  }
12343970dd7Sdan}
12443970dd7Sdan
1251e93173fSdan#-------------------------------------------------------------------------
1261e93173fSdan#
1277dd7d98bSmistachkinif {$tcl_platform(platform)=="windows"} {
1287dd7d98bSmistachkin  set drive [string range [pwd] 0 1]
1297dd7d98bSmistachkin  set ::env(fstreeDrive) $drive
1307dd7d98bSmistachkin}
1317dd7d98bSmistachkinif {$tcl_platform(platform)!="windows" || \
1327dd7d98bSmistachkin    [regexp -nocase -- {^[A-Z]:} $drive]} {
1331e93173fSdan  reset_db
1341e93173fSdan  register_fs_module db
1351e93173fSdan  do_execsql_test 3.0 {
1361e93173fSdan    SELECT name FROM fsdir WHERE dir = '.' AND name = 'test.db';
1371e93173fSdan    SELECT name FROM fsdir WHERE dir = '.' AND name = '.'
1381e93173fSdan  } {test.db .}
1391e93173fSdan
1407059138aSmistachkin  proc sort_files { names {nocase false} } {
1417059138aSmistachkin    if {$nocase && $::tcl_platform(platform) eq "windows"} {
142d3e73d6cSmistachkin      return [lsort -nocase $names]
1437059138aSmistachkin    } else {
1447059138aSmistachkin      return [lsort $names]
1457059138aSmistachkin    }
1467059138aSmistachkin  }
1477059138aSmistachkin
14892af1ebcSmistachkin  proc list_root_files {} {
14992af1ebcSmistachkin    if {$::tcl_platform(platform) eq "windows"} {
1507059138aSmistachkin      set res [list]; set dir $::env(fstreeDrive)/; set names [list]
1517059138aSmistachkin      eval lappend names [glob -nocomplain -directory $dir -- *]
1527059138aSmistachkin      foreach name $names {
15392af1ebcSmistachkin        if {[string index [file tail $name] 0] eq "."} continue
1547059138aSmistachkin        if {[file attributes $name -hidden]} continue
1557059138aSmistachkin        if {[file attributes $name -system]} continue
15692af1ebcSmistachkin        lappend res $name
15792af1ebcSmistachkin      }
1587059138aSmistachkin      return [sort_files $res true]
15992af1ebcSmistachkin    } else {
1607059138aSmistachkin      return [sort_files [string map {/ {}} [glob -nocomplain -- /*]]]
16192af1ebcSmistachkin    }
16292af1ebcSmistachkin  }
16392af1ebcSmistachkin
16492af1ebcSmistachkin  proc list_files { pattern } {
16592af1ebcSmistachkin    if {$::tcl_platform(platform) eq "windows"} {
1667059138aSmistachkin      set res [list]; set names [list]
1677059138aSmistachkin      eval lappend names [glob -nocomplain -- $pattern]
1687059138aSmistachkin      foreach name $names {
16992af1ebcSmistachkin        if {[string index [file tail $name] 0] eq "."} continue
1707059138aSmistachkin        if {[file attributes $name -hidden]} continue
1717059138aSmistachkin        if {[file attributes $name -system]} continue
17292af1ebcSmistachkin        lappend res $name
17392af1ebcSmistachkin      }
1747059138aSmistachkin      return [sort_files $res]
17592af1ebcSmistachkin    } else {
1767059138aSmistachkin      return [sort_files [glob -nocomplain -- $pattern]]
17792af1ebcSmistachkin    }
17892af1ebcSmistachkin  }
17992af1ebcSmistachkin
1807dd7d98bSmistachkin  # Read the first 5 entries from the root directory.  Except, ignore
1817dd7d98bSmistachkin  # files that contain the "$" character in their names as these are
1827dd7d98bSmistachkin  # special files on some Windows platforms.
1837dd7d98bSmistachkin  #
1847dd7d98bSmistachkin  set res [list]
1850a9428d0Smistachkin  set root_files [list_root_files]
1867059138aSmistachkin  foreach p $root_files {
1877dd7d98bSmistachkin    if {$::tcl_platform(platform) eq "windows"} {
1887059138aSmistachkin      if {![regexp {\$} $p]} {lappend res $p}
1897dd7d98bSmistachkin    } else {
1907dd7d98bSmistachkin      lappend res "/$p"
1917dd7d98bSmistachkin    }
1927dd7d98bSmistachkin  }
1937059138aSmistachkin  set num_root_files [llength $root_files]
1947059138aSmistachkin  do_test 3.1 {
1957059138aSmistachkin    sort_files [execsql {
1967059138aSmistachkin      SELECT path FROM fstree WHERE path NOT GLOB '*\$*' LIMIT $num_root_files;
1977059138aSmistachkin    }] true
1987059138aSmistachkin  } [sort_files $res true]
1997dd7d98bSmistachkin
2001e93173fSdan  # Read all entries in the current directory.
2011e93173fSdan  #
2021e93173fSdan  proc contents {pattern} {
2031e93173fSdan    set res [list]
20492af1ebcSmistachkin    foreach f [list_files $pattern] {
2051e93173fSdan      lappend res $f
2061e93173fSdan      if {[file isdir $f]} {
2071e93173fSdan        set res [concat $res [contents "$f/*"]]
2081e93173fSdan      }
2091e93173fSdan    }
2101e93173fSdan    set res
2111e93173fSdan  }
2121e93173fSdan  set pwd "[pwd]/*"
2131e93173fSdan  set res [contents $pwd]
2141e93173fSdan  do_execsql_test 3.2 {
2151e93173fSdan    SELECT path FROM fstree WHERE path GLOB $pwd ORDER BY 1
2167059138aSmistachkin  } [sort_files $res]
2171e93173fSdan
2181e93173fSdan  # Add some sub-directories and files to the current directory.
2191e93173fSdan  #
2201e93173fSdan  do_test 3.3 {
2211e93173fSdan    catch { file delete -force subdir }
2221e93173fSdan    foreach {path sz} {
2231e93173fSdan      subdir/x1.txt     143
2241e93173fSdan      subdir/x2.txt     153
2251e93173fSdan    } {
2261e93173fSdan      set dir [file dirname $path]
2271e93173fSdan      catch { file mkdir $dir }
2281e93173fSdan      set fd [open $path w]
2291e93173fSdan      puts -nonewline $fd [string repeat 1 $sz]
2301e93173fSdan      close $fd
2311e93173fSdan    }
2321e93173fSdan  } {}
2331e93173fSdan
2341e93173fSdan  set pwd [pwd]
2353b77506bSdrh  if {![string match {*[_%]*} $pwd]} {
2361e93173fSdan    do_execsql_test 3.5 {
2373b77506bSdrh      SELECT path, size FROM fstree
2383b77506bSdrh       WHERE path GLOB $pwd || '/subdir/*' ORDER BY 1
2391e93173fSdan    } [list \
2401e93173fSdan      "$pwd/subdir/x1.txt" 143 \
2411e93173fSdan      "$pwd/subdir/x2.txt" 153 \
2421e93173fSdan    ]
2431e93173fSdan    do_execsql_test 3.6 {
2443b77506bSdrh      SELECT path, size FROM fstree
2453b77506bSdrh       WHERE path LIKE $pwd || '/subdir/%' ORDER BY 1
2461e93173fSdan    } [list \
2471e93173fSdan      "$pwd/subdir/x1.txt" 143 \
2481e93173fSdan      "$pwd/subdir/x2.txt" 153 \
2491e93173fSdan    ]
2501e93173fSdan    do_execsql_test 3.7 {
2511e93173fSdan      SELECT sum(size) FROM fstree WHERE path LIKE $pwd || '/subdir/%'
2521e93173fSdan    } 296
2531e93173fSdan    do_execsql_test 3.8 {
2541e93173fSdan      SELECT size FROM fstree WHERE path = $pwd || '/subdir/x1.txt'
2551e93173fSdan    } 143
2563b77506bSdrh  }
2571e93173fSdan
2581e93173fSdan}
2591e93173fSdan
2601e93173fSdan
26107bdba86Sdanfinish_test
262