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 TCL interface to the
14 # Actually, all tests are based on the TCL interface, so the main
15 # interface is pretty well tested. This file contains some addition
16 # tests for fringe issues that the main test suite does not cover.
18 # $Id: tclsqlite.test,v 1.40 2005/05/05 10:30:30 drh Exp $
20 set testdir [file dirname $argv0]
21 source $testdir/tester.tcl
23 # Check the error messages generated by tclsqlite
25 if {[sqlite3 -has-codec]} {
26 set r "sqlite_orig HANDLE FILENAME ?-key CODEC-KEY?"
28 set r "sqlite3 HANDLE FILENAME ?MODE?"
31 set v [catch {sqlite3 bogus} msg]
33 } [list 1 "wrong # args: should be \"$r\""]
35 set v [catch {db bogus} msg]
37 } {1 {bad option "bogus": must be authorizer, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, errorcode, eval, function, last_insert_rowid, nullvalue, onecolumn, progress, rekey, timeout, total_changes, trace, or version}}
39 execsql {CREATE TABLE t1(a int, b int)}
40 execsql {INSERT INTO t1 VALUES(10,20)}
42 db eval {SELECT * FROM t1} data {
43 error "The error message"
47 } {1 {The error message}}
50 db eval {SELECT * FROM t2} data {
51 error "The error message"
55 } {1 {no such table: t2}}
58 db eval {SELECT * FROM t1} data {
66 db eval {SELECT * FROM t1} data {
70 regsub {:.*$} $msg {} msg
72 } {1 {syntax error in expression "x*"}}
74 set v [catch {db} msg]
76 } {1 {wrong # args: should be "db SUBCOMMAND ..."}}
77 if {[catch {db auth {}}]==0} {
79 set v [catch {db authorizer 1 2 3} msg]
81 } {1 {wrong # args: should be "db authorizer ?CALLBACK?"}}
84 set v [catch {db busy 1 2 3} msg]
86 } {1 {wrong # args: should be "db busy CALLBACK"}}
88 set v [catch {db progress 1} msg]
90 } {1 {wrong # args: should be "db progress N CALLBACK"}}
92 set v [catch {db changes xyz} msg]
94 } {1 {wrong # args: should be "db changes "}}
96 set v [catch {db commit_hook a b c} msg]
98 } {1 {wrong # args: should be "db commit_hook ?CALLBACK?"}}
99 ifcapable {complete} {
101 set v [catch {db complete} msg]
103 } {1 {wrong # args: should be "db complete SQL"}}
106 set v [catch {db eval} msg]
108 } {1 {wrong # args: should be "db eval SQL ?ARRAY-NAME? ?SCRIPT?"}}
110 set v [catch {db function} msg]
112 } {1 {wrong # args: should be "db function NAME SCRIPT"}}
114 set v [catch {db last_insert_rowid xyz} msg]
116 } {1 {wrong # args: should be "db last_insert_rowid "}}
118 set v [catch {db rekey} msg]
120 } {1 {wrong # args: should be "db rekey KEY"}}
122 set v [catch {db timeout} msg]
124 } {1 {wrong # args: should be "db timeout MILLISECONDS"}}
126 set v [catch {db collate} msg]
128 } {1 {wrong # args: should be "db collate NAME SCRIPT"}}
130 set v [catch {db collation_needed} msg]
132 } {1 {wrong # args: should be "db collation_needed SCRIPT"}}
134 set v [catch {db total_changes xyz} msg]
136 } {1 {wrong # args: should be "db total_changes "}}
138 set v [catch {db copy} msg]
140 } {1 {wrong # args: should be "db copy CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"}}
143 if {[sqlite3 -tcl-uses-utf]} {
144 catch {unset ::result}
146 execsql "CREATE TABLE t\u0123x(a int, b\u1235 float)"
148 ifcapable schema_pragmas {
150 execsql "PRAGMA table_info(t\u0123x)"
151 } "0 a int 0 {} 0 1 b\u1235 float 0 {} 0"
154 execsql "INSERT INTO t\u0123x VALUES(1,2.3)"
155 db eval "SELECT * FROM t\u0123x" result break
161 # Test the onecolumn method
165 INSERT INTO t1 SELECT a*2, b*2 FROM t1;
166 INSERT INTO t1 SELECT a*2+1, b*2+1 FROM t1;
167 INSERT INTO t1 SELECT a*2+3, b*2+3 FROM t1;
169 set rc [catch {db onecolumn {SELECT * FROM t1 ORDER BY a}} msg]
173 db onecolumn {SELECT * FROM t1 WHERE a<0}
176 set rc [catch {db onecolumn} errmsg]
178 } {1 {wrong # args: should be "db onecolumn SQL"}}
180 set rc [catch {db onecolumn {SELECT bogus}} errmsg]
182 } {1 {no such column: bogus}}
186 set rc [catch {db one {SELECT * FROM t1 WHERE b>$b}} msg]
191 set rc [catch {db one {SELECT * FROM t1 WHERE b>$b}} msg]
196 set rc [catch {db one {
197 INSERT INTO t1 VALUES(99,510);
198 SELECT * FROM t1 WHERE b>$b
203 ifcapable {!tclvar} {
204 execsql {INSERT INTO t1 VALUES(99,510)}
207 # Turn the busy handler on and off
210 proc busy_callback {cnt} {
213 db busy busy_callback
222 # Parsing of TCL variable names within SQL into bound parameters.
225 execsql {CREATE TABLE t3(a,b,c)}
230 INSERT INTO t3 VALUES($::x(1),$::x(2),$::x(3));
236 SELECT typeof(a), typeof(b), typeof(c) FROM t3
241 set x [binary format h12 686900686f00]
243 UPDATE t3 SET a=$::x;
248 binary scan $a h12 adata
253 SELECT typeof(a), typeof(b), typeof(c) FROM t3
258 # Operation of "break" and "continue" within row scripts
261 db eval {SELECT * FROM t1} {
268 db eval {SELECT * FROM t1} {
276 db eval {SELECT * FROM t1} {
283 proc return_test {x} {
284 db eval {SELECT * FROM t1} {
285 if {$a==$x} {return $b}
305 # modify and reset the NULL representation
309 execsql {INSERT INTO t1 VALUES(30,NULL)}
310 db eval {SELECT * FROM t1 WHERE b IS NULL}
318 db eval {SELECT * FROM t1 WHERE b IS NULL}
321 # Test the return type of user-defined functions
324 db function ret_str {return "hi"}
325 execsql {SELECT typeof(ret_str())}
328 db function ret_dbl {return [expr {[clock seconds]*0.5}]}
329 execsql {SELECT typeof(ret_dbl())}
332 db function ret_int {clock seconds}
333 execsql {SELECT typeof(ret_int())}