1c22bd47dSdrh# 2002 May 10 2c22bd47dSdrh# 3c22bd47dSdrh# The author disclaims copyright to this source code. In place of 4c22bd47dSdrh# a legal notice, here is a blessing: 5c22bd47dSdrh# 6c22bd47dSdrh# May you do good and not evil. 7c22bd47dSdrh# May you find forgiveness for yourself and forgive others. 8c22bd47dSdrh# May you share freely, never taking more than you give. 9c22bd47dSdrh# 10c22bd47dSdrh#*********************************************************************** 11c22bd47dSdrh# This file implements regression tests for SQLite library. 12c22bd47dSdrh# 13c22bd47dSdrh# This file implements tests for the SQLITE_MISUSE detection logic. 14c22bd47dSdrh# This test file leaks memory and file descriptors. 15c22bd47dSdrh# 16dddca286Sdrh# $Id: misuse.test,v 1.11 2006/01/03 00:33:50 drh Exp $ 17c22bd47dSdrh 18c22bd47dSdrhset testdir [file dirname $argv0] 19c22bd47dSdrhsource $testdir/tester.tcl 20c22bd47dSdrh 21e35ee196Sdanielk1977proc catchsql2 {sql} { 22e35ee196Sdanielk1977 set r [ 23e35ee196Sdanielk1977 catch { 24e35ee196Sdanielk1977 set res [list] 25e35ee196Sdanielk1977 db eval $sql data { 26e35ee196Sdanielk1977 if { $res==[list] } { 27e35ee196Sdanielk1977 foreach f $data(*) {lappend res $f} 28e35ee196Sdanielk1977 } 29e35ee196Sdanielk1977 foreach f $data(*) {lappend res $data($f)} 30e35ee196Sdanielk1977 } 31e35ee196Sdanielk1977 set res 32e35ee196Sdanielk1977 } msg 33e35ee196Sdanielk1977 ] 34e35ee196Sdanielk1977 lappend r $msg 35e35ee196Sdanielk1977} 36e35ee196Sdanielk1977 37e35ee196Sdanielk1977 38c22bd47dSdrh# Make sure the test logic works 39c22bd47dSdrh# 40c22bd47dSdrhdo_test misuse-1.1 { 41c22bd47dSdrh db close 42fda06befSmistachkin catch {forcedelete test2.db} 43fda06befSmistachkin catch {forcedelete test2.db-journal} 44dddca286Sdrh sqlite3 db test2.db; set ::DB [sqlite3_connection_pointer db] 45c22bd47dSdrh execsql { 46c22bd47dSdrh CREATE TABLE t1(a,b); 47c22bd47dSdrh INSERT INTO t1 VALUES(1,2); 48c22bd47dSdrh } 49e35ee196Sdanielk1977 catchsql2 { 50e35ee196Sdanielk1977 SELECT * FROM t1 51e35ee196Sdanielk1977 } 52c22bd47dSdrh} {0 {a b 1 2}} 53c22bd47dSdrhdo_test misuse-1.2 { 54e35ee196Sdanielk1977 catchsql2 { 55e35ee196Sdanielk1977 SELECT x_coalesce(NULL,a) AS 'xyz' FROM t1 56e35ee196Sdanielk1977 } 57c22bd47dSdrh} {1 {no such function: x_coalesce}} 58c22bd47dSdrhdo_test misuse-1.3 { 59e35ee196Sdanielk1977 sqlite3_create_function $::DB 60e35ee196Sdanielk1977 catchsql2 { 61e35ee196Sdanielk1977 SELECT x_coalesce(NULL,a) AS 'xyz' FROM t1 62e35ee196Sdanielk1977 } 63c22bd47dSdrh} {0 {xyz 1}} 64c22bd47dSdrh 65c22bd47dSdrh# Use the x_sqlite_exec() SQL function to simulate the effect of two 66c22bd47dSdrh# threads trying to use the same database at the same time. 67c22bd47dSdrh# 68d1d9fc33Sdrh# It used to be prohibited to invoke sqlite_exec() from within a function, 69d1d9fc33Sdrh# but that has changed. The following tests used to cause errors but now 70d1d9fc33Sdrh# they do not. 71d1d9fc33Sdrh# 726c62608fSdrhifcapable {utf16} { 73c22bd47dSdrh do_test misuse-1.4 { 74e35ee196Sdanielk1977 catchsql2 { 75d1d9fc33Sdrh SELECT x_sqlite_exec('SELECT * FROM t1') AS xyz; 76e35ee196Sdanielk1977 } 77d1d9fc33Sdrh } {0 {xyz {1 2}}} 786c62608fSdrh} 79c22bd47dSdrhdo_test misuse-1.5 { 80e35ee196Sdanielk1977 catchsql2 {SELECT * FROM t1} 81d1d9fc33Sdrh} {0 {a b 1 2}} 82c22bd47dSdrhdo_test misuse-1.6 { 83c22bd47dSdrh catchsql { 84c22bd47dSdrh SELECT * FROM t1 85c22bd47dSdrh } 86d1d9fc33Sdrh} {0 {1 2}} 87c22bd47dSdrh 88c22bd47dSdrh# Attempt to register a new SQL function while an sqlite_exec() is active. 89c22bd47dSdrh# 90c22bd47dSdrhdo_test misuse-2.1 { 91c22bd47dSdrh db close 92dddca286Sdrh sqlite3 db test2.db; set ::DB [sqlite3_connection_pointer db] 93c22bd47dSdrh execsql { 94c22bd47dSdrh SELECT * FROM t1 95c22bd47dSdrh } 96c22bd47dSdrh} {1 2} 97c22bd47dSdrhdo_test misuse-2.2 { 98e35ee196Sdanielk1977 catchsql2 {SELECT * FROM t1} 99c22bd47dSdrh} {0 {a b 1 2}} 100c60d0446Sdrh 101c60d0446Sdrh# We used to disallow creating new function from within an exec(). 102c60d0446Sdrh# But now this is acceptable. 103c22bd47dSdrhdo_test misuse-2.3 { 104c22bd47dSdrh set v [catch { 105c22bd47dSdrh db eval {SELECT * FROM t1} {} { 106e35ee196Sdanielk1977 sqlite3_create_function $::DB 107c22bd47dSdrh } 108c22bd47dSdrh } msg] 109c22bd47dSdrh lappend v $msg 110c60d0446Sdrh} {0 {}} 111c22bd47dSdrhdo_test misuse-2.4 { 112e35ee196Sdanielk1977 catchsql2 {SELECT * FROM t1} 113c60d0446Sdrh} {0 {a b 1 2}} 114c22bd47dSdrhdo_test misuse-2.5 { 115c22bd47dSdrh catchsql { 116c22bd47dSdrh SELECT * FROM t1 117c22bd47dSdrh } 118c60d0446Sdrh} {0 {1 2}} 119c22bd47dSdrh 120c22bd47dSdrh# Attempt to register a new SQL aggregate while an sqlite_exec() is active. 121c22bd47dSdrh# 122c22bd47dSdrhdo_test misuse-3.1 { 123c22bd47dSdrh db close 124dddca286Sdrh sqlite3 db test2.db; set ::DB [sqlite3_connection_pointer db] 125c22bd47dSdrh execsql { 126c22bd47dSdrh SELECT * FROM t1 127c22bd47dSdrh } 128c22bd47dSdrh} {1 2} 129c22bd47dSdrhdo_test misuse-3.2 { 130e35ee196Sdanielk1977 catchsql2 {SELECT * FROM t1} 131c22bd47dSdrh} {0 {a b 1 2}} 132c60d0446Sdrh 133c60d0446Sdrh# We used to disallow creating new function from within an exec(). 134c60d0446Sdrh# But now this is acceptable. 135c22bd47dSdrhdo_test misuse-3.3 { 136c22bd47dSdrh set v [catch { 137c22bd47dSdrh db eval {SELECT * FROM t1} {} { 138e35ee196Sdanielk1977 sqlite3_create_aggregate $::DB 139c22bd47dSdrh } 140c22bd47dSdrh } msg] 141c22bd47dSdrh lappend v $msg 142c60d0446Sdrh} {0 {}} 143c22bd47dSdrhdo_test misuse-3.4 { 144e35ee196Sdanielk1977 catchsql2 {SELECT * FROM t1} 145c60d0446Sdrh} {0 {a b 1 2}} 146c22bd47dSdrhdo_test misuse-3.5 { 147c22bd47dSdrh catchsql { 148c22bd47dSdrh SELECT * FROM t1 149c22bd47dSdrh } 150c60d0446Sdrh} {0 {1 2}} 151c22bd47dSdrh 152c22bd47dSdrh# Attempt to close the database from an sqlite_exec callback. 153c22bd47dSdrh# 154e35ee196Sdanielk1977# Update for v3: The db cannot be closed because there are active 155e35ee196Sdanielk1977# VMs. The sqlite3_close call would return SQLITE_BUSY. 156c22bd47dSdrhdo_test misuse-4.1 { 157c22bd47dSdrh db close 158dddca286Sdrh sqlite3 db test2.db; set ::DB [sqlite3_connection_pointer db] 159c22bd47dSdrh execsql { 160c22bd47dSdrh SELECT * FROM t1 161c22bd47dSdrh } 162c22bd47dSdrh} {1 2} 163c22bd47dSdrhdo_test misuse-4.2 { 164e35ee196Sdanielk1977 catchsql2 {SELECT * FROM t1} 165c22bd47dSdrh} {0 {a b 1 2}} 166c22bd47dSdrhdo_test misuse-4.3 { 167c22bd47dSdrh set v [catch { 168c22bd47dSdrh db eval {SELECT * FROM t1} {} { 169e35ee196Sdanielk1977 set r [sqlite3_close $::DB] 170c22bd47dSdrh } 171c22bd47dSdrh } msg] 172e35ee196Sdanielk1977 lappend v $msg $r 173e35ee196Sdanielk1977} {0 {} SQLITE_BUSY} 174afcf9bd8Sdan 175afcf9bd8Sdanif {[clang_sanitize_address]==0} { 176c22bd47dSdrh do_test misuse-4.4 { 177a21c6b6fSdanielk1977 # Flush the TCL statement cache here, otherwise the sqlite3_close() will 178a21c6b6fSdanielk1977 # fail because there are still un-finalized() VDBEs. 179a21c6b6fSdanielk1977 db cache flush 180e35ee196Sdanielk1977 sqlite3_close $::DB 181e35ee196Sdanielk1977 catchsql2 {SELECT * FROM t1} 182*ff4fa772Sdrh } {1 {bad parameter or other API misuse}} 183c22bd47dSdrh do_test misuse-4.5 { 184c22bd47dSdrh catchsql { 185c22bd47dSdrh SELECT * FROM t1 186c22bd47dSdrh } 187*ff4fa772Sdrh } {1 {bad parameter or other API misuse}} 188c22bd47dSdrh 189c22bd47dSdrh # Attempt to use a database after it has been closed. 190c22bd47dSdrh # 191c22bd47dSdrh do_test misuse-5.1 { 192c22bd47dSdrh db close 193dddca286Sdrh sqlite3 db test2.db; set ::DB [sqlite3_connection_pointer db] 194c22bd47dSdrh execsql { 195c22bd47dSdrh SELECT * FROM t1 196c22bd47dSdrh } 197c22bd47dSdrh } {1 2} 198c22bd47dSdrh do_test misuse-5.2 { 199e35ee196Sdanielk1977 catchsql2 {SELECT * FROM t1} 200c22bd47dSdrh } {0 {a b 1 2}} 201c22bd47dSdrh do_test misuse-5.3 { 202c22bd47dSdrh db close 203e35ee196Sdanielk1977 set r [catch { 204e35ee196Sdanielk1977 sqlite3_prepare $::DB {SELECT * FROM t1} -1 TAIL 205e35ee196Sdanielk1977 } msg] 206e35ee196Sdanielk1977 lappend r $msg 207*ff4fa772Sdrh } {1 {(21) bad parameter or other API misuse}} 208afcf9bd8Sdan} 209c22bd47dSdrh 210c22bd47dSdrhfinish_test 211