1# 2001 September 15
2#
3# The author disclaims copyright to this source code.  In place of
4# a legal notice, here is a blessing:
5#
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.
9#
10#***********************************************************************
11# Test that if sqlite3_prepare_v2() is used to prepare a query, the
12# error-message associated with an sqlite3_step() error is available
13# immediately. Whereas if sqlite3_prepare() is used, it is not available
14# until sqlite3_finalize() or sqlite3_reset() has been called.
15#
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
20set testprefix errmsg
21
22# Test organization:
23#
24#   errmsg-1.*         User-defined SQL function errors
25#   errmsg-2.*         Errors generated by the VDBE (constraint failures etc.)
26#   errmsg-3.*         SQLITE_SCHEMA and statement recompilation errors.
27#
28
29proc error_messages_worker {prepare sql schema} {
30  set ret [list]
31
32  set stmt [$prepare db $sql -1 dummy]
33  execsql $schema
34  lappend ret [sqlite3_step $stmt]
35  lappend ret [sqlite3_errmsg db]
36  lappend ret [sqlite3_finalize $stmt]
37  lappend ret [sqlite3_errmsg db]
38
39  set ret
40}
41
42proc error_messages_v2 {sql {schema {}}} {
43  error_messages_worker sqlite3_prepare_v2 $sql $schema
44}
45
46proc error_messages {sql {schema {}}} {
47  error_messages_worker sqlite3_prepare $sql $schema
48}
49
50proc sql_error {msg} { error $msg }
51db func sql_error sql_error
52
53#-------------------------------------------------------------------------
54# Test error messages returned by user-defined SQL functions.
55#
56do_test 1.1 {
57  error_messages "SELECT sql_error('custom message')"
58} [list {*}{
59    SQLITE_ERROR {SQL logic error}
60    SQLITE_ERROR {custom message}
61}]
62do_test 1.2 {
63  error_messages_v2 "SELECT sql_error('custom message')"
64} [list {*}{
65    SQLITE_ERROR {custom message}
66    SQLITE_ERROR {custom message}
67}]
68
69#-------------------------------------------------------------------------
70# Test error messages generated directly by VDBE code (e.g. constraint
71# failures).
72#
73do_execsql_test 2.1 {
74  CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
75  INSERT INTO t1 VALUES('abc', 'def');
76}
77do_test 2.2 {
78  error_messages "INSERT INTO t1 VALUES('ghi', 'def')"
79} [list {*}{
80    SQLITE_ERROR      {SQL logic error}
81    SQLITE_CONSTRAINT {UNIQUE constraint failed: t1.b}
82}]
83verify_ex_errcode 2.2b SQLITE_CONSTRAINT_UNIQUE
84do_test 2.3 {
85  error_messages_v2 "INSERT INTO t1 VALUES('ghi', 'def')"
86} [list {*}{
87    SQLITE_CONSTRAINT {UNIQUE constraint failed: t1.b}
88    SQLITE_CONSTRAINT {UNIQUE constraint failed: t1.b}
89}]
90verify_ex_errcode 2.3b SQLITE_CONSTRAINT_UNIQUE
91
92#-------------------------------------------------------------------------
93# Test SQLITE_SCHEMA errors. And, for _v2(), test that if the schema
94# change invalidates the SQL statement itself the error message is returned
95# correctly.
96#
97do_execsql_test 3.1.1 {
98  CREATE TABLE t2(a PRIMARY KEY, b UNIQUE);
99  INSERT INTO t2 VALUES('abc', 'def');
100}
101do_test 3.1.2 {
102  error_messages "SELECT a FROM t2" "DROP TABLE t2"
103} [list {*}{
104    SQLITE_ERROR {SQL logic error}
105    SQLITE_SCHEMA {database schema has changed}
106}]
107do_execsql_test 3.2.1 {
108  CREATE TABLE t2(a PRIMARY KEY, b UNIQUE);
109  INSERT INTO t2 VALUES('abc', 'def');
110}
111do_test 3.2.2 {
112  error_messages_v2 "SELECT a FROM t2" "DROP TABLE t2"
113} [list {*}{
114    SQLITE_ERROR {no such table: t2}
115    SQLITE_ERROR {no such table: t2}
116}]
117
118finish_test
119