| # 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 or missing database} |
| 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 or missing database} |
| 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 or missing database} |
| 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 |