3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
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.
16 set testdir [file dirname $argv0]
17 source $testdir/tester.tcl
25 register_echo_module db
28 CREATE TABLE t6(a, b TEXT);
29 CREATE INDEX i6 ON t6(b, a);
30 CREATE VIRTUAL TABLE e6 USING echo(t6);
34 foreach {tn sql expect} {
35 1 "SELECT * FROM e6 WHERE b LIKE '8abc'" {
37 {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?}
39 {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?}
43 2 "SELECT * FROM e6 WHERE b GLOB '8abc'" {
45 {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?}
47 {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?}
50 3 "SELECT * FROM e6 WHERE b LIKE '8e/'" {
51 xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?}
52 xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8e/
54 4 "SELECT * FROM e6 WHERE b GLOB '8e/'" {
55 xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?}
56 xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8e/
68 #--------------------------------------------------------------------------
70 register_tclvar_module db
73 CREATE VIRTUAL TABLE vars USING tclvar;
74 SELECT name, arrayname, value FROM vars WHERE name = 'xyz';
87 db func glob -argcount 2 gfunc
93 db func like -argcount 2 lfunc
99 db func regexp -argcount 2 rfunc
105 foreach ::tclvar_set_omit {0 1} {
106 foreach {tn expr res cnt} {
107 1 {value GLOB 'aban*'} {x3 abandon x4 abandonint} 2
108 2 {value LIKE '%ac%'} {x1 aback x7 backbone x8 backarrow} 300
109 3 {value REGEXP '^......$'} {x5 babble x6 baboon x9 castle} 30000
113 if {$::tclvar_set_omit} {set cnt 0}
115 do_test 2.$tclvar_set_omit.$tn.1 {
116 execsql "SELECT name, value FROM vars WHERE name MATCH 'x*' AND $expr"
119 do_test 2.$tclvar_set_omit.$tn.2 {
125 #-------------------------------------------------------------------------
127 if {$tcl_platform(platform)=="windows"} {
128 set drive [string range [pwd] 0 1]
129 set ::env(fstreeDrive) $drive
131 if {$tcl_platform(platform)!="windows" || \
132 [regexp -nocase -- {^[A-Z]:} $drive]} {
134 register_fs_module db
135 do_execsql_test 3.0 {
136 SELECT name FROM fsdir WHERE dir = '.' AND name = 'test.db';
137 SELECT name FROM fsdir WHERE dir = '.' AND name = '.'
140 proc sort_files { names {nocase false} } {
141 if {$nocase && $::tcl_platform(platform) eq "windows"} {
142 return [lsort -nocase $names]
144 return [lsort $names]
148 proc list_root_files {} {
149 if {$::tcl_platform(platform) eq "windows"} {
150 set res [list]; set dir $::env(fstreeDrive)/; set names [list]
151 eval lappend names [glob -nocomplain -directory $dir -- *]
152 foreach name $names {
153 if {[string index [file tail $name] 0] eq "."} continue
154 if {[file attributes $name -hidden]} continue
155 if {[file attributes $name -system]} continue
158 return [sort_files $res true]
160 return [sort_files [string map {/ {}} [glob -nocomplain -- /*]]]
164 proc list_files { pattern } {
165 if {$::tcl_platform(platform) eq "windows"} {
166 set res [list]; set names [list]
167 eval lappend names [glob -nocomplain -- $pattern]
168 foreach name $names {
169 if {[string index [file tail $name] 0] eq "."} continue
170 if {[file attributes $name -hidden]} continue
171 if {[file attributes $name -system]} continue
174 return [sort_files $res]
176 return [sort_files [glob -nocomplain -- $pattern]]
180 # Read the first 5 entries from the root directory. Except, ignore
181 # files that contain the "$" character in their names as these are
182 # special files on some Windows platforms.
185 set root_files [list_root_files]
186 foreach p $root_files {
187 if {$::tcl_platform(platform) eq "windows"} {
188 if {![regexp {\$} $p]} {lappend res $p}
193 set num_root_files [llength $root_files]
195 sort_files [execsql {
196 SELECT path FROM fstree WHERE path NOT GLOB '*\$*' LIMIT $num_root_files;
198 } [sort_files $res true]
200 # Read all entries in the current directory.
202 proc contents {pattern} {
204 foreach f [list_files $pattern] {
206 if {[file isdir $f]} {
207 set res [concat $res [contents "$f/*"]]
213 set res [contents $pwd]
214 do_execsql_test 3.2 {
215 SELECT path FROM fstree WHERE path GLOB $pwd ORDER BY 1
218 # Add some sub-directories and files to the current directory.
221 catch { file delete -force subdir }
226 set dir [file dirname $path]
227 catch { file mkdir $dir }
228 set fd [open $path w]
229 puts -nonewline $fd [string repeat 1 $sz]
235 if {![string match {*[_%]*} $pwd]} {
236 do_execsql_test 3.5 {
237 SELECT path, size FROM fstree
238 WHERE path GLOB $pwd || '/subdir/*' ORDER BY 1
240 "$pwd/subdir/x1.txt" 143 \
241 "$pwd/subdir/x2.txt" 153 \
243 do_execsql_test 3.6 {
244 SELECT path, size FROM fstree
245 WHERE path LIKE $pwd || '/subdir/%' ORDER BY 1
247 "$pwd/subdir/x1.txt" 143 \
248 "$pwd/subdir/x2.txt" 153 \
250 do_execsql_test 3.7 {
251 SELECT sum(size) FROM fstree WHERE path LIKE $pwd || '/subdir/%'
253 do_execsql_test 3.8 {
254 SELECT size FROM fstree WHERE path = $pwd || '/subdir/x1.txt'