xref: /sqlite-3.40.0/test/vtabH.test (revision 7aa3ebee)
1# 2015 Nov 24
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# This file implements regression tests for SQLite library. Specifically,
12# it tests that the GLOB, LIKE and REGEXP operators are correctly exposed
13# to virtual table implementations.
14#
15
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
18set testprefix vtabH
19
20ifcapable !vtab {
21  finish_test
22  return
23}
24
25register_echo_module db
26
27do_execsql_test 1.0 {
28  CREATE TABLE t6(a, b TEXT);
29  CREATE INDEX i6 ON t6(b, a);
30  CREATE VIRTUAL TABLE e6 USING echo(t6);
31}
32
33foreach {tn sql expect} {
34  1 "SELECT * FROM e6 WHERE b LIKE 'abc'" {
35    xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?}
36    xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} abc
37  }
38
39  2 "SELECT * FROM e6 WHERE b GLOB 'abc'" {
40    xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?}
41    xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} abc
42  }
43} {
44  do_test 1.$tn {
45    set echo_module {}
46    execsql $sql
47    set ::echo_module
48  } [list {*}$expect]
49}
50
51
52#--------------------------------------------------------------------------
53
54register_tclvar_module db
55set ::xyz 10
56do_execsql_test 2.0 {
57  CREATE VIRTUAL TABLE vars USING tclvar;
58  SELECT * FROM vars WHERE name = 'xyz';
59} {xyz {} 10}
60
61set x1 aback
62set x2 abaft
63set x3 abandon
64set x4 abandonint
65set x5 babble
66set x6 baboon
67set x7 backbone
68set x8 backarrow
69set x9 castle
70
71db func glob -argcount 2 gfunc
72proc gfunc {a b} {
73  incr ::gfunc
74  return 1
75}
76
77db func like -argcount 2 lfunc
78proc lfunc {a b} {
79  incr ::gfunc 100
80  return 1
81}
82
83db func regexp -argcount 2 rfunc
84proc rfunc {a b} {
85  incr ::gfunc 10000
86  return 1
87}
88
89foreach ::tclvar_set_omit {0 1} {
90  foreach {tn expr res cnt} {
91    1 {value GLOB 'aban*'} {x3 abandon x4 abandonint} 2
92    2 {value LIKE '%ac%'}  {x1 aback x7 backbone x8 backarrow} 300
93    3 {value REGEXP '^......$'}  {x5 babble x6 baboon x9 castle} 30000
94  } {
95    db cache flush
96    set ::gfunc 0
97    if {$::tclvar_set_omit} {set cnt 0}
98
99    do_test 2.$tclvar_set_omit.$tn.1 {
100      execsql "SELECT name, value FROM vars WHERE name MATCH 'x*' AND $expr"
101    } $res
102
103    do_test 2.$tclvar_set_omit.$tn.2 {
104      set ::gfunc
105    } $cnt
106  }
107}
108
109#-------------------------------------------------------------------------
110#
111if {1} {
112  reset_db
113  register_fs_module db
114  do_execsql_test 3.0 {
115    SELECT name FROM fsdir WHERE dir = '.' AND name = 'test.db';
116    SELECT name FROM fsdir WHERE dir = '.' AND name = '.'
117  } {test.db .}
118
119  proc list_root_files {} {
120    if {$::tcl_platform(platform) eq "windows"} {
121      set res [list]
122      foreach name [glob -directory $::env(SystemDrive)/ -- *] {
123        if {[string index [file tail $name] 0] eq "."} continue
124        lappend res $name
125      }
126      return $res
127    } else {
128      return [string map {/ {}} [glob /*]]
129    }
130  }
131
132  proc list_files { pattern } {
133    if {$::tcl_platform(platform) eq "windows"} {
134      set res [list]
135      foreach name [glob -nocomplain $pattern] {
136        if {[string index [file tail $name] 0] eq "."} continue
137        lappend res $name
138      }
139      return $res
140    } else {
141      return [glob -nocomplain $pattern]
142    }
143  }
144
145  # Read all entries in the current directory.
146  #
147  proc contents {pattern} {
148    set res [list]
149    foreach f [list_files $pattern] {
150      lappend res $f
151      if {[file isdir $f]} {
152        set res [concat $res [contents "$f/*"]]
153      }
154    }
155    set res
156  }
157  set pwd "[pwd]/*"
158  set res [contents $pwd]
159  do_execsql_test 3.2 {
160    SELECT path FROM fstree WHERE path GLOB $pwd ORDER BY 1
161  } [lsort $res]
162
163  # Add some sub-directories and files to the current directory.
164  #
165  do_test 3.3 {
166    catch { file delete -force subdir }
167    foreach {path sz} {
168      subdir/x1.txt     143
169      subdir/x2.txt     153
170    } {
171      set dir [file dirname $path]
172      catch { file mkdir $dir }
173      set fd [open $path w]
174      puts -nonewline $fd [string repeat 1 $sz]
175      close $fd
176    }
177  } {}
178
179  set pwd [pwd]
180  do_execsql_test 3.5 {
181    SELECT path, size FROM fstree WHERE path GLOB $pwd || '/subdir/*' ORDER BY 1
182  } [list \
183    "$pwd/subdir/x1.txt" 143 \
184    "$pwd/subdir/x2.txt" 153 \
185  ]
186  do_execsql_test 3.6 {
187    SELECT path, size FROM fstree WHERE path LIKE $pwd || '/subdir/%' ORDER BY 1
188  } [list \
189    "$pwd/subdir/x1.txt" 143 \
190    "$pwd/subdir/x2.txt" 153 \
191  ]
192  do_execsql_test 3.7 {
193    SELECT sum(size) FROM fstree WHERE path LIKE $pwd || '/subdir/%'
194  } 296
195  do_execsql_test 3.8 {
196    SELECT size FROM fstree WHERE path = $pwd || '/subdir/x1.txt'
197  } 143
198
199}
200
201
202finish_test
203