diff options
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/test/capi3.test')
-rw-r--r-- | libraries/sqlite/unix/sqlite-3.5.1/test/capi3.test | 1071 |
1 files changed, 1071 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/test/capi3.test b/libraries/sqlite/unix/sqlite-3.5.1/test/capi3.test new file mode 100644 index 0000000..2c89c43 --- /dev/null +++ b/libraries/sqlite/unix/sqlite-3.5.1/test/capi3.test | |||
@@ -0,0 +1,1071 @@ | |||
1 | # 2003 January 29 | ||
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 testing the callback-free C/C++ API. | ||
13 | # | ||
14 | # $Id: capi3.test,v 1.55 2007/08/29 19:15:09 drh Exp $ | ||
15 | # | ||
16 | |||
17 | set testdir [file dirname $argv0] | ||
18 | source $testdir/tester.tcl | ||
19 | |||
20 | # Return the UTF-16 representation of the supplied UTF-8 string $str. | ||
21 | # If $nt is true, append two 0x00 bytes as a nul terminator. | ||
22 | proc utf16 {str {nt 1}} { | ||
23 | set r [encoding convertto unicode $str] | ||
24 | if {$nt} { | ||
25 | append r "\x00\x00" | ||
26 | } | ||
27 | return $r | ||
28 | } | ||
29 | |||
30 | # Return the UTF-8 representation of the supplied UTF-16 string $str. | ||
31 | proc utf8 {str} { | ||
32 | # If $str ends in two 0x00 0x00 bytes, knock these off before | ||
33 | # converting to UTF-8 using TCL. | ||
34 | binary scan $str \c* vals | ||
35 | if {[lindex $vals end]==0 && [lindex $vals end-1]==0} { | ||
36 | set str [binary format \c* [lrange $vals 0 end-2]] | ||
37 | } | ||
38 | |||
39 | set r [encoding convertfrom unicode $str] | ||
40 | return $r | ||
41 | } | ||
42 | |||
43 | # These tests complement those in capi2.test. They are organized | ||
44 | # as follows: | ||
45 | # | ||
46 | # capi3-1.*: Test sqlite3_prepare | ||
47 | # capi3-2.*: Test sqlite3_prepare16 | ||
48 | # capi3-3.*: Test sqlite3_open | ||
49 | # capi3-4.*: Test sqlite3_open16 | ||
50 | # capi3-5.*: Test the various sqlite3_result_* APIs | ||
51 | # capi3-6.*: Test that sqlite3_close fails if there are outstanding VMs. | ||
52 | # | ||
53 | |||
54 | set DB [sqlite3_connection_pointer db] | ||
55 | |||
56 | do_test capi3-1.0 { | ||
57 | sqlite3_get_autocommit $DB | ||
58 | } 1 | ||
59 | do_test capi3-1.1 { | ||
60 | set STMT [sqlite3_prepare $DB {SELECT name FROM sqlite_master} -1 TAIL] | ||
61 | sqlite3_finalize $STMT | ||
62 | set TAIL | ||
63 | } {} | ||
64 | do_test capi3-1.2 { | ||
65 | sqlite3_errcode $DB | ||
66 | } {SQLITE_OK} | ||
67 | do_test capi3-1.3 { | ||
68 | sqlite3_errmsg $DB | ||
69 | } {not an error} | ||
70 | do_test capi3-1.4 { | ||
71 | set sql {SELECT name FROM sqlite_master;SELECT 10} | ||
72 | set STMT [sqlite3_prepare $DB $sql -1 TAIL] | ||
73 | sqlite3_finalize $STMT | ||
74 | set TAIL | ||
75 | } {SELECT 10} | ||
76 | do_test capi3-1.5 { | ||
77 | set sql {SELECT namex FROM sqlite_master} | ||
78 | catch { | ||
79 | set STMT [sqlite3_prepare $DB $sql -1 TAIL] | ||
80 | } | ||
81 | } {1} | ||
82 | do_test capi3-1.6 { | ||
83 | sqlite3_errcode $DB | ||
84 | } {SQLITE_ERROR} | ||
85 | do_test capi3-1.7 { | ||
86 | sqlite3_errmsg $DB | ||
87 | } {no such column: namex} | ||
88 | |||
89 | ifcapable {utf16} { | ||
90 | do_test capi3-2.1 { | ||
91 | set sql16 [utf16 {SELECT name FROM sqlite_master}] | ||
92 | set STMT [sqlite3_prepare16 $DB $sql16 -1 ::TAIL] | ||
93 | sqlite3_finalize $STMT | ||
94 | utf8 $::TAIL | ||
95 | } {} | ||
96 | do_test capi3-2.2 { | ||
97 | set sql [utf16 {SELECT name FROM sqlite_master;SELECT 10}] | ||
98 | set STMT [sqlite3_prepare16 $DB $sql -1 TAIL] | ||
99 | sqlite3_finalize $STMT | ||
100 | utf8 $TAIL | ||
101 | } {SELECT 10} | ||
102 | do_test capi3-2.3 { | ||
103 | set sql [utf16 {SELECT namex FROM sqlite_master}] | ||
104 | catch { | ||
105 | set STMT [sqlite3_prepare16 $DB $sql -1 TAIL] | ||
106 | } | ||
107 | } {1} | ||
108 | do_test capi3-2.4 { | ||
109 | sqlite3_errcode $DB | ||
110 | } {SQLITE_ERROR} | ||
111 | do_test capi3-2.5 { | ||
112 | sqlite3_errmsg $DB | ||
113 | } {no such column: namex} | ||
114 | |||
115 | ifcapable schema_pragmas { | ||
116 | do_test capi3-2.6 { | ||
117 | execsql {CREATE TABLE tablename(x)} | ||
118 | set sql16 [utf16 {PRAGMA table_info("TableName")}] | ||
119 | set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL] | ||
120 | sqlite3_step $STMT | ||
121 | } SQLITE_ROW | ||
122 | do_test capi3-2.7 { | ||
123 | sqlite3_step $STMT | ||
124 | } SQLITE_DONE | ||
125 | do_test capi3-2.8 { | ||
126 | sqlite3_finalize $STMT | ||
127 | } SQLITE_OK | ||
128 | } | ||
129 | |||
130 | } ;# endif utf16 | ||
131 | |||
132 | # rename sqlite3_open sqlite3_open_old | ||
133 | # proc sqlite3_open {fname options} {sqlite3_open_new $fname $options} | ||
134 | |||
135 | do_test capi3-3.1 { | ||
136 | set db2 [sqlite3_open test.db {}] | ||
137 | sqlite3_errcode $db2 | ||
138 | } {SQLITE_OK} | ||
139 | # FIX ME: Should test the db handle works. | ||
140 | do_test capi3-3.2 { | ||
141 | sqlite3_close $db2 | ||
142 | } {SQLITE_OK} | ||
143 | do_test capi3-3.3 { | ||
144 | catch { | ||
145 | set db2 [sqlite3_open /bogus/path/test.db {}] | ||
146 | } | ||
147 | sqlite3_errcode $db2 | ||
148 | } {SQLITE_CANTOPEN} | ||
149 | do_test capi3-3.4 { | ||
150 | sqlite3_errmsg $db2 | ||
151 | } {unable to open database file} | ||
152 | do_test capi3-3.5 { | ||
153 | sqlite3_close $db2 | ||
154 | } {SQLITE_OK} | ||
155 | do_test capi3-3.6.1-misuse { | ||
156 | sqlite3_close $db2 | ||
157 | } {SQLITE_MISUSE} | ||
158 | do_test capi3-3.6.2-misuse { | ||
159 | sqlite3_errmsg $db2 | ||
160 | } {library routine called out of sequence} | ||
161 | ifcapable {utf16} { | ||
162 | do_test capi3-3.6.3-misuse { | ||
163 | utf8 [sqlite3_errmsg16 $db2] | ||
164 | } {library routine called out of sequence} | ||
165 | } | ||
166 | |||
167 | # rename sqlite3_open "" | ||
168 | # rename sqlite3_open_old sqlite3_open | ||
169 | |||
170 | ifcapable {utf16} { | ||
171 | do_test capi3-4.1 { | ||
172 | set db2 [sqlite3_open16 [utf16 test.db] {}] | ||
173 | sqlite3_errcode $db2 | ||
174 | } {SQLITE_OK} | ||
175 | # FIX ME: Should test the db handle works. | ||
176 | do_test capi3-4.2 { | ||
177 | sqlite3_close $db2 | ||
178 | } {SQLITE_OK} | ||
179 | do_test capi3-4.3 { | ||
180 | catch { | ||
181 | set db2 [sqlite3_open16 [utf16 /bogus/path/test.db] {}] | ||
182 | } | ||
183 | sqlite3_errcode $db2 | ||
184 | } {SQLITE_CANTOPEN} | ||
185 | do_test capi3-4.4 { | ||
186 | utf8 [sqlite3_errmsg16 $db2] | ||
187 | } {unable to open database file} | ||
188 | do_test capi3-4.5 { | ||
189 | sqlite3_close $db2 | ||
190 | } {SQLITE_OK} | ||
191 | } ;# utf16 | ||
192 | |||
193 | # This proc is used to test the following API calls: | ||
194 | # | ||
195 | # sqlite3_column_count | ||
196 | # sqlite3_column_name | ||
197 | # sqlite3_column_name16 | ||
198 | # sqlite3_column_decltype | ||
199 | # sqlite3_column_decltype16 | ||
200 | # | ||
201 | # $STMT is a compiled SQL statement. $test is a prefix | ||
202 | # to use for test names within this proc. $names is a list | ||
203 | # of the column names that should be returned by $STMT. | ||
204 | # $decltypes is a list of column declaration types for $STMT. | ||
205 | # | ||
206 | # Example: | ||
207 | # | ||
208 | # set STMT [sqlite3_prepare "SELECT 1, 2, 2;" -1 DUMMY] | ||
209 | # check_header test1.1 {1 2 3} {"" "" ""} | ||
210 | # | ||
211 | proc check_header {STMT test names decltypes} { | ||
212 | |||
213 | # Use the return value of sqlite3_column_count() to build | ||
214 | # a list of column indexes. i.e. If sqlite3_column_count | ||
215 | # is 3, build the list {0 1 2}. | ||
216 | set ::idxlist [list] | ||
217 | set ::numcols [sqlite3_column_count $STMT] | ||
218 | for {set i 0} {$i < $::numcols} {incr i} {lappend ::idxlist $i} | ||
219 | |||
220 | # Column names in UTF-8 | ||
221 | do_test $test.1 { | ||
222 | set cnamelist [list] | ||
223 | foreach i $idxlist {lappend cnamelist [sqlite3_column_name $STMT $i]} | ||
224 | set cnamelist | ||
225 | } $names | ||
226 | |||
227 | # Column names in UTF-16 | ||
228 | ifcapable {utf16} { | ||
229 | do_test $test.2 { | ||
230 | set cnamelist [list] | ||
231 | foreach i $idxlist { | ||
232 | lappend cnamelist [utf8 [sqlite3_column_name16 $STMT $i]] | ||
233 | } | ||
234 | set cnamelist | ||
235 | } $names | ||
236 | } | ||
237 | |||
238 | # Column names in UTF-8 | ||
239 | do_test $test.3 { | ||
240 | set cnamelist [list] | ||
241 | foreach i $idxlist {lappend cnamelist [sqlite3_column_name $STMT $i]} | ||
242 | set cnamelist | ||
243 | } $names | ||
244 | |||
245 | # Column names in UTF-16 | ||
246 | ifcapable {utf16} { | ||
247 | do_test $test.4 { | ||
248 | set cnamelist [list] | ||
249 | foreach i $idxlist { | ||
250 | lappend cnamelist [utf8 [sqlite3_column_name16 $STMT $i]] | ||
251 | } | ||
252 | set cnamelist | ||
253 | } $names | ||
254 | } | ||
255 | |||
256 | # Column names in UTF-8 | ||
257 | do_test $test.5 { | ||
258 | set cnamelist [list] | ||
259 | foreach i $idxlist {lappend cnamelist [sqlite3_column_decltype $STMT $i]} | ||
260 | set cnamelist | ||
261 | } $decltypes | ||
262 | |||
263 | # Column declaration types in UTF-16 | ||
264 | ifcapable {utf16} { | ||
265 | do_test $test.6 { | ||
266 | set cnamelist [list] | ||
267 | foreach i $idxlist { | ||
268 | lappend cnamelist [utf8 [sqlite3_column_decltype16 $STMT $i]] | ||
269 | } | ||
270 | set cnamelist | ||
271 | } $decltypes | ||
272 | } | ||
273 | |||
274 | |||
275 | # Test some out of range conditions: | ||
276 | ifcapable {utf16} { | ||
277 | do_test $test.7 { | ||
278 | list \ | ||
279 | [sqlite3_column_name $STMT -1] \ | ||
280 | [sqlite3_column_name16 $STMT -1] \ | ||
281 | [sqlite3_column_decltype $STMT -1] \ | ||
282 | [sqlite3_column_decltype16 $STMT -1] \ | ||
283 | [sqlite3_column_name $STMT $numcols] \ | ||
284 | [sqlite3_column_name16 $STMT $numcols] \ | ||
285 | [sqlite3_column_decltype $STMT $numcols] \ | ||
286 | [sqlite3_column_decltype16 $STMT $numcols] | ||
287 | } {{} {} {} {} {} {} {} {}} | ||
288 | } | ||
289 | } | ||
290 | |||
291 | # This proc is used to test the following API calls: | ||
292 | # | ||
293 | # sqlite3_column_origin_name | ||
294 | # sqlite3_column_origin_name16 | ||
295 | # sqlite3_column_table_name | ||
296 | # sqlite3_column_table_name16 | ||
297 | # sqlite3_column_database_name | ||
298 | # sqlite3_column_database_name16 | ||
299 | # | ||
300 | # $STMT is a compiled SQL statement. $test is a prefix | ||
301 | # to use for test names within this proc. $names is a list | ||
302 | # of the column names that should be returned by $STMT. | ||
303 | # $decltypes is a list of column declaration types for $STMT. | ||
304 | # | ||
305 | # Example: | ||
306 | # | ||
307 | # set STMT [sqlite3_prepare "SELECT 1, 2, 2;" -1 DUMMY] | ||
308 | # check_header test1.1 {1 2 3} {"" "" ""} | ||
309 | # | ||
310 | proc check_origin_header {STMT test dbs tables cols} { | ||
311 | # If sqlite3_column_origin_name() and friends are not compiled into | ||
312 | # this build, this proc is a no-op. | ||
313 | ifcapable columnmetadata { | ||
314 | # Use the return value of sqlite3_column_count() to build | ||
315 | # a list of column indexes. i.e. If sqlite3_column_count | ||
316 | # is 3, build the list {0 1 2}. | ||
317 | set ::idxlist [list] | ||
318 | set ::numcols [sqlite3_column_count $STMT] | ||
319 | for {set i 0} {$i < $::numcols} {incr i} {lappend ::idxlist $i} | ||
320 | |||
321 | # Database names in UTF-8 | ||
322 | do_test $test.8 { | ||
323 | set cnamelist [list] | ||
324 | foreach i $idxlist { | ||
325 | lappend cnamelist [sqlite3_column_database_name $STMT $i] | ||
326 | } | ||
327 | set cnamelist | ||
328 | } $dbs | ||
329 | |||
330 | # Database names in UTF-16 | ||
331 | ifcapable {utf16} { | ||
332 | do_test $test.9 { | ||
333 | set cnamelist [list] | ||
334 | foreach i $idxlist { | ||
335 | lappend cnamelist [utf8 [sqlite3_column_database_name16 $STMT $i]] | ||
336 | } | ||
337 | set cnamelist | ||
338 | } $dbs | ||
339 | } | ||
340 | |||
341 | # Table names in UTF-8 | ||
342 | do_test $test.10 { | ||
343 | set cnamelist [list] | ||
344 | foreach i $idxlist { | ||
345 | lappend cnamelist [sqlite3_column_table_name $STMT $i] | ||
346 | } | ||
347 | set cnamelist | ||
348 | } $tables | ||
349 | |||
350 | # Table names in UTF-16 | ||
351 | ifcapable {utf16} { | ||
352 | do_test $test.11 { | ||
353 | set cnamelist [list] | ||
354 | foreach i $idxlist { | ||
355 | lappend cnamelist [utf8 [sqlite3_column_table_name16 $STMT $i]] | ||
356 | } | ||
357 | set cnamelist | ||
358 | } $tables | ||
359 | } | ||
360 | |||
361 | # Origin names in UTF-8 | ||
362 | do_test $test.12 { | ||
363 | set cnamelist [list] | ||
364 | foreach i $idxlist { | ||
365 | lappend cnamelist [sqlite3_column_origin_name $STMT $i] | ||
366 | } | ||
367 | set cnamelist | ||
368 | } $cols | ||
369 | |||
370 | # Origin declaration types in UTF-16 | ||
371 | ifcapable {utf16} { | ||
372 | do_test $test.13 { | ||
373 | set cnamelist [list] | ||
374 | foreach i $idxlist { | ||
375 | lappend cnamelist [utf8 [sqlite3_column_origin_name16 $STMT $i]] | ||
376 | } | ||
377 | set cnamelist | ||
378 | } $cols | ||
379 | } | ||
380 | } | ||
381 | } | ||
382 | |||
383 | # This proc is used to test the following APIs: | ||
384 | # | ||
385 | # sqlite3_data_count | ||
386 | # sqlite3_column_type | ||
387 | # sqlite3_column_int | ||
388 | # sqlite3_column_text | ||
389 | # sqlite3_column_text16 | ||
390 | # sqlite3_column_double | ||
391 | # | ||
392 | # $STMT is a compiled SQL statement for which the previous call | ||
393 | # to sqlite3_step returned SQLITE_ROW. $test is a prefix to use | ||
394 | # for test names within this proc. $types is a list of the | ||
395 | # manifest types for the current row. $ints, $doubles and $strings | ||
396 | # are lists of the integer, real and string representations of | ||
397 | # the values in the current row. | ||
398 | # | ||
399 | # Example: | ||
400 | # | ||
401 | # set STMT [sqlite3_prepare "SELECT 'hello', 1.1, NULL" -1 DUMMY] | ||
402 | # sqlite3_step $STMT | ||
403 | # check_data test1.2 {TEXT REAL NULL} {0 1 0} {0 1.1 0} {hello 1.1 {}} | ||
404 | # | ||
405 | proc check_data {STMT test types ints doubles strings} { | ||
406 | |||
407 | # Use the return value of sqlite3_column_count() to build | ||
408 | # a list of column indexes. i.e. If sqlite3_column_count | ||
409 | # is 3, build the list {0 1 2}. | ||
410 | set ::idxlist [list] | ||
411 | set numcols [sqlite3_data_count $STMT] | ||
412 | for {set i 0} {$i < $numcols} {incr i} {lappend ::idxlist $i} | ||
413 | |||
414 | # types | ||
415 | do_test $test.1 { | ||
416 | set types [list] | ||
417 | foreach i $idxlist {lappend types [sqlite3_column_type $STMT $i]} | ||
418 | set types | ||
419 | } $types | ||
420 | |||
421 | # Integers | ||
422 | do_test $test.2 { | ||
423 | set ints [list] | ||
424 | foreach i $idxlist {lappend ints [sqlite3_column_int64 $STMT $i]} | ||
425 | set ints | ||
426 | } $ints | ||
427 | |||
428 | # bytes | ||
429 | set lens [list] | ||
430 | foreach i $::idxlist { | ||
431 | lappend lens [string length [lindex $strings $i]] | ||
432 | } | ||
433 | do_test $test.3 { | ||
434 | set bytes [list] | ||
435 | set lens [list] | ||
436 | foreach i $idxlist { | ||
437 | lappend bytes [sqlite3_column_bytes $STMT $i] | ||
438 | } | ||
439 | set bytes | ||
440 | } $lens | ||
441 | |||
442 | # bytes16 | ||
443 | ifcapable {utf16} { | ||
444 | set lens [list] | ||
445 | foreach i $::idxlist { | ||
446 | lappend lens [expr 2 * [string length [lindex $strings $i]]] | ||
447 | } | ||
448 | do_test $test.4 { | ||
449 | set bytes [list] | ||
450 | set lens [list] | ||
451 | foreach i $idxlist { | ||
452 | lappend bytes [sqlite3_column_bytes16 $STMT $i] | ||
453 | } | ||
454 | set bytes | ||
455 | } $lens | ||
456 | } | ||
457 | |||
458 | # Blob | ||
459 | do_test $test.5 { | ||
460 | set utf8 [list] | ||
461 | foreach i $idxlist {lappend utf8 [sqlite3_column_blob $STMT $i]} | ||
462 | set utf8 | ||
463 | } $strings | ||
464 | |||
465 | # UTF-8 | ||
466 | do_test $test.6 { | ||
467 | set utf8 [list] | ||
468 | foreach i $idxlist {lappend utf8 [sqlite3_column_text $STMT $i]} | ||
469 | set utf8 | ||
470 | } $strings | ||
471 | |||
472 | # Floats | ||
473 | do_test $test.7 { | ||
474 | set utf8 [list] | ||
475 | foreach i $idxlist {lappend utf8 [sqlite3_column_double $STMT $i]} | ||
476 | set utf8 | ||
477 | } $doubles | ||
478 | |||
479 | # UTF-16 | ||
480 | ifcapable {utf16} { | ||
481 | do_test $test.8 { | ||
482 | set utf8 [list] | ||
483 | foreach i $idxlist {lappend utf8 [utf8 [sqlite3_column_text16 $STMT $i]]} | ||
484 | set utf8 | ||
485 | } $strings | ||
486 | } | ||
487 | |||
488 | # Integers | ||
489 | do_test $test.9 { | ||
490 | set ints [list] | ||
491 | foreach i $idxlist {lappend ints [sqlite3_column_int $STMT $i]} | ||
492 | set ints | ||
493 | } $ints | ||
494 | |||
495 | # Floats | ||
496 | do_test $test.10 { | ||
497 | set utf8 [list] | ||
498 | foreach i $idxlist {lappend utf8 [sqlite3_column_double $STMT $i]} | ||
499 | set utf8 | ||
500 | } $doubles | ||
501 | |||
502 | # UTF-8 | ||
503 | do_test $test.11 { | ||
504 | set utf8 [list] | ||
505 | foreach i $idxlist {lappend utf8 [sqlite3_column_text $STMT $i]} | ||
506 | set utf8 | ||
507 | } $strings | ||
508 | |||
509 | # Types | ||
510 | do_test $test.12 { | ||
511 | set types [list] | ||
512 | foreach i $idxlist {lappend types [sqlite3_column_type $STMT $i]} | ||
513 | set types | ||
514 | } $types | ||
515 | |||
516 | # Test that an out of range request returns the equivalent of NULL | ||
517 | do_test $test.13 { | ||
518 | sqlite3_column_int $STMT -1 | ||
519 | } {0} | ||
520 | do_test $test.13 { | ||
521 | sqlite3_column_text $STMT -1 | ||
522 | } {} | ||
523 | |||
524 | } | ||
525 | |||
526 | ifcapable !floatingpoint { | ||
527 | finish_test | ||
528 | return | ||
529 | } | ||
530 | |||
531 | do_test capi3-5.0 { | ||
532 | execsql { | ||
533 | CREATE TABLE t1(a VARINT, b BLOB, c VARCHAR(16)); | ||
534 | INSERT INTO t1 VALUES(1, 2, 3); | ||
535 | INSERT INTO t1 VALUES('one', 'two', NULL); | ||
536 | INSERT INTO t1 VALUES(1.2, 1.3, 1.4); | ||
537 | } | ||
538 | set sql "SELECT * FROM t1" | ||
539 | set STMT [sqlite3_prepare $DB $sql -1 TAIL] | ||
540 | sqlite3_column_count $STMT | ||
541 | } 3 | ||
542 | |||
543 | check_header $STMT capi3-5.1 {a b c} {VARINT BLOB VARCHAR(16)} | ||
544 | check_origin_header $STMT capi3-5.1 {main main main} {t1 t1 t1} {a b c} | ||
545 | do_test capi3-5.2 { | ||
546 | sqlite3_step $STMT | ||
547 | } SQLITE_ROW | ||
548 | |||
549 | check_header $STMT capi3-5.3 {a b c} {VARINT BLOB VARCHAR(16)} | ||
550 | check_origin_header $STMT capi3-5.3 {main main main} {t1 t1 t1} {a b c} | ||
551 | check_data $STMT capi3-5.4 {INTEGER INTEGER TEXT} {1 2 3} {1.0 2.0 3.0} {1 2 3} | ||
552 | |||
553 | do_test capi3-5.5 { | ||
554 | sqlite3_step $STMT | ||
555 | } SQLITE_ROW | ||
556 | |||
557 | check_header $STMT capi3-5.6 {a b c} {VARINT BLOB VARCHAR(16)} | ||
558 | check_origin_header $STMT capi3-5.6 {main main main} {t1 t1 t1} {a b c} | ||
559 | check_data $STMT capi3-5.7 {TEXT TEXT NULL} {0 0 0} {0.0 0.0 0.0} {one two {}} | ||
560 | |||
561 | do_test capi3-5.8 { | ||
562 | sqlite3_step $STMT | ||
563 | } SQLITE_ROW | ||
564 | |||
565 | check_header $STMT capi3-5.9 {a b c} {VARINT BLOB VARCHAR(16)} | ||
566 | check_origin_header $STMT capi3-5.9 {main main main} {t1 t1 t1} {a b c} | ||
567 | check_data $STMT capi3-5.10 {FLOAT FLOAT TEXT} {1 1 1} {1.2 1.3 1.4} {1.2 1.3 1.4} | ||
568 | |||
569 | do_test capi3-5.11 { | ||
570 | sqlite3_step $STMT | ||
571 | } SQLITE_DONE | ||
572 | |||
573 | do_test capi3-5.12 { | ||
574 | sqlite3_finalize $STMT | ||
575 | } SQLITE_OK | ||
576 | |||
577 | do_test capi3-5.20 { | ||
578 | set sql "SELECT a, sum(b), max(c) FROM t1 GROUP BY a" | ||
579 | set STMT [sqlite3_prepare $DB $sql -1 TAIL] | ||
580 | sqlite3_column_count $STMT | ||
581 | } 3 | ||
582 | |||
583 | check_header $STMT capi3-5.21 {a sum(b) max(c)} {VARINT {} {}} | ||
584 | check_origin_header $STMT capi3-5.22 {main {} {}} {t1 {} {}} {a {} {}} | ||
585 | do_test capi3-5.23 { | ||
586 | sqlite3_finalize $STMT | ||
587 | } SQLITE_OK | ||
588 | |||
589 | do_test capi3-5.30 { | ||
590 | set sql "SELECT a AS x, sum(b) AS y, max(c) AS z FROM t1 AS m GROUP BY x" | ||
591 | set STMT [sqlite3_prepare $DB $sql -1 TAIL] | ||
592 | sqlite3_column_count $STMT | ||
593 | } 3 | ||
594 | |||
595 | check_header $STMT capi3-5.31 {x y z} {VARINT {} {}} | ||
596 | check_origin_header $STMT capi3-5.32 {main {} {}} {t1 {} {}} {a {} {}} | ||
597 | do_test capi3-5.33 { | ||
598 | sqlite3_finalize $STMT | ||
599 | } SQLITE_OK | ||
600 | |||
601 | |||
602 | set ::ENC [execsql {pragma encoding}] | ||
603 | db close | ||
604 | |||
605 | do_test capi3-6.0 { | ||
606 | sqlite3 db test.db | ||
607 | set DB [sqlite3_connection_pointer db] | ||
608 | sqlite3_key $DB xyzzy | ||
609 | set sql {SELECT a FROM t1 order by rowid} | ||
610 | set STMT [sqlite3_prepare $DB $sql -1 TAIL] | ||
611 | expr 0 | ||
612 | } {0} | ||
613 | do_test capi3-6.1 { | ||
614 | db cache flush | ||
615 | sqlite3_close $DB | ||
616 | } {SQLITE_BUSY} | ||
617 | do_test capi3-6.2 { | ||
618 | sqlite3_step $STMT | ||
619 | } {SQLITE_ROW} | ||
620 | check_data $STMT capi3-6.3 {INTEGER} {1} {1.0} {1} | ||
621 | do_test capi3-6.3 { | ||
622 | sqlite3_finalize $STMT | ||
623 | } {SQLITE_OK} | ||
624 | do_test capi3-6.4-misuse { | ||
625 | db cache flush | ||
626 | sqlite3_close $DB | ||
627 | } {SQLITE_OK} | ||
628 | db close | ||
629 | |||
630 | if {![sqlite3 -has-codec]} { | ||
631 | # Test what happens when the library encounters a newer file format. | ||
632 | # Do this by updating the file format via the btree layer. | ||
633 | do_test capi3-7.1 { | ||
634 | set ::bt [btree_open test.db 10 0] | ||
635 | btree_begin_transaction $::bt | ||
636 | set meta [btree_get_meta $::bt] | ||
637 | lset meta 2 5 | ||
638 | eval [concat btree_update_meta $::bt [lrange $meta 0 end]] | ||
639 | btree_commit $::bt | ||
640 | btree_close $::bt | ||
641 | } {} | ||
642 | do_test capi3-7.2 { | ||
643 | sqlite3 db test.db | ||
644 | catchsql { | ||
645 | SELECT * FROM sqlite_master; | ||
646 | } | ||
647 | } {1 {unsupported file format}} | ||
648 | db close | ||
649 | } | ||
650 | |||
651 | if {![sqlite3 -has-codec]} { | ||
652 | # Now test that the library correctly handles bogus entries in the | ||
653 | # sqlite_master table (schema corruption). | ||
654 | do_test capi3-8.1 { | ||
655 | file delete -force test.db | ||
656 | file delete -force test.db-journal | ||
657 | sqlite3 db test.db | ||
658 | execsql { | ||
659 | CREATE TABLE t1(a); | ||
660 | } | ||
661 | db close | ||
662 | } {} | ||
663 | do_test capi3-8.2 { | ||
664 | set ::bt [btree_open test.db 10 0] | ||
665 | btree_begin_transaction $::bt | ||
666 | set ::bc [btree_cursor $::bt 1 1] | ||
667 | |||
668 | # Build a 5-field row record consisting of 5 null records. This is | ||
669 | # officially black magic. | ||
670 | catch {unset data} | ||
671 | set data [binary format c6 {6 0 0 0 0 0}] | ||
672 | btree_insert $::bc 5 $data | ||
673 | |||
674 | btree_close_cursor $::bc | ||
675 | btree_commit $::bt | ||
676 | btree_close $::bt | ||
677 | } {} | ||
678 | do_test capi3-8.3 { | ||
679 | sqlite3 db test.db | ||
680 | catchsql { | ||
681 | SELECT * FROM sqlite_master; | ||
682 | } | ||
683 | } {1 {malformed database schema}} | ||
684 | do_test capi3-8.4 { | ||
685 | set ::bt [btree_open test.db 10 0] | ||
686 | btree_begin_transaction $::bt | ||
687 | set ::bc [btree_cursor $::bt 1 1] | ||
688 | |||
689 | # Build a 5-field row record. The first field is a string 'table', and | ||
690 | # subsequent fields are all NULL. Replace the other broken record with | ||
691 | # this one and try to read the schema again. The broken record uses | ||
692 | # either UTF-8 or native UTF-16 (if this file is being run by | ||
693 | # utf16.test). | ||
694 | if { [string match UTF-16* $::ENC] } { | ||
695 | set data [binary format c6a10 {6 33 0 0 0 0} [utf16 table]] | ||
696 | } else { | ||
697 | set data [binary format c6a5 {6 23 0 0 0 0} table] | ||
698 | } | ||
699 | btree_insert $::bc 5 $data | ||
700 | |||
701 | btree_close_cursor $::bc | ||
702 | btree_commit $::bt | ||
703 | btree_close $::bt | ||
704 | } {}; | ||
705 | do_test capi3-8.5 { | ||
706 | db close | ||
707 | sqlite3 db test.db | ||
708 | catchsql { | ||
709 | SELECT * FROM sqlite_master; | ||
710 | } | ||
711 | } {1 {malformed database schema}} | ||
712 | db close | ||
713 | } | ||
714 | file delete -force test.db | ||
715 | file delete -force test.db-journal | ||
716 | |||
717 | |||
718 | # Test the english language string equivalents for sqlite error codes | ||
719 | set code2english [list \ | ||
720 | SQLITE_OK {not an error} \ | ||
721 | SQLITE_ERROR {SQL logic error or missing database} \ | ||
722 | SQLITE_PERM {access permission denied} \ | ||
723 | SQLITE_ABORT {callback requested query abort} \ | ||
724 | SQLITE_BUSY {database is locked} \ | ||
725 | SQLITE_LOCKED {database table is locked} \ | ||
726 | SQLITE_NOMEM {out of memory} \ | ||
727 | SQLITE_READONLY {attempt to write a readonly database} \ | ||
728 | SQLITE_INTERRUPT {interrupted} \ | ||
729 | SQLITE_IOERR {disk I/O error} \ | ||
730 | SQLITE_CORRUPT {database disk image is malformed} \ | ||
731 | SQLITE_FULL {database or disk is full} \ | ||
732 | SQLITE_CANTOPEN {unable to open database file} \ | ||
733 | SQLITE_EMPTY {table contains no data} \ | ||
734 | SQLITE_SCHEMA {database schema has changed} \ | ||
735 | SQLITE_CONSTRAINT {constraint failed} \ | ||
736 | SQLITE_MISMATCH {datatype mismatch} \ | ||
737 | SQLITE_MISUSE {library routine called out of sequence} \ | ||
738 | SQLITE_NOLFS {kernel lacks large file support} \ | ||
739 | SQLITE_AUTH {authorization denied} \ | ||
740 | SQLITE_FORMAT {auxiliary database format error} \ | ||
741 | SQLITE_RANGE {bind or column index out of range} \ | ||
742 | SQLITE_NOTADB {file is encrypted or is not a database} \ | ||
743 | unknownerror {unknown error} \ | ||
744 | ] | ||
745 | |||
746 | set test_number 1 | ||
747 | foreach {code english} $code2english { | ||
748 | do_test capi3-9.$test_number "sqlite3_test_errstr $code" $english | ||
749 | incr test_number | ||
750 | } | ||
751 | |||
752 | # Test the error message when a "real" out of memory occurs. | ||
753 | ifcapable memdebug { | ||
754 | do_test capi3-10-1 { | ||
755 | sqlite3 db test.db | ||
756 | set DB [sqlite3_connection_pointer db] | ||
757 | sqlite3_memdebug_fail 1 | ||
758 | catchsql { | ||
759 | select * from sqlite_master; | ||
760 | } | ||
761 | } {1 {out of memory}} | ||
762 | do_test capi3-10-2 { | ||
763 | sqlite3_errmsg $::DB | ||
764 | } {out of memory} | ||
765 | ifcapable {utf16} { | ||
766 | do_test capi3-10-3 { | ||
767 | utf8 [sqlite3_errmsg16 $::DB] | ||
768 | } {out of memory} | ||
769 | } | ||
770 | db close | ||
771 | sqlite3_memdebug_fail -1 | ||
772 | } | ||
773 | |||
774 | # The following tests - capi3-11.* - test that a COMMIT or ROLLBACK | ||
775 | # statement issued while there are still outstanding VMs that are part of | ||
776 | # the transaction fails. | ||
777 | sqlite3 db test.db | ||
778 | set DB [sqlite3_connection_pointer db] | ||
779 | sqlite_register_test_function $DB func | ||
780 | do_test capi3-11.1 { | ||
781 | execsql { | ||
782 | BEGIN; | ||
783 | CREATE TABLE t1(a, b); | ||
784 | INSERT INTO t1 VALUES(1, 'int'); | ||
785 | INSERT INTO t1 VALUES(2, 'notatype'); | ||
786 | } | ||
787 | } {} | ||
788 | do_test capi3-11.1.1 { | ||
789 | sqlite3_get_autocommit $DB | ||
790 | } 0 | ||
791 | do_test capi3-11.2 { | ||
792 | set STMT [sqlite3_prepare $DB "SELECT func(b, a) FROM t1" -1 TAIL] | ||
793 | sqlite3_step $STMT | ||
794 | } {SQLITE_ROW} | ||
795 | do_test capi3-11.3 { | ||
796 | catchsql { | ||
797 | COMMIT; | ||
798 | } | ||
799 | } {1 {cannot commit transaction - SQL statements in progress}} | ||
800 | do_test capi3-11.3.1 { | ||
801 | sqlite3_get_autocommit $DB | ||
802 | } 0 | ||
803 | do_test capi3-11.4 { | ||
804 | sqlite3_step $STMT | ||
805 | } {SQLITE_ERROR} | ||
806 | do_test capi3-11.5 { | ||
807 | sqlite3_finalize $STMT | ||
808 | } {SQLITE_ERROR} | ||
809 | do_test capi3-11.6 { | ||
810 | catchsql { | ||
811 | SELECT * FROM t1; | ||
812 | } | ||
813 | } {0 {1 int 2 notatype}} | ||
814 | do_test capi3-11.6.1 { | ||
815 | sqlite3_get_autocommit $DB | ||
816 | } 0 | ||
817 | do_test capi3-11.7 { | ||
818 | catchsql { | ||
819 | COMMIT; | ||
820 | } | ||
821 | } {0 {}} | ||
822 | do_test capi3-11.7.1 { | ||
823 | sqlite3_get_autocommit $DB | ||
824 | } 1 | ||
825 | do_test capi3-11.8 { | ||
826 | execsql { | ||
827 | CREATE TABLE t2(a); | ||
828 | INSERT INTO t2 VALUES(1); | ||
829 | INSERT INTO t2 VALUES(2); | ||
830 | BEGIN; | ||
831 | INSERT INTO t2 VALUES(3); | ||
832 | } | ||
833 | } {} | ||
834 | do_test capi3-11.8.1 { | ||
835 | sqlite3_get_autocommit $DB | ||
836 | } 0 | ||
837 | do_test capi3-11.9 { | ||
838 | set STMT [sqlite3_prepare $DB "SELECT a FROM t2" -1 TAIL] | ||
839 | sqlite3_step $STMT | ||
840 | } {SQLITE_ROW} | ||
841 | do_test capi3-11.9.1 { | ||
842 | sqlite3_get_autocommit $DB | ||
843 | } 0 | ||
844 | do_test capi3-11.9.2 { | ||
845 | catchsql { | ||
846 | ROLLBACK; | ||
847 | } | ||
848 | } {1 {cannot rollback transaction - SQL statements in progress}} | ||
849 | do_test capi3-11.9.3 { | ||
850 | sqlite3_get_autocommit $DB | ||
851 | } 0 | ||
852 | do_test capi3-11.10 { | ||
853 | sqlite3_step $STMT | ||
854 | } {SQLITE_ROW} | ||
855 | do_test capi3-11.11 { | ||
856 | sqlite3_step $STMT | ||
857 | } {SQLITE_ROW} | ||
858 | do_test capi3-11.12 { | ||
859 | sqlite3_step $STMT | ||
860 | } {SQLITE_DONE} | ||
861 | do_test capi3-11.13 { | ||
862 | sqlite3_finalize $STMT | ||
863 | } {SQLITE_OK} | ||
864 | do_test capi3-11.14 { | ||
865 | execsql { | ||
866 | SELECT a FROM t2; | ||
867 | } | ||
868 | } {1 2 3} | ||
869 | do_test capi3-11.14.1 { | ||
870 | sqlite3_get_autocommit $DB | ||
871 | } 0 | ||
872 | do_test capi3-11.15 { | ||
873 | catchsql { | ||
874 | ROLLBACK; | ||
875 | } | ||
876 | } {0 {}} | ||
877 | do_test capi3-11.15.1 { | ||
878 | sqlite3_get_autocommit $DB | ||
879 | } 1 | ||
880 | do_test capi3-11.16 { | ||
881 | execsql { | ||
882 | SELECT a FROM t2; | ||
883 | } | ||
884 | } {1 2} | ||
885 | |||
886 | # Sanity check on the definition of 'outstanding VM'. This means any VM | ||
887 | # that has had sqlite3_step() called more recently than sqlite3_finalize() or | ||
888 | # sqlite3_reset(). So a VM that has just been prepared or reset does not | ||
889 | # count as an active VM. | ||
890 | do_test capi3-11.17 { | ||
891 | execsql { | ||
892 | BEGIN; | ||
893 | } | ||
894 | } {} | ||
895 | do_test capi3-11.18 { | ||
896 | set STMT [sqlite3_prepare $DB "SELECT a FROM t1" -1 TAIL] | ||
897 | catchsql { | ||
898 | COMMIT; | ||
899 | } | ||
900 | } {0 {}} | ||
901 | do_test capi3-11.19 { | ||
902 | sqlite3_step $STMT | ||
903 | } {SQLITE_ROW} | ||
904 | do_test capi3-11.20 { | ||
905 | catchsql { | ||
906 | BEGIN; | ||
907 | COMMIT; | ||
908 | } | ||
909 | } {1 {cannot commit transaction - SQL statements in progress}} | ||
910 | do_test capi3-11.20 { | ||
911 | sqlite3_reset $STMT | ||
912 | catchsql { | ||
913 | COMMIT; | ||
914 | } | ||
915 | } {0 {}} | ||
916 | do_test capi3-11.21 { | ||
917 | sqlite3_finalize $STMT | ||
918 | } {SQLITE_OK} | ||
919 | |||
920 | # The following tests - capi3-12.* - check that it's Ok to start a | ||
921 | # transaction while other VMs are active, and that it's Ok to execute | ||
922 | # atomic updates in the same situation | ||
923 | # | ||
924 | do_test capi3-12.1 { | ||
925 | set STMT [sqlite3_prepare $DB "SELECT a FROM t2" -1 TAIL] | ||
926 | sqlite3_step $STMT | ||
927 | } {SQLITE_ROW} | ||
928 | do_test capi3-12.2 { | ||
929 | catchsql { | ||
930 | INSERT INTO t1 VALUES(3, NULL); | ||
931 | } | ||
932 | } {0 {}} | ||
933 | do_test capi3-12.3 { | ||
934 | catchsql { | ||
935 | INSERT INTO t2 VALUES(4); | ||
936 | } | ||
937 | } {0 {}} | ||
938 | do_test capi3-12.4 { | ||
939 | catchsql { | ||
940 | BEGIN; | ||
941 | INSERT INTO t1 VALUES(4, NULL); | ||
942 | } | ||
943 | } {0 {}} | ||
944 | do_test capi3-12.5 { | ||
945 | sqlite3_step $STMT | ||
946 | } {SQLITE_ROW} | ||
947 | do_test capi3-12.5.1 { | ||
948 | sqlite3_step $STMT | ||
949 | } {SQLITE_ROW} | ||
950 | do_test capi3-12.6 { | ||
951 | sqlite3_step $STMT | ||
952 | } {SQLITE_DONE} | ||
953 | do_test capi3-12.7 { | ||
954 | sqlite3_finalize $STMT | ||
955 | } {SQLITE_OK} | ||
956 | do_test capi3-12.8 { | ||
957 | execsql { | ||
958 | COMMIT; | ||
959 | SELECT a FROM t1; | ||
960 | } | ||
961 | } {1 2 3 4} | ||
962 | |||
963 | # Test cases capi3-13.* test the sqlite3_clear_bindings() and | ||
964 | # sqlite3_sleep APIs. | ||
965 | # | ||
966 | if {[llength [info commands sqlite3_clear_bindings]]>0} { | ||
967 | do_test capi3-13.1 { | ||
968 | execsql { | ||
969 | DELETE FROM t1; | ||
970 | } | ||
971 | set STMT [sqlite3_prepare $DB "INSERT INTO t1 VALUES(?, ?)" -1 TAIL] | ||
972 | sqlite3_step $STMT | ||
973 | } {SQLITE_DONE} | ||
974 | do_test capi3-13.2 { | ||
975 | sqlite3_reset $STMT | ||
976 | sqlite3_bind_text $STMT 1 hello 5 | ||
977 | sqlite3_bind_text $STMT 2 world 5 | ||
978 | sqlite3_step $STMT | ||
979 | } {SQLITE_DONE} | ||
980 | do_test capi3-13.3 { | ||
981 | sqlite3_reset $STMT | ||
982 | sqlite3_clear_bindings $STMT | ||
983 | sqlite3_step $STMT | ||
984 | } {SQLITE_DONE} | ||
985 | do_test capi3-13-4 { | ||
986 | sqlite3_finalize $STMT | ||
987 | execsql { | ||
988 | SELECT * FROM t1; | ||
989 | } | ||
990 | } {{} {} hello world {} {}} | ||
991 | } | ||
992 | if {[llength [info commands sqlite3_sleep]]>0} { | ||
993 | do_test capi3-13-5 { | ||
994 | set ms [sqlite3_sleep 80] | ||
995 | expr {$ms==80 || $ms==1000} | ||
996 | } {1} | ||
997 | } | ||
998 | |||
999 | # Ticket #1219: Make sure binding APIs can handle a NULL pointer. | ||
1000 | # | ||
1001 | do_test capi3-14.1-misuse { | ||
1002 | set rc [catch {sqlite3_bind_text 0 1 hello 5} msg] | ||
1003 | lappend rc $msg | ||
1004 | } {1 SQLITE_MISUSE} | ||
1005 | |||
1006 | # Ticket #1650: Honor the nBytes parameter to sqlite3_prepare. | ||
1007 | # | ||
1008 | do_test capi3-15.1 { | ||
1009 | set sql {SELECT * FROM t2} | ||
1010 | set nbytes [string length $sql] | ||
1011 | append sql { WHERE a==1} | ||
1012 | set STMT [sqlite3_prepare $DB $sql $nbytes TAIL] | ||
1013 | sqlite3_step $STMT | ||
1014 | sqlite3_column_int $STMT 0 | ||
1015 | } {1} | ||
1016 | do_test capi3-15.2 { | ||
1017 | sqlite3_step $STMT | ||
1018 | sqlite3_column_int $STMT 0 | ||
1019 | } {2} | ||
1020 | do_test capi3-15.3 { | ||
1021 | sqlite3_finalize $STMT | ||
1022 | } {SQLITE_OK} | ||
1023 | |||
1024 | # Make sure code is always generated even if an IF EXISTS or | ||
1025 | # IF NOT EXISTS clause is present that the table does not or | ||
1026 | # does exists. That way we will always have a prepared statement | ||
1027 | # to expire when the schema changes. | ||
1028 | # | ||
1029 | do_test capi3-16.1 { | ||
1030 | set sql {DROP TABLE IF EXISTS t3} | ||
1031 | set STMT [sqlite3_prepare $DB $sql -1 TAIL] | ||
1032 | sqlite3_finalize $STMT | ||
1033 | expr {$STMT!=""} | ||
1034 | } {1} | ||
1035 | do_test capi3-16.2 { | ||
1036 | set sql {CREATE TABLE IF NOT EXISTS t1(x,y)} | ||
1037 | set STMT [sqlite3_prepare $DB $sql -1 TAIL] | ||
1038 | sqlite3_finalize $STMT | ||
1039 | expr {$STMT!=""} | ||
1040 | } {1} | ||
1041 | |||
1042 | # But still we do not generate code if there is no SQL | ||
1043 | # | ||
1044 | do_test capi3-16.3 { | ||
1045 | set STMT [sqlite3_prepare $DB {} -1 TAIL] | ||
1046 | sqlite3_finalize $STMT | ||
1047 | expr {$STMT==""} | ||
1048 | } {1} | ||
1049 | do_test capi3-16.4 { | ||
1050 | set STMT [sqlite3_prepare $DB {;} -1 TAIL] | ||
1051 | sqlite3_finalize $STMT | ||
1052 | expr {$STMT==""} | ||
1053 | } {1} | ||
1054 | |||
1055 | # Ticket #2426: Misuse of sqlite3_column_* by calling it after | ||
1056 | # a sqlite3_reset should be harmless. | ||
1057 | # | ||
1058 | do_test capi3-17.1 { | ||
1059 | set STMT [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL] | ||
1060 | sqlite3_step $STMT | ||
1061 | sqlite3_column_int $STMT 0 | ||
1062 | } {1} | ||
1063 | do_test capi3-17.2 { | ||
1064 | sqlite3_reset $STMT | ||
1065 | sqlite3_column_int $STMT 0 | ||
1066 | } {0} | ||
1067 | do_test capi3-17.3 { | ||
1068 | sqlite3_finalize $STMT | ||
1069 | } {SQLITE_OK} | ||
1070 | |||
1071 | finish_test | ||