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