w.i.p. add an icon for the developer env shell (abc shell)
[AROS-Contrib.git] / sqlite3 / test / types.test
blobeda9e71057ec636a821a379ad482fb33ba404b81
1 # 2001 September 15
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. Specfically
12 # it tests that the different storage classes (integer, real, text etc.)
13 # all work correctly.
15 # $Id: types.test,v 1.14 2004/11/14 21:56:31 drh Exp $
17 set testdir [file dirname $argv0]
18 source $testdir/tester.tcl
20 # Tests in this file are organized roughly as follows:
22 # types-1.*.*: Test that values are stored using the expected storage
23 #              classes when various forms of literals are inserted into
24 #              columns with different affinities.
25 # types-1.1.*: INSERT INTO <table> VALUES(...)
26 # types-1.2.*: INSERT INTO <table> SELECT...
27 # types-1.3.*: UPDATE <table> SET...
29 # types-2.*.*: Check that values can be stored and retrieving using the
30 #              various storage classes.
31 # types-2.1.*: INTEGER
32 # types-2.2.*: REAL
33 # types-2.3.*: NULL
34 # types-2.4.*: TEXT
35 # types-2.5.*: Records with a few different storage classes.
37 # types-3.*: Test that the '=' operator respects manifest types.
40 # Disable encryption on the database for this test.
41 db close
42 set DB [sqlite3 db test.db]
43 sqlite3_rekey $DB {}
45 # Create a table with one column for each type of affinity
46 do_test types-1.1.0 {
47   execsql {
48     CREATE TABLE t1(i integer, n numeric, t text, o blob);
49   }
50 } {}
52 # Each element of the following list represents one test case.
54 # The first value of each sub-list is an SQL literal. The following
55 # four value are the storage classes that would be used if the
56 # literal were inserted into a column with affinity INTEGER, NUMERIC, TEXT
57 # or NONE, respectively.
58 set values {
59   { 5.0    integer real    text real    }
60   { 5      integer integer text integer }
61   { '5.0'  integer real    text text    }
62   { '-5.0' integer real    text text    }
63   { '-5.0' integer real    text text    }
64   { '5'    integer integer text text    }
65   { 'abc'  text    text    text text    }
66   { NULL   null    null    null null    }
68 ifcapable {bloblit} {
69   lappend values  { X'00'  blob    blob    blob blob    }
72 # This code tests that the storage classes specified above (in the $values
73 # table) are correctly assigned when values are inserted using a statement
74 # of the form:
76 # INSERT INTO <table> VALUE(<values>);
78 set tnum 1
79 foreach val $values {
80   set lit [lindex $val 0]
81   execsql "DELETE FROM t1;"
82   execsql "INSERT INTO t1 VALUES($lit, $lit, $lit, $lit);"
83   do_test types-1.1.$tnum {
84     execsql {
85       SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1;
86     }
87   } [lrange $val 1 end]
88   incr tnum
91 # This code tests that the storage classes specified above (in the $values
92 # table) are correctly assigned when values are inserted using a statement
93 # of the form:
95 # INSERT INTO t1 SELECT ....
97 set tnum 1
98 foreach val $values {
99   set lit [lindex $val 0]
100   execsql "DELETE FROM t1;"
101   execsql "INSERT INTO t1 SELECT $lit, $lit, $lit, $lit;"
102   do_test types-1.2.$tnum {
103     execsql {
104       SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1;
105     }
106   } [lrange $val 1 end]
107   incr tnum
110 # This code tests that the storage classes specified above (in the $values
111 # table) are correctly assigned when values are inserted using a statement
112 # of the form:
114 # UPDATE <table> SET <column> = <value>;
116 set tnum 1
117 foreach val $values {
118   set lit [lindex $val 0]
119   execsql "UPDATE t1 SET i = $lit, n = $lit, t = $lit, o = $lit;"
120   do_test types-1.3.$tnum {
121     execsql {
122       SELECT typeof(i), typeof(n), typeof(t), typeof(o) FROM t1;
123     }
124   } [lrange $val 1 end]
125   incr tnum
128 execsql {
129   DROP TABLE t1;
132 # Open the table with root-page $rootpage at the btree
133 # level. Return a list that is the length of each record
134 # in the table, in the tables default scanning order.
135 proc record_sizes {rootpage} {
136   set bt [btree_open test.db 10 0]
137   set c [btree_cursor $bt $rootpage 0]
138   btree_first $c
139   while 1 {
140     lappend res [btree_payload_size $c]
141     if {[btree_next $c]} break
142   }
143   btree_close_cursor $c
144   btree_close $bt
145   set res
149 # Create a table and insert some 1-byte integers. Make sure they 
150 # can be read back OK. These should be 3 byte records.
151 do_test types-2.1.1 {
152   execsql {
153     CREATE TABLE t1(a integer);
154     INSERT INTO t1 VALUES(0);
155     INSERT INTO t1 VALUES(120);
156     INSERT INTO t1 VALUES(-120);
157   }
158 } {}
159 do_test types-2.1.2 {
160   execsql {
161     SELECT a FROM t1;
162   }
163 } {0 120 -120}
165 # Try some 2-byte integers (4 byte records)
166 do_test types-2.1.3 {
167   execsql {
168     INSERT INTO t1 VALUES(30000);
169     INSERT INTO t1 VALUES(-30000);
170   }
171 } {}
172 do_test types-2.1.4 {
173   execsql {
174     SELECT a FROM t1;
175   }
176 } {0 120 -120 30000 -30000}
178 # 4-byte integers (6 byte records)
179 do_test types-2.1.5 {
180   execsql {
181     INSERT INTO t1 VALUES(2100000000);
182     INSERT INTO t1 VALUES(-2100000000);
183   }
184 } {}
185 do_test types-2.1.6 {
186   execsql {
187     SELECT a FROM t1;
188   }
189 } {0 120 -120 30000 -30000 2100000000 -2100000000}
191 # 8-byte integers (10 byte records)
192 do_test types-2.1.7 {
193   execsql {
194     INSERT INTO t1 VALUES(9000000*1000000*1000000);
195     INSERT INTO t1 VALUES(-9000000*1000000*1000000);
196   }
197 } {}
198 do_test types-2.1.8 {
199   execsql {
200     SELECT a FROM t1;
201   }
202 } [list 0 120 -120 30000 -30000 2100000000 -2100000000 \
203         9000000000000000000 -9000000000000000000]
205 # Check that all the record sizes are as we expected.
206 do_test types-2.1.9 {
207   set root [db eval {select rootpage from sqlite_master where name = 't1'}]
208   record_sizes $root
209 } {3 3 3 4 4 6 6 10 10}
211 # Insert some reals. These should be 10 byte records.
212 do_test types-2.2.1 {
213   execsql {
214     CREATE TABLE t2(a float);
215     INSERT INTO t2 VALUES(0.0);
216     INSERT INTO t2 VALUES(12345.678);
217     INSERT INTO t2 VALUES(-12345.678);
218   }
219 } {}
220 do_test types-2.2.2 {
221   execsql {
222     SELECT a FROM t2;
223   }
224 } {0.0 12345.678 -12345.678}
226 # Check that all the record sizes are as we expected.
227 do_test types-2.2.3 {
228   set root [db eval {select rootpage from sqlite_master where name = 't2'}]
229   record_sizes $root
230 } {10 10 10}
232 # Insert a NULL. This should be a two byte record.
233 do_test types-2.3.1 {
234   execsql {
235     CREATE TABLE t3(a nullvalue);
236     INSERT INTO t3 VALUES(NULL);
237   }
238 } {}
239 do_test types-2.3.2 {
240   execsql {
241     SELECT a ISNULL FROM t3;
242   }
243 } {1}
245 # Check that all the record sizes are as we expected.
246 do_test types-2.3.3 {
247   set root [db eval {select rootpage from sqlite_master where name = 't3'}]
248   record_sizes $root
249 } {2}
251 # Insert a couple of strings.
252 do_test types-2.4.1 {
253   set string10 abcdefghij
254   set string500 [string repeat $string10 50]
255   set string500000 [string repeat $string10 50000]
257   execsql "
258     CREATE TABLE t4(a string);
259     INSERT INTO t4 VALUES('$string10');
260     INSERT INTO t4 VALUES('$string500');
261     INSERT INTO t4 VALUES('$string500000');
262   "
263 } {}
264 do_test types-2.4.2 {
265   execsql {
266     SELECT a FROM t4;
267   }
268 } [list $string10 $string500 $string500000]
270 # Check that all the record sizes are as we expected. This is dependant on
271 # the database encoding.
272 if { $sqlite_options(utf16)==0 || [execsql {pragma encoding}] == "UTF-8" } {
273   do_test types-2.4.3 {
274     set root [db eval {select rootpage from sqlite_master where name = 't4'}]
275     record_sizes $root
276   } {12 503 500004}
277 } else {
278   do_test types-2.4.3 {
279     set root [db eval {select rootpage from sqlite_master where name = 't4'}]
280     record_sizes $root
281   } {22 1003 1000004}
284 do_test types-2.5.1 {
285   execsql {
286     DROP TABLE t1;
287     DROP TABLE t2;
288     DROP TABLE t3;
289     DROP TABLE t4;
290     CREATE TABLE t1(a, b, c);
291   }
292 } {}
293 do_test types-2.5.2 {
294   set string10 abcdefghij
295   set string500 [string repeat $string10 50]
296   set string500000 [string repeat $string10 50000]
298   execsql "INSERT INTO t1 VALUES(NULL, '$string10', 4000);"
299   execsql "INSERT INTO t1 VALUES('$string500', 4000, NULL);"
300   execsql "INSERT INTO t1 VALUES(4000, NULL, '$string500000');"
301 } {}
302 do_test types-2.5.3 {
303   execsql {
304     SELECT * FROM t1;
305   }
306 } [list {} $string10 4000 $string500 4000 {} 4000 {} $string500000]
308 finish_test