xref: /sqlite-3.40.0/test/descidx1.test (revision ff91c454)
1# 2005 December 21
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.  The
12# focus of this script is descending indices.
13#
14# $Id: descidx1.test,v 1.6 2006/06/27 12:51:13 drh Exp $
15#
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
20ifcapable legacyformat {
21  finish_test
22  return
23}
24
25# This procedure sets the value of the file-format in file 'test.db'
26# to $newval. Also, the schema cookie is incremented.
27#
28proc set_file_format {newval} {
29  set bt [btree_open test.db 10 0]
30  btree_begin_transaction $bt
31  set meta [btree_get_meta $bt]
32  lset meta 2 $newval                    ;# File format
33  lset meta 1 [expr [lindex $meta 1]+1]  ;# Schema cookie
34  eval "btree_update_meta $bt $meta"
35  btree_commit $bt
36  btree_close $bt
37}
38
39# This procedure returns the value of the file-format in file 'test.db'.
40#
41proc get_file_format {{fname test.db}} {
42  set bt [btree_open $fname 10 0]
43  set meta [btree_get_meta $bt]
44  btree_close $bt
45  lindex $meta 2
46}
47
48# Verify that the file format starts as 4.
49#
50do_test descidx1-1.1 {
51  execsql {
52    CREATE TABLE t1(a,b);
53    CREATE INDEX i1 ON t1(b ASC);
54  }
55  get_file_format
56} {4}
57do_test descidx1-1.2 {
58  execsql {
59    CREATE INDEX i2 ON t1(a DESC);
60  }
61  get_file_format
62} {4}
63
64# Put some information in the table and verify that the descending
65# index actually works.
66#
67do_test descidx1-2.1 {
68  execsql {
69    INSERT INTO t1 VALUES(1,1);
70    INSERT INTO t1 VALUES(2,2);
71    INSERT INTO t1 SELECT a+2, a+2 FROM t1;
72    INSERT INTO t1 SELECT a+4, a+4 FROM t1;
73    SELECT b FROM t1 WHERE a>3 AND a<7;
74  }
75} {6 5 4}
76do_test descidx1-2.2 {
77  execsql {
78    SELECT a FROM t1 WHERE b>3 AND b<7;
79  }
80} {4 5 6}
81do_test descidx1-2.3 {
82  execsql {
83    SELECT b FROM t1 WHERE a>=3 AND a<7;
84  }
85} {6 5 4 3}
86do_test descidx1-2.4 {
87  execsql {
88    SELECT b FROM t1 WHERE a>3 AND a<=7;
89  }
90} {7 6 5 4}
91do_test descidx1-2.5 {
92  execsql {
93    SELECT b FROM t1 WHERE a>=3 AND a<=7;
94  }
95} {7 6 5 4 3}
96do_test descidx1-2.6 {
97  execsql {
98    SELECT a FROM t1 WHERE b>=3 AND b<=7;
99  }
100} {3 4 5 6 7}
101
102# This procedure executes the SQL.  Then it checks to see if the OP_Sort
103# opcode was executed.  If an OP_Sort did occur, then "sort" is appended
104# to the result.  If no OP_Sort happened, then "nosort" is appended.
105#
106# This procedure is used to check to make sure sorting is or is not
107# occurring as expected.
108#
109proc cksort {sql} {
110  set ::sqlite_sort_count 0
111  set data [execsql $sql]
112  if {$::sqlite_sort_count} {set x sort} {set x nosort}
113  lappend data $x
114  return $data
115}
116
117# Test sorting using a descending index.
118#
119do_test descidx1-3.1 {
120  cksort {SELECT a FROM t1 ORDER BY a}
121} {1 2 3 4 5 6 7 8 nosort}
122do_test descidx1-3.2 {
123  cksort {SELECT a FROM t1 ORDER BY a ASC}
124} {1 2 3 4 5 6 7 8 nosort}
125do_test descidx1-3.3 {
126  cksort {SELECT a FROM t1 ORDER BY a DESC}
127} {8 7 6 5 4 3 2 1 nosort}
128do_test descidx1-3.4 {
129  cksort {SELECT b FROM t1 ORDER BY a}
130} {1 2 3 4 5 6 7 8 nosort}
131do_test descidx1-3.5 {
132  cksort {SELECT b FROM t1 ORDER BY a ASC}
133} {1 2 3 4 5 6 7 8 nosort}
134do_test descidx1-3.6 {
135  cksort {SELECT b FROM t1 ORDER BY a DESC}
136} {8 7 6 5 4 3 2 1 nosort}
137do_test descidx1-3.7 {
138  cksort {SELECT a FROM t1 ORDER BY b}
139} {1 2 3 4 5 6 7 8 nosort}
140do_test descidx1-3.8 {
141  cksort {SELECT a FROM t1 ORDER BY b ASC}
142} {1 2 3 4 5 6 7 8 nosort}
143do_test descidx1-3.9 {
144  cksort {SELECT a FROM t1 ORDER BY b DESC}
145} {8 7 6 5 4 3 2 1 nosort}
146do_test descidx1-3.10 {
147  cksort {SELECT b FROM t1 ORDER BY b}
148} {1 2 3 4 5 6 7 8 nosort}
149do_test descidx1-3.11 {
150  cksort {SELECT b FROM t1 ORDER BY b ASC}
151} {1 2 3 4 5 6 7 8 nosort}
152do_test descidx1-3.12 {
153  cksort {SELECT b FROM t1 ORDER BY b DESC}
154} {8 7 6 5 4 3 2 1 nosort}
155
156do_test descidx1-3.21 {
157  cksort {SELECT a FROM t1 WHERE a>3 AND a<8 ORDER BY a}
158} {4 5 6 7 nosort}
159do_test descidx1-3.22 {
160  cksort {SELECT a FROM t1 WHERE a>3 AND a<8 ORDER BY a ASC}
161} {4 5 6 7 nosort}
162do_test descidx1-3.23 {
163  cksort {SELECT a FROM t1 WHERE a>3 AND a<8 ORDER BY a DESC}
164} {7 6 5 4 nosort}
165do_test descidx1-3.24 {
166  cksort {SELECT b FROM t1 WHERE a>3 AND a<8 ORDER BY a}
167} {4 5 6 7 nosort}
168do_test descidx1-3.25 {
169  cksort {SELECT b FROM t1 WHERE a>3 AND a<8 ORDER BY a ASC}
170} {4 5 6 7 nosort}
171do_test descidx1-3.26 {
172  cksort {SELECT b FROM t1 WHERE a>3 AND a<8 ORDER BY a DESC}
173} {7 6 5 4 nosort}
174
175# Create a table with indices that are descending on some terms and
176# ascending on others.
177#
178ifcapable bloblit {
179  do_test descidx1-4.1 {
180    execsql {
181      CREATE TABLE t2(a INT, b TEXT, c BLOB, d REAL);
182      CREATE INDEX i3 ON t2(a ASC, b DESC, c ASC);
183      CREATE INDEX i4 ON t2(b DESC, a ASC, d DESC);
184      INSERT INTO t2 VALUES(1,'one',x'31',1.0);
185      INSERT INTO t2 VALUES(2,'two',x'3232',2.0);
186      INSERT INTO t2 VALUES(3,'three',x'333333',3.0);
187      INSERT INTO t2 VALUES(4,'four',x'34343434',4.0);
188      INSERT INTO t2 VALUES(5,'five',x'3535353535',5.0);
189      INSERT INTO t2 VALUES(6,'six',x'363636363636',6.0);
190      INSERT INTO t2 VALUES(2,'two',x'323232',2.1);
191      INSERT INTO t2 VALUES(2,'zwei',x'3232',2.2);
192      INSERT INTO t2 VALUES(2,NULL,NULL,2.3);
193      SELECT count(*) FROM t2;
194    }
195  } {9}
196  do_test descidx1-4.2 {
197    execsql {
198      SELECT d FROM t2 ORDER BY a;
199    }
200  } {1.0 2.2 2.0 2.1 2.3 3.0 4.0 5.0 6.0}
201  do_test descidx1-4.3 {
202    execsql {
203      SELECT d FROM t2 WHERE a>=2;
204    }
205  } {2.2 2.0 2.1 2.3 3.0 4.0 5.0 6.0}
206  do_test descidx1-4.4 {
207    execsql {
208      SELECT d FROM t2 WHERE a>2;
209    }
210  } {3.0 4.0 5.0 6.0}
211  do_test descidx1-4.5 {
212    execsql {
213      SELECT d FROM t2 WHERE a=2 AND b>'two';
214    }
215  } {2.2}
216  do_test descidx1-4.6 {
217    execsql {
218      SELECT d FROM t2 WHERE a=2 AND b>='two';
219    }
220  } {2.2 2.0 2.1}
221  do_test descidx1-4.7 {
222    execsql {
223      SELECT d FROM t2 WHERE a=2 AND b<'two';
224    }
225  } {}
226  do_test descidx1-4.8 {
227    execsql {
228      SELECT d FROM t2 WHERE a=2 AND b<='two';
229    }
230  } {2.0 2.1}
231}
232
233do_test descidx1-5.1 {
234  execsql {
235    CREATE TABLE t3(a,b,c,d);
236    CREATE INDEX t3i1 ON t3(a DESC, b ASC, c DESC, d ASC);
237    INSERT INTO t3 VALUES(0,0,0,0);
238    INSERT INTO t3 VALUES(0,0,0,1);
239    INSERT INTO t3 VALUES(0,0,1,0);
240    INSERT INTO t3 VALUES(0,0,1,1);
241    INSERT INTO t3 VALUES(0,1,0,0);
242    INSERT INTO t3 VALUES(0,1,0,1);
243    INSERT INTO t3 VALUES(0,1,1,0);
244    INSERT INTO t3 VALUES(0,1,1,1);
245    INSERT INTO t3 VALUES(1,0,0,0);
246    INSERT INTO t3 VALUES(1,0,0,1);
247    INSERT INTO t3 VALUES(1,0,1,0);
248    INSERT INTO t3 VALUES(1,0,1,1);
249    INSERT INTO t3 VALUES(1,1,0,0);
250    INSERT INTO t3 VALUES(1,1,0,1);
251    INSERT INTO t3 VALUES(1,1,1,0);
252    INSERT INTO t3 VALUES(1,1,1,1);
253    SELECT count(*) FROM t3;
254  }
255} {16}
256do_test descidx1-5.2 {
257  cksort {
258    SELECT a||b||c||d FROM t3 ORDER BY a,b,c,d;
259  }
260} {0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 sort}
261do_test descidx1-5.3 {
262  cksort {
263    SELECT a||b||c||d FROM t3 ORDER BY a DESC, b ASC, c DESC, d ASC;
264  }
265} {1010 1011 1000 1001 1110 1111 1100 1101 0010 0011 0000 0001 0110 0111 0100 0101 nosort}
266do_test descidx1-5.4 {
267  cksort {
268    SELECT a||b||c||d FROM t3 ORDER BY a ASC, b DESC, c ASC, d DESC;
269  }
270} {0101 0100 0111 0110 0001 0000 0011 0010 1101 1100 1111 1110 1001 1000 1011 1010 nosort}
271do_test descidx1-5.5 {
272  cksort {
273    SELECT a||b||c FROM t3 WHERE d=0 ORDER BY a DESC, b ASC, c DESC
274  }
275} {101 100 111 110 001 000 011 010 nosort}
276do_test descidx1-5.6 {
277  cksort {
278    SELECT a||b||c FROM t3 WHERE d=0 ORDER BY a ASC, b DESC, c ASC
279  }
280} {010 011 000 001 110 111 100 101 nosort}
281do_test descidx1-5.7 {
282  cksort {
283    SELECT a||b||c FROM t3 WHERE d=0 ORDER BY a ASC, b DESC, c DESC
284  }
285} {011 010 001 000 111 110 101 100 sort}
286do_test descidx1-5.8 {
287  cksort {
288    SELECT a||b||c FROM t3 WHERE d=0 ORDER BY a ASC, b ASC, c ASC
289  }
290} {000 001 010 011 100 101 110 111 sort}
291do_test descidx1-5.9 {
292  cksort {
293    SELECT a||b||c FROM t3 WHERE d=0 ORDER BY a DESC, b DESC, c ASC
294  }
295} {110 111 100 101 010 011 000 001 sort}
296
297# Test the legacy_file_format pragma here because we have access to
298# the get_file_format command.
299#
300do_test descidx1-6.1 {
301  db close
302  file delete -force test.db test.db-journal
303  sqlite3 db test.db
304  execsql {PRAGMA legacy_file_format}
305} {0}
306do_test descidx1-6.2 {
307  execsql {PRAGMA legacy_file_format=YES}
308  execsql {PRAGMA legacy_file_format}
309} {1}
310do_test descidx1-6.3 {
311  execsql {
312    CREATE TABLE t1(a,b,c);
313  }
314  get_file_format
315} {1}
316
317
318finish_test
319