1b19a2bc6Sdrh# 2001 September 15 2960e8c63Sdrh# 3b19a2bc6Sdrh# The author disclaims copyright to this source code. In place of 4b19a2bc6Sdrh# a legal notice, here is a blessing: 5960e8c63Sdrh# 6b19a2bc6Sdrh# May you do good and not evil. 7b19a2bc6Sdrh# May you find forgiveness for yourself and forgive others. 8b19a2bc6Sdrh# May you share freely, never taking more than you give. 9960e8c63Sdrh# 10960e8c63Sdrh#*********************************************************************** 11960e8c63Sdrh# This file implements regression tests for TCL interface to the 12960e8c63Sdrh# SQLite library. 13960e8c63Sdrh# 14960e8c63Sdrh# Actually, all tests are based on the TCL interface, so the main 15960e8c63Sdrh# interface is pretty well tested. This file contains some addition 16960e8c63Sdrh# tests for fringe issues that the main test suite does not cover. 17960e8c63Sdrh# 18404ca075Sdanielk1977# $Id: tclsqlite.test,v 1.73 2009/03/16 13:19:36 danielk1977 Exp $ 19960e8c63Sdrh 20c6727c83Sdrhcatch {sqlite3} 21c6727c83Sdrh 22960e8c63Sdrhset testdir [file dirname $argv0] 23960e8c63Sdrhsource $testdir/tester.tcl 2489d24936Sdanset testprefix tcl 25960e8c63Sdrh 26960e8c63Sdrh# Check the error messages generated by tclsqlite 27960e8c63Sdrh# 280933aad7Sdrhset r "sqlite_orig HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nofollow BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" 297da56b4fSdrhif {[sqlite3 -has-codec]} { 307da56b4fSdrh append r " ?-key CODECKEY?" 3122fbcb8dSdrh} 32960e8c63Sdrhdo_test tcl-1.1 { 334dcac40eSdrh set v [catch {sqlite3 -bogus} msg] 34df81a25aSdrh regsub {really_sqlite3} $msg {sqlite3} msg 35960e8c63Sdrh lappend v $msg 3622fbcb8dSdrh} [list 1 "wrong # args: should be \"$r\""] 37c6727c83Sdrhdo_test tcl-1.1.1 { 38c6727c83Sdrh set v [catch {sqlite3} msg] 39c6727c83Sdrh regsub {really_sqlite3} $msg {sqlite3} msg 40c6727c83Sdrh lappend v $msg 41c6727c83Sdrh} [list 1 "wrong # args: should be \"$r\""] 42960e8c63Sdrhdo_test tcl-1.2 { 43960e8c63Sdrh set v [catch {db bogus} msg] 44960e8c63Sdrh lappend v $msg 45*be4e3c88Sdrh} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, config, copy, deserialize, enable_load_extension, errorcode, erroroffset, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}} 46191fadcfSdanielk1977do_test tcl-1.2.1 { 47191fadcfSdanielk1977 set v [catch {db cache bogus} msg] 48191fadcfSdanielk1977 lappend v $msg 49191fadcfSdanielk1977} {1 {bad option "bogus": must be flush or size}} 50191fadcfSdanielk1977do_test tcl-1.2.2 { 51191fadcfSdanielk1977 set v [catch {db cache} msg] 52191fadcfSdanielk1977 lappend v $msg 53191fadcfSdanielk1977} {1 {wrong # args: should be "db cache option ?arg?"}} 54960e8c63Sdrhdo_test tcl-1.3 { 55960e8c63Sdrh execsql {CREATE TABLE t1(a int, b int)} 56960e8c63Sdrh execsql {INSERT INTO t1 VALUES(10,20)} 57960e8c63Sdrh set v [catch { 58960e8c63Sdrh db eval {SELECT * FROM t1} data { 59960e8c63Sdrh error "The error message" 60960e8c63Sdrh } 61960e8c63Sdrh } msg] 62960e8c63Sdrh lappend v $msg 63960e8c63Sdrh} {1 {The error message}} 64960e8c63Sdrhdo_test tcl-1.4 { 65960e8c63Sdrh set v [catch { 66960e8c63Sdrh db eval {SELECT * FROM t2} data { 67960e8c63Sdrh error "The error message" 68960e8c63Sdrh } 69960e8c63Sdrh } msg] 70960e8c63Sdrh lappend v $msg 71960e8c63Sdrh} {1 {no such table: t2}} 72960e8c63Sdrhdo_test tcl-1.5 { 73960e8c63Sdrh set v [catch { 74960e8c63Sdrh db eval {SELECT * FROM t1} data { 75960e8c63Sdrh break 76960e8c63Sdrh } 77960e8c63Sdrh } msg] 78960e8c63Sdrh lappend v $msg 79960e8c63Sdrh} {0 {}} 80d65e530bSdrhcatch {expr x*} msg 81960e8c63Sdrhdo_test tcl-1.6 { 82960e8c63Sdrh set v [catch { 83960e8c63Sdrh db eval {SELECT * FROM t1} data { 84960e8c63Sdrh expr x* 85960e8c63Sdrh } 86960e8c63Sdrh } msg] 87960e8c63Sdrh lappend v $msg 88d65e530bSdrh} [list 1 $msg] 890f14e2ebSdrhdo_test tcl-1.7 { 900f14e2ebSdrh set v [catch {db} msg] 910f14e2ebSdrh lappend v $msg 920f14e2ebSdrh} {1 {wrong # args: should be "db SUBCOMMAND ..."}} 931211de37Sdrhif {[catch {db auth {}}]==0} { 940f14e2ebSdrh do_test tcl-1.8 { 950f14e2ebSdrh set v [catch {db authorizer 1 2 3} msg] 960f14e2ebSdrh lappend v $msg 970f14e2ebSdrh } {1 {wrong # args: should be "db authorizer ?CALLBACK?"}} 981211de37Sdrh} 990f14e2ebSdrhdo_test tcl-1.9 { 1000f14e2ebSdrh set v [catch {db busy 1 2 3} msg] 1010f14e2ebSdrh lappend v $msg 1020f14e2ebSdrh} {1 {wrong # args: should be "db busy CALLBACK"}} 1030f14e2ebSdrhdo_test tcl-1.10 { 1040f14e2ebSdrh set v [catch {db progress 1} msg] 1050f14e2ebSdrh lappend v $msg 1060f14e2ebSdrh} {1 {wrong # args: should be "db progress N CALLBACK"}} 1070f14e2ebSdrhdo_test tcl-1.11 { 1080f14e2ebSdrh set v [catch {db changes xyz} msg] 1090f14e2ebSdrh lappend v $msg 1100f14e2ebSdrh} {1 {wrong # args: should be "db changes "}} 1110f14e2ebSdrhdo_test tcl-1.12 { 1120f14e2ebSdrh set v [catch {db commit_hook a b c} msg] 1130f14e2ebSdrh lappend v $msg 1140f14e2ebSdrh} {1 {wrong # args: should be "db commit_hook ?CALLBACK?"}} 115ccae6026Sdrhifcapable {complete} { 1160f14e2ebSdrh do_test tcl-1.13 { 1170f14e2ebSdrh set v [catch {db complete} msg] 1180f14e2ebSdrh lappend v $msg 1190f14e2ebSdrh } {1 {wrong # args: should be "db complete SQL"}} 120ccae6026Sdrh} 1210f14e2ebSdrhdo_test tcl-1.14 { 1220f14e2ebSdrh set v [catch {db eval} msg] 1230f14e2ebSdrh lappend v $msg 124af38cdbcSdrh} {1 {wrong # args: should be "db eval ?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?"}} 1250f14e2ebSdrhdo_test tcl-1.15 { 1260f14e2ebSdrh set v [catch {db function} msg] 1270f14e2ebSdrh lappend v $msg 1283df30592Sdan} {1 {wrong # args: should be "db function NAME ?SWITCHES? SCRIPT"}} 1297ddad969Sdanielk1977do_test tcl-1.16 { 1300f14e2ebSdrh set v [catch {db last_insert_rowid xyz} msg] 1310f14e2ebSdrh lappend v $msg 1320f14e2ebSdrh} {1 {wrong # args: should be "db last_insert_rowid "}} 1337ddad969Sdanielk1977do_test tcl-1.17 { 1340f14e2ebSdrh set v [catch {db rekey} msg] 1350f14e2ebSdrh lappend v $msg 1360f14e2ebSdrh} {1 {wrong # args: should be "db rekey KEY"}} 1377ddad969Sdanielk1977do_test tcl-1.18 { 1380f14e2ebSdrh set v [catch {db timeout} msg] 1390f14e2ebSdrh lappend v $msg 1400f14e2ebSdrh} {1 {wrong # args: should be "db timeout MILLISECONDS"}} 1417ddad969Sdanielk1977do_test tcl-1.19 { 1420f14e2ebSdrh set v [catch {db collate} msg] 1430f14e2ebSdrh lappend v $msg 1440f14e2ebSdrh} {1 {wrong # args: should be "db collate NAME SCRIPT"}} 1457ddad969Sdanielk1977do_test tcl-1.20 { 1460f14e2ebSdrh set v [catch {db collation_needed} msg] 1470f14e2ebSdrh lappend v $msg 1480f14e2ebSdrh} {1 {wrong # args: should be "db collation_needed SCRIPT"}} 1497ddad969Sdanielk1977do_test tcl-1.21 { 1500f14e2ebSdrh set v [catch {db total_changes xyz} msg] 1510f14e2ebSdrh lappend v $msg 1520f14e2ebSdrh} {1 {wrong # args: should be "db total_changes "}} 1531c9ee268Smistachkindo_test tcl-1.22 { 1541067fe11Stpoindex set v [catch {db copy} msg] 1551067fe11Stpoindex lappend v $msg 1561067fe11Stpoindex} {1 {wrong # args: should be "db copy CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"}} 1571c9ee268Smistachkindo_test tcl-1.23 { 15895c8a54cSdanielk1977 set v [catch {sqlite3 db2 test.db -vfs nosuchvfs} msg] 15995c8a54cSdanielk1977 lappend v $msg 16095c8a54cSdanielk1977} {1 {no such vfs: nosuchvfs}} 161960e8c63Sdrh 162c275b4eaSdrhcatch {unset ::result} 1636d4abfbeSdrhdo_test tcl-2.1 { 1646d4abfbeSdrh execsql "CREATE TABLE t\u0123x(a int, b\u1235 float)" 16527188fb5Sdanielk1977} {} 16627188fb5Sdanielk1977ifcapable schema_pragmas { 16727188fb5Sdanielk1977 do_test tcl-2.2 { 1686d4abfbeSdrh execsql "PRAGMA table_info(t\u0123x)" 169c2df4d6aSdrh } "0 a INT 0 {} 0 1 b\u1235 float 0 {} 0" 17027188fb5Sdanielk1977} 17127188fb5Sdanielk1977do_test tcl-2.3 { 1726d4abfbeSdrh execsql "INSERT INTO t\u0123x VALUES(1,2.3)" 1736d4abfbeSdrh db eval "SELECT * FROM t\u0123x" result break 1746d4abfbeSdrh set result(*) 1756d4abfbeSdrh} "a b\u1235" 1766d4abfbeSdrh 1776d4abfbeSdrh 1785d9d7576Sdrh# Test the onecolumn method 1795d9d7576Sdrh# 1805d9d7576Sdrhdo_test tcl-3.1 { 1815d9d7576Sdrh execsql { 1825d9d7576Sdrh INSERT INTO t1 SELECT a*2, b*2 FROM t1; 1835d9d7576Sdrh INSERT INTO t1 SELECT a*2+1, b*2+1 FROM t1; 1845d9d7576Sdrh INSERT INTO t1 SELECT a*2+3, b*2+3 FROM t1; 1855d9d7576Sdrh } 18622fbcb8dSdrh set rc [catch {db onecolumn {SELECT * FROM t1 ORDER BY a}} msg] 18722fbcb8dSdrh lappend rc $msg 18822fbcb8dSdrh} {0 10} 1895d9d7576Sdrhdo_test tcl-3.2 { 1905d9d7576Sdrh db onecolumn {SELECT * FROM t1 WHERE a<0} 1915d9d7576Sdrh} {} 1925d9d7576Sdrhdo_test tcl-3.3 { 1935d9d7576Sdrh set rc [catch {db onecolumn} errmsg] 1945d9d7576Sdrh lappend rc $errmsg 1955d9d7576Sdrh} {1 {wrong # args: should be "db onecolumn SQL"}} 1960f14e2ebSdrhdo_test tcl-3.4 { 1970f14e2ebSdrh set rc [catch {db onecolumn {SELECT bogus}} errmsg] 1980f14e2ebSdrh lappend rc $errmsg 1990f14e2ebSdrh} {1 {no such column: bogus}} 2006bf89570Sdrhifcapable {tclvar} { 2011807ce37Sdrh do_test tcl-3.5 { 2021807ce37Sdrh set b 50 2031807ce37Sdrh set rc [catch {db one {SELECT * FROM t1 WHERE b>$b}} msg] 2041807ce37Sdrh lappend rc $msg 2051807ce37Sdrh } {0 41} 2061807ce37Sdrh do_test tcl-3.6 { 2071807ce37Sdrh set b 500 2081807ce37Sdrh set rc [catch {db one {SELECT * FROM t1 WHERE b>$b}} msg] 2091807ce37Sdrh lappend rc $msg 2101807ce37Sdrh } {0 {}} 2111807ce37Sdrh do_test tcl-3.7 { 2121807ce37Sdrh set b 500 2131807ce37Sdrh set rc [catch {db one { 2141807ce37Sdrh INSERT INTO t1 VALUES(99,510); 2151807ce37Sdrh SELECT * FROM t1 WHERE b>$b 2161807ce37Sdrh }} msg] 2171807ce37Sdrh lappend rc $msg 2181807ce37Sdrh } {0 99} 2196bf89570Sdrh} 2206bf89570Sdrhifcapable {!tclvar} { 2216bf89570Sdrh execsql {INSERT INTO t1 VALUES(99,510)} 2226bf89570Sdrh} 2235d9d7576Sdrh 2240f14e2ebSdrh# Turn the busy handler on and off 2250f14e2ebSdrh# 2260f14e2ebSdrhdo_test tcl-4.1 { 2270f14e2ebSdrh proc busy_callback {cnt} { 2280f14e2ebSdrh break 2290f14e2ebSdrh } 2300f14e2ebSdrh db busy busy_callback 2310f14e2ebSdrh db busy 2320f14e2ebSdrh} {busy_callback} 2330f14e2ebSdrhdo_test tcl-4.2 { 2340f14e2ebSdrh db busy {} 2350f14e2ebSdrh db busy 2360f14e2ebSdrh} {} 2376d4abfbeSdrh 2386bf89570Sdrhifcapable {tclvar} { 23992febd92Sdrh # Parsing of TCL variable names within SQL into bound parameters. 24092febd92Sdrh # 24192febd92Sdrh do_test tcl-5.1 { 24292febd92Sdrh execsql {CREATE TABLE t3(a,b,c)} 24392febd92Sdrh catch {unset x} 2447a1d17f1Sdanielk1977 set x(1) A 2457a1d17f1Sdanielk1977 set x(2) B 24692febd92Sdrh execsql { 24792febd92Sdrh INSERT INTO t3 VALUES($::x(1),$::x(2),$::x(3)); 24892febd92Sdrh SELECT * FROM t3 24992febd92Sdrh } 2507a1d17f1Sdanielk1977 } {A B {}} 25192febd92Sdrh do_test tcl-5.2 { 25292febd92Sdrh execsql { 25392febd92Sdrh SELECT typeof(a), typeof(b), typeof(c) FROM t3 25492febd92Sdrh } 25592febd92Sdrh } {text text null} 25692febd92Sdrh do_test tcl-5.3 { 25792febd92Sdrh catch {unset x} 25892febd92Sdrh set x [binary format h12 686900686f00] 25992febd92Sdrh execsql { 26092febd92Sdrh UPDATE t3 SET a=$::x; 26192febd92Sdrh } 26292febd92Sdrh db eval { 26392febd92Sdrh SELECT a FROM t3 26492febd92Sdrh } break 26592febd92Sdrh binary scan $a h12 adata 26692febd92Sdrh set adata 26792febd92Sdrh } {686900686f00} 26892febd92Sdrh do_test tcl-5.4 { 26992febd92Sdrh execsql { 27092febd92Sdrh SELECT typeof(a), typeof(b), typeof(c) FROM t3 27192febd92Sdrh } 27292febd92Sdrh } {blob text null} 2736bf89570Sdrh} 27492febd92Sdrh 275fd241b0eSdrh# Operation of "break" and "continue" within row scripts 276fd241b0eSdrh# 277fd241b0eSdrhdo_test tcl-6.1 { 278fd241b0eSdrh db eval {SELECT * FROM t1} { 279fd241b0eSdrh break 280fd241b0eSdrh } 281fd241b0eSdrh lappend a $b 282fd241b0eSdrh} {10 20} 283fd241b0eSdrhdo_test tcl-6.2 { 284fd241b0eSdrh set cnt 0 285fd241b0eSdrh db eval {SELECT * FROM t1} { 286fd241b0eSdrh if {$a>40} continue 287fd241b0eSdrh incr cnt 288fd241b0eSdrh } 289fd241b0eSdrh set cnt 290fd241b0eSdrh} {4} 291fd241b0eSdrhdo_test tcl-6.3 { 292fd241b0eSdrh set cnt 0 293fd241b0eSdrh db eval {SELECT * FROM t1} { 294fd241b0eSdrh if {$a<40} continue 295fd241b0eSdrh incr cnt 296fd241b0eSdrh } 297fd241b0eSdrh set cnt 298fd241b0eSdrh} {5} 299fd241b0eSdrhdo_test tcl-6.4 { 300fd241b0eSdrh proc return_test {x} { 301fd241b0eSdrh db eval {SELECT * FROM t1} { 302fd241b0eSdrh if {$a==$x} {return $b} 303fd241b0eSdrh } 304fd241b0eSdrh } 305fd241b0eSdrh return_test 10 306fd241b0eSdrh} 20 307fd241b0eSdrhdo_test tcl-6.5 { 308fd241b0eSdrh return_test 20 309fd241b0eSdrh} 40 310fd241b0eSdrhdo_test tcl-6.6 { 311fd241b0eSdrh return_test 99 312fd241b0eSdrh} 510 313fd241b0eSdrhdo_test tcl-6.7 { 314fd241b0eSdrh return_test 0 315fd241b0eSdrh} {} 316fd241b0eSdrh 3174397de57Sdanielk1977do_test tcl-7.1 { 3184397de57Sdanielk1977 db version 3194397de57Sdanielk1977 expr 0 3204397de57Sdanielk1977} {0} 3214397de57Sdanielk1977 32255c45f2eSdanielk1977# modify and reset the NULL representation 32355c45f2eSdanielk1977# 32455c45f2eSdanielk1977do_test tcl-8.1 { 32555c45f2eSdanielk1977 db nullvalue NaN 32655c45f2eSdanielk1977 execsql {INSERT INTO t1 VALUES(30,NULL)} 32755c45f2eSdanielk1977 db eval {SELECT * FROM t1 WHERE b IS NULL} 32855c45f2eSdanielk1977} {30 NaN} 329c45e6716Sdrhproc concatFunc args {return [join $args {}]} 33055c45f2eSdanielk1977do_test tcl-8.2 { 331c45e6716Sdrh db function concat concatFunc 332c45e6716Sdrh db eval {SELECT concat('a', b, 'z') FROM t1 WHERE b is NULL} 333c45e6716Sdrh} {aNaNz} 334c45e6716Sdrhdo_test tcl-8.3 { 33555c45f2eSdanielk1977 db nullvalue NULL 33655c45f2eSdanielk1977 db nullvalue 33755c45f2eSdanielk1977} {NULL} 338c45e6716Sdrhdo_test tcl-8.4 { 33955c45f2eSdanielk1977 db nullvalue {} 34055c45f2eSdanielk1977 db eval {SELECT * FROM t1 WHERE b IS NULL} 34155c45f2eSdanielk1977} {30 {}} 342c45e6716Sdrhdo_test tcl-8.5 { 343c45e6716Sdrh db function concat concatFunc 344c45e6716Sdrh db eval {SELECT concat('a', b, 'z') FROM t1 WHERE b is NULL} 345c45e6716Sdrh} {az} 34655c45f2eSdanielk1977 347c7f269d5Sdrh# Test the return type of user-defined functions 348c7f269d5Sdrh# 349c7f269d5Sdrhdo_test tcl-9.1 { 350c7f269d5Sdrh db function ret_str {return "hi"} 351c7f269d5Sdrh execsql {SELECT typeof(ret_str())} 352c7f269d5Sdrh} {text} 353c7f269d5Sdrhdo_test tcl-9.2 { 3549645d8d4Sdrh db function ret_dbl {return [expr {rand()*0.5}]} 355c7f269d5Sdrh execsql {SELECT typeof(ret_dbl())} 356c7f269d5Sdrh} {real} 357c7f269d5Sdrhdo_test tcl-9.3 { 3589645d8d4Sdrh db function ret_int {return [expr {int(rand()*200)}]} 359c7f269d5Sdrh execsql {SELECT typeof(ret_int())} 360c7f269d5Sdrh} {integer} 361c7f269d5Sdrh 362d1e4733dSdrh# Recursive calls to the same user-defined function 363d1e4733dSdrh# 3643bdca9c9Sdanielk1977ifcapable tclvar { 365d1e4733dSdrh do_test tcl-9.10 { 366d1e4733dSdrh proc userfunc_r1 {n} { 367d1e4733dSdrh if {$n<=0} {return 0} 368d1e4733dSdrh set nm1 [expr {$n-1}] 369d1e4733dSdrh return [expr {[db eval {SELECT r1($nm1)}]+$n}] 370d1e4733dSdrh } 371d1e4733dSdrh db function r1 userfunc_r1 372d1e4733dSdrh execsql {SELECT r1(10)} 373d1e4733dSdrh } {55} 374a01fda71Sdrh # Fails under -fsanitize=address,undefined due to stack overflow 375a01fda71Sdrh # do_test tcl-9.11 { 376a01fda71Sdrh # execsql {SELECT r1(100)} 377a01fda71Sdrh # } {5050} 3783bdca9c9Sdanielk1977} 379d1e4733dSdrh 380b5555e7eSdrh# Tests for the new transaction method 381b5555e7eSdrh# 382b5555e7eSdrhdo_test tcl-10.1 { 383b5555e7eSdrh db transaction {} 384b5555e7eSdrh} {} 385b5555e7eSdrhdo_test tcl-10.2 { 386b5555e7eSdrh db transaction deferred {} 387b5555e7eSdrh} {} 388b5555e7eSdrhdo_test tcl-10.3 { 389b5555e7eSdrh db transaction immediate {} 390b5555e7eSdrh} {} 391b5555e7eSdrhdo_test tcl-10.4 { 392b5555e7eSdrh db transaction exclusive {} 393b5555e7eSdrh} {} 394b5555e7eSdrhdo_test tcl-10.5 { 395b5555e7eSdrh set rc [catch {db transaction xyzzy {}} msg] 396b5555e7eSdrh lappend rc $msg 397b5555e7eSdrh} {1 {bad transaction type "xyzzy": must be deferred, exclusive, or immediate}} 398b5555e7eSdrhdo_test tcl-10.6 { 399b5555e7eSdrh set rc [catch {db transaction {error test-error}} msg] 400b5555e7eSdrh lappend rc $msg 401b5555e7eSdrh} {1 test-error} 402b5555e7eSdrhdo_test tcl-10.7 { 403b5555e7eSdrh db transaction { 404b5555e7eSdrh db eval {CREATE TABLE t4(x)} 405b5555e7eSdrh db transaction { 406b5555e7eSdrh db eval {INSERT INTO t4 VALUES(1)} 407b5555e7eSdrh } 408b5555e7eSdrh } 409b5555e7eSdrh db eval {SELECT * FROM t4} 410b5555e7eSdrh} 1 411b5555e7eSdrhdo_test tcl-10.8 { 412b5555e7eSdrh catch { 413b5555e7eSdrh db transaction { 414b5555e7eSdrh db eval {INSERT INTO t4 VALUES(2)} 415b5555e7eSdrh db eval {INSERT INTO t4 VALUES(3)} 416b5555e7eSdrh db eval {INSERT INTO t4 VALUES(4)} 417b5555e7eSdrh error test-error 418b5555e7eSdrh } 419b5555e7eSdrh } 420b5555e7eSdrh db eval {SELECT * FROM t4} 421b5555e7eSdrh} 1 422b5555e7eSdrhdo_test tcl-10.9 { 423b5555e7eSdrh db transaction { 424b5555e7eSdrh db eval {INSERT INTO t4 VALUES(2)} 425b5555e7eSdrh catch { 426b5555e7eSdrh db transaction { 427b5555e7eSdrh db eval {INSERT INTO t4 VALUES(3)} 428b5555e7eSdrh db eval {INSERT INTO t4 VALUES(4)} 429b5555e7eSdrh error test-error 430b5555e7eSdrh } 431b5555e7eSdrh } 432b5555e7eSdrh } 433b5555e7eSdrh db eval {SELECT * FROM t4} 434cd38d520Sdanielk1977} {1 2} 435b5555e7eSdrhdo_test tcl-10.10 { 436b5555e7eSdrh for {set i 0} {$i<1} {incr i} { 437b5555e7eSdrh db transaction { 438b5555e7eSdrh db eval {INSERT INTO t4 VALUES(5)} 439b5555e7eSdrh continue 440b5555e7eSdrh } 441cd38d520Sdanielk1977 error "This line should not be run" 442b5555e7eSdrh } 443b5555e7eSdrh db eval {SELECT * FROM t4} 444cd38d520Sdanielk1977} {1 2 5} 445b5555e7eSdrhdo_test tcl-10.11 { 446b5555e7eSdrh for {set i 0} {$i<10} {incr i} { 447b5555e7eSdrh db transaction { 448b5555e7eSdrh db eval {INSERT INTO t4 VALUES(6)} 449b5555e7eSdrh break 450b5555e7eSdrh } 451b5555e7eSdrh } 452b5555e7eSdrh db eval {SELECT * FROM t4} 453cd38d520Sdanielk1977} {1 2 5 6} 454b5555e7eSdrhdo_test tcl-10.12 { 455b5555e7eSdrh set rc [catch { 456b5555e7eSdrh for {set i 0} {$i<10} {incr i} { 457b5555e7eSdrh db transaction { 458b5555e7eSdrh db eval {INSERT INTO t4 VALUES(7)} 459b5555e7eSdrh return 460b5555e7eSdrh } 461b5555e7eSdrh } 462b5555e7eSdrh }] 463b5555e7eSdrh} {2} 464b5555e7eSdrhdo_test tcl-10.13 { 465b5555e7eSdrh db eval {SELECT * FROM t4} 466cd38d520Sdanielk1977} {1 2 5 6 7} 467cd38d520Sdanielk1977 468cd38d520Sdanielk1977# Now test that [db transaction] commands may be nested with 469cd38d520Sdanielk1977# the expected results. 470cd38d520Sdanielk1977# 471cd38d520Sdanielk1977do_test tcl-10.14 { 472cd38d520Sdanielk1977 db transaction { 473cd38d520Sdanielk1977 db eval { 474cd38d520Sdanielk1977 DELETE FROM t4; 475cd38d520Sdanielk1977 INSERT INTO t4 VALUES('one'); 476cd38d520Sdanielk1977 } 477cd38d520Sdanielk1977 478cd38d520Sdanielk1977 catch { 479cd38d520Sdanielk1977 db transaction { 480cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('two') } 481cd38d520Sdanielk1977 db transaction { 482cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('three') } 483cd38d520Sdanielk1977 error "throw an error!" 484cd38d520Sdanielk1977 } 485cd38d520Sdanielk1977 } 486cd38d520Sdanielk1977 } 487cd38d520Sdanielk1977 } 488cd38d520Sdanielk1977 489cd38d520Sdanielk1977 db eval {SELECT * FROM t4} 490cd38d520Sdanielk1977} {one} 491cd38d520Sdanielk1977do_test tcl-10.15 { 492cd38d520Sdanielk1977 # Make sure a transaction has not been left open. 493cd38d520Sdanielk1977 db eval {BEGIN ; COMMIT} 494cd38d520Sdanielk1977} {} 495cd38d520Sdanielk1977do_test tcl-10.16 { 496cd38d520Sdanielk1977 db transaction { 497cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('two'); } 498cd38d520Sdanielk1977 db transaction { 499cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('three') } 500cd38d520Sdanielk1977 db transaction { 501cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('four') } 502cd38d520Sdanielk1977 } 503cd38d520Sdanielk1977 } 504cd38d520Sdanielk1977 } 505cd38d520Sdanielk1977 db eval {SELECT * FROM t4} 506cd38d520Sdanielk1977} {one two three four} 507cd38d520Sdanielk1977do_test tcl-10.17 { 508cd38d520Sdanielk1977 catch { 509cd38d520Sdanielk1977 db transaction { 510cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('A'); } 511cd38d520Sdanielk1977 db transaction { 512cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('B') } 513cd38d520Sdanielk1977 db transaction { 514cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('C') } 515cd38d520Sdanielk1977 error "throw an error!" 516cd38d520Sdanielk1977 } 517cd38d520Sdanielk1977 } 518cd38d520Sdanielk1977 } 519cd38d520Sdanielk1977 } 520cd38d520Sdanielk1977 db eval {SELECT * FROM t4} 521cd38d520Sdanielk1977} {one two three four} 522cd38d520Sdanielk1977do_test tcl-10.18 { 523cd38d520Sdanielk1977 # Make sure a transaction has not been left open. 524cd38d520Sdanielk1977 db eval {BEGIN ; COMMIT} 525cd38d520Sdanielk1977} {} 526cd38d520Sdanielk1977 527cd38d520Sdanielk1977# Mess up a [db transaction] command by locking the database using a 528cd38d520Sdanielk1977# second connection when it tries to commit. Make sure the transaction 529cd38d520Sdanielk1977# is not still open after the "database is locked" exception is thrown. 530cd38d520Sdanielk1977# 531cd38d520Sdanielk1977do_test tcl-10.18 { 532cd38d520Sdanielk1977 sqlite3 db2 test.db 533cd38d520Sdanielk1977 db2 eval { 534cd38d520Sdanielk1977 BEGIN; 535cd38d520Sdanielk1977 SELECT * FROM sqlite_master; 536cd38d520Sdanielk1977 } 537cd38d520Sdanielk1977 538cd38d520Sdanielk1977 set rc [catch { 539cd38d520Sdanielk1977 db transaction { 540cd38d520Sdanielk1977 db eval {INSERT INTO t4 VALUES('five')} 541cd38d520Sdanielk1977 } 542cd38d520Sdanielk1977 } msg] 543cd38d520Sdanielk1977 list $rc $msg 544cd38d520Sdanielk1977} {1 {database is locked}} 545cd38d520Sdanielk1977do_test tcl-10.19 { 546cd38d520Sdanielk1977 db eval {BEGIN ; COMMIT} 547cd38d520Sdanielk1977} {} 548cd38d520Sdanielk1977 549cd38d520Sdanielk1977# Thwart a [db transaction] command by locking the database using a 550cd38d520Sdanielk1977# second connection with "BEGIN EXCLUSIVE". Make sure no transaction is 551cd38d520Sdanielk1977# open after the "database is locked" exception is thrown. 552cd38d520Sdanielk1977# 553cd38d520Sdanielk1977do_test tcl-10.20 { 554cd38d520Sdanielk1977 db2 eval { 555cd38d520Sdanielk1977 COMMIT; 556cd38d520Sdanielk1977 BEGIN EXCLUSIVE; 557cd38d520Sdanielk1977 } 558cd38d520Sdanielk1977 set rc [catch { 559cd38d520Sdanielk1977 db transaction { 560cd38d520Sdanielk1977 db eval {INSERT INTO t4 VALUES('five')} 561cd38d520Sdanielk1977 } 562cd38d520Sdanielk1977 } msg] 563cd38d520Sdanielk1977 list $rc $msg 564cd38d520Sdanielk1977} {1 {database is locked}} 565cd38d520Sdanielk1977do_test tcl-10.21 { 566cd38d520Sdanielk1977 db2 close 567cd38d520Sdanielk1977 db eval {BEGIN ; COMMIT} 568cd38d520Sdanielk1977} {} 569cd38d520Sdanielk1977do_test tcl-10.22 { 570cd38d520Sdanielk1977 sqlite3 db2 test.db 571cd38d520Sdanielk1977 db transaction exclusive { 572cd38d520Sdanielk1977 catch { db2 eval {SELECT * FROM sqlite_master} } msg 573cd38d520Sdanielk1977 set msg "db2: $msg" 574cd38d520Sdanielk1977 } 575cd38d520Sdanielk1977 set msg 576cd38d520Sdanielk1977} {db2: database is locked} 577cd38d520Sdanielk1977db2 close 578c7f269d5Sdrh 57997f2ebc1Sdrhdo_test tcl-11.1 { 580cd38d520Sdanielk1977 db eval {INSERT INTO t4 VALUES(6)} 581cd38d520Sdanielk1977 db exists {SELECT x,x*2,x+x FROM t4 WHERE x==6} 58297f2ebc1Sdrh} {1} 58397f2ebc1Sdrhdo_test tcl-11.2 { 584cd38d520Sdanielk1977 db exists {SELECT 0 FROM t4 WHERE x==6} 58597f2ebc1Sdrh} {1} 58697f2ebc1Sdrhdo_test tcl-11.3 { 58797f2ebc1Sdrh db exists {SELECT 1 FROM t4 WHERE x==8} 58897f2ebc1Sdrh} {0} 589a2c8a95bSdrhdo_test tcl-11.3.1 { 590a2c8a95bSdrh tcl_objproc db exists {SELECT 1 FROM t4 WHERE x==8} 591a2c8a95bSdrh} {0} 59297f2ebc1Sdrh 593161fb796Sdanielk1977do_test tcl-12.1 { 594161fb796Sdanielk1977 unset -nocomplain a b c version 595161fb796Sdanielk1977 set version [db version] 596161fb796Sdanielk1977 scan $version "%d.%d.%d" a b c 597161fb796Sdanielk1977 expr $a*1000000 + $b*1000 + $c 598161fb796Sdanielk1977} [sqlite3_libversion_number] 599161fb796Sdanielk1977 6004f5e80f9Sdrh 6014f5e80f9Sdrh# Check to see that when bindings of the form @aaa are used instead 6021c747819Sdrh# of $aaa, that objects are treated as bytearray and are inserted 6031c747819Sdrh# as BLOBs. 6044f5e80f9Sdrh# 6054152e677Sdanielk1977ifcapable tclvar { 6064f5e80f9Sdrh do_test tcl-13.1 { 6074f5e80f9Sdrh db eval {CREATE TABLE t5(x BLOB)} 6084f5e80f9Sdrh set x abc123 6094f5e80f9Sdrh db eval {INSERT INTO t5 VALUES($x)} 6104f5e80f9Sdrh db eval {SELECT typeof(x) FROM t5} 6114f5e80f9Sdrh } {text} 6124f5e80f9Sdrh do_test tcl-13.2 { 6134f5e80f9Sdrh binary scan $x H notUsed 6144f5e80f9Sdrh db eval { 6154f5e80f9Sdrh DELETE FROM t5; 6164f5e80f9Sdrh INSERT INTO t5 VALUES($x); 6174f5e80f9Sdrh SELECT typeof(x) FROM t5; 6184f5e80f9Sdrh } 6194f5e80f9Sdrh } {text} 6204f5e80f9Sdrh do_test tcl-13.3 { 6214f5e80f9Sdrh db eval { 6224f5e80f9Sdrh DELETE FROM t5; 6234f5e80f9Sdrh INSERT INTO t5 VALUES(@x); 6244f5e80f9Sdrh SELECT typeof(x) FROM t5; 6254f5e80f9Sdrh } 6264f5e80f9Sdrh } {blob} 6271c747819Sdrh do_test tcl-13.4 { 6281c747819Sdrh set y 1234 6291c747819Sdrh db eval { 6301c747819Sdrh DELETE FROM t5; 6311c747819Sdrh INSERT INTO t5 VALUES(@y); 6321c747819Sdrh SELECT hex(x), typeof(x) FROM t5 6331c747819Sdrh } 6341c747819Sdrh } {31323334 blob} 6354152e677Sdanielk1977} 6361c747819Sdrh 637d5f12cd5Sdandb func xCall xCall 638d5f12cd5Sdanproc xCall {} { return "value" } 639d5f12cd5Sdando_execsql_test tcl-14.1 { 640d5f12cd5Sdan CREATE TABLE t6(x); 641d5f12cd5Sdan INSERT INTO t6 VALUES(1); 642d5f12cd5Sdan} 643d5f12cd5Sdando_test tcl-14.2 { 644d5f12cd5Sdan db one {SELECT x FROM t6 WHERE xCall()!='value'} 645d5f12cd5Sdan} {} 646d5f12cd5Sdan 647edc4024bSdrh# Verify that the "exists" and "onecolumn" methods work when 648edc4024bSdrh# a "profile" is registered. 649edc4024bSdrh# 650edc4024bSdrhcatch {db close} 651edc4024bSdrhsqlite3 db :memory: 652edc4024bSdrhproc noop-profile {args} { 653edc4024bSdrh return 654edc4024bSdrh} 655edc4024bSdrhdo_test tcl-15.0 { 656edc4024bSdrh db eval {CREATE TABLE t1(a); INSERT INTO t1 VALUES(1),(2),(3);} 657edc4024bSdrh db onecolumn {SELECT a FROM t1 WHERE a>2} 658edc4024bSdrh} {3} 659edc4024bSdrhdo_test tcl-15.1 { 660edc4024bSdrh db exists {SELECT a FROM t1 WHERE a>2} 661edc4024bSdrh} {1} 662edc4024bSdrhdo_test tcl-15.2 { 663edc4024bSdrh db exists {SELECT a FROM t1 WHERE a>3} 664edc4024bSdrh} {0} 665edc4024bSdrhdb profile noop-profile 666edc4024bSdrhdo_test tcl-15.3 { 667edc4024bSdrh db onecolumn {SELECT a FROM t1 WHERE a>2} 668edc4024bSdrh} {3} 669edc4024bSdrhdo_test tcl-15.4 { 670edc4024bSdrh db exists {SELECT a FROM t1 WHERE a>2} 671edc4024bSdrh} {1} 672edc4024bSdrhdo_test tcl-15.5 { 673edc4024bSdrh db exists {SELECT a FROM t1 WHERE a>3} 674edc4024bSdrh} {0} 675edc4024bSdrh 676edc4024bSdrh 677af38cdbcSdrh# 2017-06-26: The --withoutnulls flag to "db eval". 678af38cdbcSdrh# 679af38cdbcSdrh# In the "db eval --withoutnulls SQL ARRAY" form, NULL results cause the 680af38cdbcSdrh# corresponding array entry to be unset. The default behavior (without 681af38cdbcSdrh# the -withoutnulls flags) is for the corresponding array value to get 682af38cdbcSdrh# the [db nullvalue] string. 683af38cdbcSdrh# 684af38cdbcSdrhcatch {db close} 685af38cdbcSdrhforcedelete test.db 686af38cdbcSdrhsqlite3 db test.db 687af38cdbcSdrhdo_execsql_test tcl-16.100 { 688af38cdbcSdrh CREATE TABLE t1(a,b); 689af38cdbcSdrh INSERT INTO t1 VALUES(1,2),(2,NULL),(3,'xyz'); 690af38cdbcSdrh} 691af38cdbcSdrhdo_test tcl-16.101 { 692af38cdbcSdrh set res {} 693af38cdbcSdrh unset -nocomplain x 694af38cdbcSdrh db eval {SELECT * FROM t1} x { 695af38cdbcSdrh lappend res $x(a) [array names x] 696af38cdbcSdrh } 697af38cdbcSdrh set res 698af38cdbcSdrh} {1 {a b *} 2 {a b *} 3 {a b *}} 699af38cdbcSdrhdo_test tcl-16.102 { 700af38cdbcSdrh set res [catch { 701af38cdbcSdrh db eval -unknown {SELECT * FROM t1} x { 702af38cdbcSdrh lappend res $x(a) [array names x] 703af38cdbcSdrh } 704af38cdbcSdrh } rc] 705af38cdbcSdrh lappend res $rc 706af38cdbcSdrh} {1 {unknown option: "-unknown"}} 707af38cdbcSdrhdo_test tcl-16.103 { 708af38cdbcSdrh set res {} 709af38cdbcSdrh unset -nocomplain x 710af38cdbcSdrh db eval -withoutnulls {SELECT * FROM t1} x { 711af38cdbcSdrh lappend res $x(a) [array names x] 712af38cdbcSdrh } 713af38cdbcSdrh set res 714af38cdbcSdrh} {1 {a b *} 2 {a *} 3 {a b *}} 715edc4024bSdrh 71689d24936Sdan#------------------------------------------------------------------------- 71789d24936Sdan# Test the -type option to [db function]. 71889d24936Sdan# 71989d24936Sdanreset_db 72089d24936Sdanproc add {a b} { return [expr $a + $b] } 72189d24936Sdanproc ret {a} { return $a } 722edc4024bSdrh 72389d24936Sdandb function add_i -returntype integer add 72489d24936Sdandb function add_r -ret real add 72589d24936Sdandb function add_t -return text add 72689d24936Sdandb function add_b -returntype blob add 72789d24936Sdandb function add_a -returntype any add 728edc4024bSdrh 72989d24936Sdandb function ret_i -returntype int ret 73089d24936Sdandb function ret_r -returntype real ret 73189d24936Sdandb function ret_t -returntype text ret 73289d24936Sdandb function ret_b -returntype blob ret 73389d24936Sdandb function ret_a -r any ret 734d5f12cd5Sdan 73589d24936Sdando_execsql_test 17.0 { 73689d24936Sdan SELECT quote( add_i(2, 3) ); 73789d24936Sdan SELECT quote( add_r(2, 3) ); 73889d24936Sdan SELECT quote( add_t(2, 3) ); 73989d24936Sdan SELECT quote( add_b(2, 3) ); 74089d24936Sdan SELECT quote( add_a(2, 3) ); 74189d24936Sdan} {5 5.0 '5' X'35' 5} 74289d24936Sdan 74389d24936Sdando_execsql_test 17.1 { 74489d24936Sdan SELECT quote( add_i(2.2, 3.3) ); 74589d24936Sdan SELECT quote( add_r(2.2, 3.3) ); 74689d24936Sdan SELECT quote( add_t(2.2, 3.3) ); 74789d24936Sdan SELECT quote( add_b(2.2, 3.3) ); 74889d24936Sdan SELECT quote( add_a(2.2, 3.3) ); 74989d24936Sdan} {5.5 5.5 '5.5' X'352E35' 5.5} 75089d24936Sdan 75189d24936Sdando_execsql_test 17.2 { 75289d24936Sdan SELECT quote( ret_i(2.5) ); 75389d24936Sdan SELECT quote( ret_r(2.5) ); 75489d24936Sdan SELECT quote( ret_t(2.5) ); 75589d24936Sdan SELECT quote( ret_b(2.5) ); 75689d24936Sdan SELECT quote( ret_a(2.5) ); 75789d24936Sdan} {2.5 2.5 '2.5' X'322E35' 2.5} 75889d24936Sdan 75989d24936Sdando_execsql_test 17.3 { 76089d24936Sdan SELECT quote( ret_i('2.5') ); 76189d24936Sdan SELECT quote( ret_r('2.5') ); 76289d24936Sdan SELECT quote( ret_t('2.5') ); 76389d24936Sdan SELECT quote( ret_b('2.5') ); 76489d24936Sdan SELECT quote( ret_a('2.5') ); 76589d24936Sdan} {2.5 2.5 '2.5' X'322E35' '2.5'} 76689d24936Sdan 76789d24936Sdando_execsql_test 17.4 { 76889d24936Sdan SELECT quote( ret_i('abc') ); 76989d24936Sdan SELECT quote( ret_r('abc') ); 77089d24936Sdan SELECT quote( ret_t('abc') ); 77189d24936Sdan SELECT quote( ret_b('abc') ); 77289d24936Sdan SELECT quote( ret_a('abc') ); 77389d24936Sdan} {'abc' 'abc' 'abc' X'616263' 'abc'} 77489d24936Sdan 77589d24936Sdando_execsql_test 17.5 { 77689d24936Sdan SELECT quote( ret_i(X'616263') ); 77789d24936Sdan SELECT quote( ret_r(X'616263') ); 77889d24936Sdan SELECT quote( ret_t(X'616263') ); 77989d24936Sdan SELECT quote( ret_b(X'616263') ); 78089d24936Sdan SELECT quote( ret_a(X'616263') ); 78189d24936Sdan} {'abc' 'abc' 'abc' X'616263' X'616263'} 78289d24936Sdan 78389d24936Sdando_test 17.6.1 { 78489d24936Sdan list [catch { db function xyz -return object ret } msg] $msg 78589d24936Sdan} {1 {bad type "object": must be integer, real, text, blob, or any}} 78689d24936Sdan 78789d24936Sdando_test 17.6.2 { 78889d24936Sdan list [catch { db function xyz -return ret } msg] $msg 78989d24936Sdan} {1 {option requires an argument: -return}} 79089d24936Sdan 79189d24936Sdando_test 17.6.3 { 79289d24936Sdan list [catch { db function xyz -n object ret } msg] $msg 7932eeca204Sdrh} {1 {bad option "-n": must be -argcount, -deterministic, -directonly, -innocuous, or -returntype}} 7944f5e80f9Sdrh 795c06ede10Sdrh# 2019-02-28: The "bind_fallback" command. 796c06ede10Sdrh# 797c06ede10Sdrhdo_test 18.100 { 798c06ede10Sdrh unset -nocomplain bindings abc def ghi jkl mno e01 e02 799c06ede10Sdrh set bindings(abc) [expr {1+2}] 800c06ede10Sdrh set bindings(def) {hello} 801c06ede10Sdrh set bindings(ghi) [expr {3.1415926*1.0}] 802c06ede10Sdrh proc bind_callback {nm} { 803c06ede10Sdrh global bindings 804c06ede10Sdrh set n2 [string range $nm 1 end] 805c06ede10Sdrh if {[info exists bindings($n2)]} { 806c06ede10Sdrh return $bindings($n2) 807c06ede10Sdrh } 808c06ede10Sdrh if {[string match e* $n2]} { 809c06ede10Sdrh error "no such variable: $nm" 810c06ede10Sdrh } 811c06ede10Sdrh return -code return {} 812c06ede10Sdrh } 813c06ede10Sdrh db bind_fallback bind_callback 814c06ede10Sdrh db eval {SELECT $abc, typeof($abc), $def, typeof($def), $ghi, typeof($ghi)} 815c06ede10Sdrh} {3 integer hello text 3.1415926 real} 816c06ede10Sdrhdo_test 18.110 { 817c06ede10Sdrh db eval {SELECT quote(@def), typeof(@def)} 818c06ede10Sdrh} {X'68656C6C6F' blob} 819c06ede10Sdrhdo_execsql_test 18.120 { 820c06ede10Sdrh SELECT typeof($mno); 821c06ede10Sdrh} {null} 822c06ede10Sdrhdo_catchsql_test 18.130 { 823c06ede10Sdrh SELECT $e01; 824c06ede10Sdrh} {1 {no such variable: $e01}} 825c06ede10Sdrhdo_test 18.140 { 826c06ede10Sdrh db bind_fallback 827c06ede10Sdrh} {bind_callback} 828c06ede10Sdrhdo_test 18.200 { 829c06ede10Sdrh db bind_fallback {} 830c06ede10Sdrh db eval {SELECT $abc, typeof($abc), $def, typeof($def), $ghi, typeof($ghi)} 831c06ede10Sdrh} {{} null {} null {} null} 832c06ede10Sdrhdo_test 18.300 { 833c06ede10Sdrh unset -nocomplain bindings 834c06ede10Sdrh proc bind_callback {nm} {lappend ::bindings $nm} 835c06ede10Sdrh db bind_fallback bind_callback 836c06ede10Sdrh db eval {SELECT $abc, @def, $ghi(123), :mno} 837c06ede10Sdrh set bindings 838c06ede10Sdrh} {{$abc} @def {$ghi(123)} :mno} 839c06ede10Sdrhdo_test 18.900 { 840c06ede10Sdrh set rc [catch {db bind_fallback a b} msg] 841c06ede10Sdrh lappend rc $msg 842c06ede10Sdrh} {1 {wrong # args: should be "db bind_fallback ?CALLBACK?"}} 843c06ede10Sdrhdo_test 18.910 { 844c06ede10Sdrh db bind_fallback bind_fallback_does_not_exist 845c06ede10Sdrh} {} 846c06ede10Sdrhdo_catchsql_test 19.911 { 847c06ede10Sdrh SELECT $abc, typeof($abc), $def, typeof($def), $ghi, typeof($ghi); 848c06ede10Sdrh} {1 {invalid command name "bind_fallback_does_not_exist"}} 849c06ede10Sdrhdb bind_fallback {} 85089d24936Sdan 851bea28c73Sdan#------------------------------------------------------------------------- 852bea28c73Sdando_test 20.0 { 853bea28c73Sdan db transaction { 854bea28c73Sdan db close 855bea28c73Sdan } 856bea28c73Sdan} {} 857bea28c73Sdan 858bea28c73Sdando_test 20.1 { 859bea28c73Sdan sqlite3 db test.db 860bea28c73Sdan set rc [catch { 861bea28c73Sdan db eval {SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3} { db close } 862bea28c73Sdan } msg] 863bea28c73Sdan list $rc $msg 864bea28c73Sdan} {1 {invalid command name "db"}} 865bea28c73Sdan 866bea28c73Sdan 867bea28c73Sdanproc closedb {} { 868bea28c73Sdan db close 869bea28c73Sdan return 10 870bea28c73Sdan} 871bea28c73Sdanproc func1 {} { return 1 } 872bea28c73Sdan 873bea28c73Sdansqlite3 db test.db 874bea28c73Sdandb func closedb closedb 875bea28c73Sdandb func func1 func1 876bea28c73Sdan 877bea28c73Sdando_test 20.2 { 878bea28c73Sdan set rc [catch { 879bea28c73Sdan db eval { 880bea28c73Sdan SELECT closedb(),func1() UNION ALL SELECT 20,30 UNION ALL SELECT 30,40 881bea28c73Sdan } 882bea28c73Sdan } msg] 883bea28c73Sdan list $rc $msg 884bea28c73Sdan} {0 {10 1 20 30 30 40}} 885bea28c73Sdan 886*be4e3c88Sdrhsqlite3 db :memory: 887*be4e3c88Sdrhdo_test 21.1 { 888*be4e3c88Sdrh catch {db eval {SELECT 1 2 3;}} msg 889*be4e3c88Sdrh db erroroffset 890*be4e3c88Sdrh} {9} 891bea28c73Sdan 892*be4e3c88Sdrhfinish_test 893