Fix a problem allowing a LIMIT constraint to be passed to a virtual table in cases...
[sqlite.git] / test / bestindexC.test
blob769f1601db7f2e55ca1deedcc748c00c9bb18e9f
1 # 2023-10-26
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
14 set testdir [file dirname $argv0]
15 source $testdir/tester.tcl
16 set testprefix bestindexB
18 ifcapable !vtab {
19   finish_test
20   return
23 register_tcl_module db
25 proc vtab_command {lVal method args} {
26   switch -- $method {
27     xConnect {
28       return "CREATE TABLE t1(a)"
29     }
31     xBestIndex {
32       set hdl [lindex $args 0]
33       set clist [$hdl constraints]
34       set orderby [$hdl orderby]
36       set idxstr [list]
37       set res [list]
39       set idx 0
40       foreach c $clist {
41         array set a $c
42         if {$a(usable)==0} continue
43         if {$a(op)=="limit"} { 
44           lappend idxstr limit
45           lappend res omit $idx
46         }
47         if {$a(op)=="offset"} { 
48           lappend idxstr offset
49           lappend res omit $idx
50         }
51         incr idx
52       }
54       return "cost 1000000 rows 1000000 idxnum 0 idxstr {$idxstr} $res"
55     }
57     xFilter {
58       set idxstr [lindex $args 1]
59       set LIMIT ""
60       foreach a $idxstr b [lindex $args 2] {
61         append LIMIT " $a $b"
62       }
64       set idx 1
65       foreach v $lVal {
66         lappend lRow "($idx, '$v')"
67         incr idx
68       }
70       return [list sql "
71         SELECT * FROM ( VALUES [join $lRow ,]) $LIMIT
72       "]
73     }
74   }
76   return {}
79 do_execsql_test 1.0 {
80   CREATE VIRTUAL TABLE x1 USING tcl(vtab_command "a b c d e f");
81   CREATE VIRTUAL TABLE x2 USING tcl(vtab_command "A B C D E F a b");
82 } {}
84 do_execsql_test 1.1 {
85   CREATE TEMP TABLE t_unionall AS 
86     SELECT * FROM x1 UNION ALL SELECT * FROM x2;
88   CREATE TEMP TABLE t_intersect AS 
89     SELECT * FROM x1 INTERSECT SELECT * FROM x2;
91   CREATE TEMP TABLE t_union AS 
92     SELECT * FROM x1 UNION SELECT * FROM x2;
94   CREATE TEMP TABLE t_except AS 
95     SELECT * FROM x1 EXCEPT SELECT * FROM x2;
98 foreach {tn limit} {
99   1 "LIMIT 8" 
100   2 "LIMIT 4" 
101   3 "LIMIT 4 OFFSET 2" 
102   4 "LIMIT 8 OFFSET 4" 
103 } {
105   foreach {op tbl} {
106     "UNION ALL" t_unionall
107     "UNION"     t_union
108     "INTERSECT" t_intersect
109     "EXCEPT"    t_except
110   } {
112     set expect [execsql "SELECT * FROM $tbl $limit"]
113     do_execsql_test 1.2.$tbl.$tn "SELECT * FROM (
114       SELECT * FROM x1 $op SELECT * FROM x2
115     ) $limit" $expect
117   }
121 #-------------------------------------------------------------------------
122 reset_db
123 register_tcl_module db
125 do_execsql_test 2.0 {
126   CREATE VIRTUAL TABLE x1 USING tcl(vtab_command "a b c d e f");
127   CREATE VIRTUAL TABLE x2 USING tcl(vtab_command "a b e f");
128 } {}
130 do_execsql_test 2.1 {
131   SELECT * FROM x1 
132     EXCEPT
133   SELECT * FROM x2
134   LIMIT 3
135 } {c d}
137 #-------------------------------------------------------------------------
138 reset_db
139 register_tcl_module db
140 do_execsql_test 3.0 {
141   CREATE VIRTUAL TABLE y1 USING tcl(vtab_command "1 2 3 4 5 6 7 8 9 10");
142 } {}
144 do_execsql_test 3.1 {
145   SELECT * FROM y1 WHERE a = COALESCE('8', a) LIMIT 3
146 } {8}
148 do_execsql_test 3.2 {
149   SELECT * FROM y1 WHERE a = '2' LIMIT 3
150 } {2}
152 load_static_extension db series
153 do_execsql_test 3.3 {
154   SELECT * FROM generate_series(1, 5) WHERE value = (value & 14) LIMIT 3
155 } {2 4}
157 finish_test