# 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # Test that if sqlite3_prepare_v2() is used to prepare a query, the # error-message associated with an sqlite3_step() error is available # immediately. Whereas if sqlite3_prepare() is used, it is not available # until sqlite3_finalize() or sqlite3_reset() has been called. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix errmsg # Test organization: # # errmsg-1.* User-defined SQL function errors # errmsg-2.* Errors generated by the VDBE (constraint failures etc.) # errmsg-3.* SQLITE_SCHEMA and statement recompilation errors. # proc error_messages_worker {prepare sql schema} { set ret [list] set stmt [$prepare db $sql -1 dummy] execsql $schema lappend ret [sqlite3_step $stmt] lappend ret [sqlite3_errmsg db] lappend ret [sqlite3_finalize $stmt] lappend ret [sqlite3_errmsg db] set ret } proc error_messages_v2 {sql {schema {}}} { error_messages_worker sqlite3_prepare_v2 $sql $schema } proc error_messages {sql {schema {}}} { error_messages_worker sqlite3_prepare $sql $schema } proc sql_error {msg} { error $msg } db func sql_error sql_error #------------------------------------------------------------------------- # Test error messages returned by user-defined SQL functions. # do_test 1.1 { error_messages "SELECT sql_error('custom message')" } [list {*}{ SQLITE_ERROR {SQL logic error} SQLITE_ERROR {custom message} }] do_test 1.2 { error_messages_v2 "SELECT sql_error('custom message')" } [list {*}{ SQLITE_ERROR {custom message} SQLITE_ERROR {custom message} }] #------------------------------------------------------------------------- # Test error messages generated directly by VDBE code (e.g. constraint # failures). # do_execsql_test 2.1 { CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); INSERT INTO t1 VALUES('abc', 'def'); } do_test 2.2 { error_messages "INSERT INTO t1 VALUES('ghi', 'def')" } [list {*}{ SQLITE_ERROR {SQL logic error} SQLITE_CONSTRAINT {UNIQUE constraint failed: t1.b} }] verify_ex_errcode 2.2b SQLITE_CONSTRAINT_UNIQUE do_test 2.3 { error_messages_v2 "INSERT INTO t1 VALUES('ghi', 'def')" } [list {*}{ SQLITE_CONSTRAINT {UNIQUE constraint failed: t1.b} SQLITE_CONSTRAINT {UNIQUE constraint failed: t1.b} }] verify_ex_errcode 2.3b SQLITE_CONSTRAINT_UNIQUE #------------------------------------------------------------------------- # Test SQLITE_SCHEMA errors. And, for _v2(), test that if the schema # change invalidates the SQL statement itself the error message is returned # correctly. # do_execsql_test 3.1.1 { CREATE TABLE t2(a PRIMARY KEY, b UNIQUE); INSERT INTO t2 VALUES('abc', 'def'); } do_test 3.1.2 { error_messages "SELECT a FROM t2" "DROP TABLE t2" } [list {*}{ SQLITE_ERROR {SQL logic error} SQLITE_SCHEMA {database schema has changed} }] do_execsql_test 3.2.1 { CREATE TABLE t2(a PRIMARY KEY, b UNIQUE); INSERT INTO t2 VALUES('abc', 'def'); } do_test 3.2.2 { error_messages_v2 "SELECT a FROM t2" "DROP TABLE t2" } [list {*}{ SQLITE_ERROR {no such table: t2} SQLITE_ERROR {no such table: t2} }] finish_test