Add the SQLITE_FCNTL_WIN32_GET_HANDLE file control.
[sqlite.git] / test / vtabH.test
blobf2a116f350fbe581807481cbf8799b8b97b15130
1 # 2015 Nov 24
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
18 set testprefix vtabH
20 ifcapable !vtab {
21   finish_test
22   return
25 register_echo_module db
27 do_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);
33 foreach {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   }
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]
52 #--------------------------------------------------------------------------
54 register_tclvar_module db
55 set ::xyz 10
56 do_execsql_test 2.0 {
57   CREATE VIRTUAL TABLE vars USING tclvar;
58   SELECT * FROM vars WHERE name = 'xyz';
59 } {xyz {} 10}
61 set x1 aback
62 set x2 abaft
63 set x3 abandon
64 set x4 abandonint
65 set x5 babble
66 set x6 baboon
67 set x7 backbone
68 set x8 backarrow
69 set x9 castle
71 db func glob -argcount 2 gfunc
72 proc gfunc {a b} {
73   incr ::gfunc
74   return 1
77 db func like -argcount 2 lfunc
78 proc lfunc {a b} {
79   incr ::gfunc 100
80   return 1
83 db func regexp -argcount 2 rfunc
84 proc rfunc {a b} {
85   incr ::gfunc 10000
86   return 1
89 foreach ::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}
99     do_test 2.$tclvar_set_omit.$tn.1 {
100       execsql "SELECT name, value FROM vars WHERE name MATCH 'x*' AND $expr"
101     } $res
103     do_test 2.$tclvar_set_omit.$tn.2 {
104       set ::gfunc
105     } $cnt
106   }
109 #-------------------------------------------------------------------------
111 if {$tcl_platform(platform)=="windows"} {
112   set drive [string range [pwd] 0 1]
113   set ::env(fstreeDrive) $drive
115 if {$tcl_platform(platform)!="windows" || \
116     [regexp -nocase -- {^[A-Z]:} $drive]} {
117   reset_db
118   register_fs_module db
119   do_execsql_test 3.0 {
120     SELECT name FROM fsdir WHERE dir = '.' AND name = 'test.db';
121     SELECT name FROM fsdir WHERE dir = '.' AND name = '.'
122   } {test.db .}
124   proc list_root_files {} {
125     if {$::tcl_platform(platform) eq "windows"} {
126       set res [list]
127       foreach name [glob -directory $::env(fstreeDrive)/ -- *] {
128         if {[string index [file tail $name] 0] eq "."} continue
129         lappend res $name
130       }
131       return $res
132     } else {
133       return [string map {/ {}} [glob /*]]
134     }
135   }
137   proc list_files { pattern } {
138     if {$::tcl_platform(platform) eq "windows"} {
139       set res [list]
140       foreach name [glob -nocomplain $pattern] {
141         if {[string index [file tail $name] 0] eq "."} continue
142         lappend res $name
143       }
144       return $res
145     } else {
146       return [glob -nocomplain $pattern]
147     }
148   }
150   # Read the first 5 entries from the root directory.  Except, ignore
151   # files that contain the "$" character in their names as these are
152   # special files on some Windows platforms.
153   #
154   set res [list]
155   set root_files [list_root_files]
156   set num_root_files [llength $root_files]
157   set lim_root_files [expr {$num_root_files > 5 ? 5 : $num_root_files}]
158   foreach p [lrange $root_files 0 [expr {$lim_root_files - 1}]] {
159     if {$::tcl_platform(platform) eq "windows"} {
160       if {[regexp {\$} $p]} {incr lim_root_files -1} else {lappend res $p}
161     } else {
162       lappend res "/$p"
163     }
164   }
165   do_execsql_test 3.1 [subst {
166     SELECT path FROM fstree WHERE path NOT GLOB '*\$*' LIMIT $lim_root_files;
167   }] $res
169   # Read all entries in the current directory.
170   #
171   proc contents {pattern} {
172     set res [list]
173     foreach f [list_files $pattern] {
174       lappend res $f
175       if {[file isdir $f]} {
176         set res [concat $res [contents "$f/*"]]
177       }
178     }
179     set res
180   }
181   set pwd "[pwd]/*"
182   set res [contents $pwd]
183   do_execsql_test 3.2 {
184     SELECT path FROM fstree WHERE path GLOB $pwd ORDER BY 1
185   } [lsort $res]
187   # Add some sub-directories and files to the current directory.
188   #
189   do_test 3.3 {
190     catch { file delete -force subdir }
191     foreach {path sz} {
192       subdir/x1.txt     143
193       subdir/x2.txt     153
194     } {
195       set dir [file dirname $path]
196       catch { file mkdir $dir }
197       set fd [open $path w]
198       puts -nonewline $fd [string repeat 1 $sz]
199       close $fd
200     }
201   } {}
203   set pwd [pwd]
204   do_execsql_test 3.5 {
205     SELECT path, size FROM fstree WHERE path GLOB $pwd || '/subdir/*' ORDER BY 1
206   } [list \
207     "$pwd/subdir/x1.txt" 143 \
208     "$pwd/subdir/x2.txt" 153 \
209   ]
210   do_execsql_test 3.6 {
211     SELECT path, size FROM fstree WHERE path LIKE $pwd || '/subdir/%' ORDER BY 1
212   } [list \
213     "$pwd/subdir/x1.txt" 143 \
214     "$pwd/subdir/x2.txt" 153 \
215   ]
216   do_execsql_test 3.7 {
217     SELECT sum(size) FROM fstree WHERE path LIKE $pwd || '/subdir/%'
218   } 296
219   do_execsql_test 3.8 {
220     SELECT size FROM fstree WHERE path = $pwd || '/subdir/x1.txt'
221   } 143
226 finish_test