xref: /sqlite-3.40.0/test/schema.test (revision ea4d9e2d)
1# 2005 Jan 24
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# This file implements regression tests for SQLite library.
12#
13# This file tests the various conditions under which an SQLITE_SCHEMA
14# error should be returned.
15#
16# $Id: schema.test,v 1.7 2007/08/13 15:28:35 danielk1977 Exp $
17
18#---------------------------------------------------------------------
19# When any of the following types of SQL statements or actions are
20# executed, all pre-compiled statements are invalidated. An attempt
21# to execute an invalidated statement always returns SQLITE_SCHEMA.
22#
23# CREATE/DROP TABLE...................................schema-1.*
24# CREATE/DROP VIEW....................................schema-2.*
25# CREATE/DROP TRIGGER.................................schema-3.*
26# CREATE/DROP INDEX...................................schema-4.*
27# DETACH..............................................schema-5.*
28# Deleting a user-function............................schema-6.*
29# Deleting a collation sequence.......................schema-7.*
30# Setting or changing the authorization function......schema-8.*
31# Rollback of a DDL statement.........................schema-12.*
32#
33# Test cases schema-9.* and schema-10.* test some specific bugs
34# that came up during development.
35#
36# Test cases schema-11.* test that it is impossible to delete or
37# change a collation sequence or user-function while SQL statements
38# are executing. Adding new collations or functions is allowed.
39#
40
41set testdir [file dirname $argv0]
42source $testdir/tester.tcl
43
44do_test schema-1.1 {
45  set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL]
46  execsql {
47    CREATE TABLE abc(a, b, c);
48  }
49  sqlite3_step $::STMT
50} {SQLITE_ERROR}
51do_test schema-1.2 {
52  sqlite3_finalize $::STMT
53} {SQLITE_SCHEMA}
54do_test schema-1.3 {
55  set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL]
56  execsql {
57    DROP TABLE abc;
58  }
59  sqlite3_step $::STMT
60} {SQLITE_ERROR}
61do_test schema-1.4 {
62  sqlite3_finalize $::STMT
63} {SQLITE_SCHEMA}
64
65ifcapable view {
66  do_test schema-2.1 {
67    set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL]
68    execsql {
69      CREATE VIEW v1 AS SELECT * FROM sqlite_master;
70    }
71    sqlite3_step $::STMT
72  } {SQLITE_ERROR}
73  do_test schema-2.2 {
74    sqlite3_finalize $::STMT
75  } {SQLITE_SCHEMA}
76  do_test schema-2.3 {
77    set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL]
78    execsql {
79      DROP VIEW v1;
80    }
81    sqlite3_step $::STMT
82  } {SQLITE_ERROR}
83  do_test schema-2.4 {
84    sqlite3_finalize $::STMT
85  } {SQLITE_SCHEMA}
86}
87
88ifcapable trigger {
89  do_test schema-3.1 {
90    execsql {
91      CREATE TABLE abc(a, b, c);
92    }
93    set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL]
94    execsql {
95      CREATE TRIGGER abc_trig AFTER INSERT ON abc BEGIN
96        SELECT 1, 2, 3;
97      END;
98    }
99    sqlite3_step $::STMT
100  } {SQLITE_ERROR}
101  do_test schema-3.2 {
102    sqlite3_finalize $::STMT
103  } {SQLITE_SCHEMA}
104  do_test schema-3.3 {
105    set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL]
106    execsql {
107      DROP TRIGGER abc_trig;
108    }
109    sqlite3_step $::STMT
110  } {SQLITE_ERROR}
111  do_test schema-3.4 {
112    sqlite3_finalize $::STMT
113  } {SQLITE_SCHEMA}
114}
115
116do_test schema-4.1 {
117  catchsql {
118    CREATE TABLE abc(a, b, c);
119  }
120  set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL]
121  execsql {
122    CREATE INDEX abc_index ON abc(a);
123  }
124  sqlite3_step $::STMT
125} {SQLITE_ERROR}
126do_test schema-4.2 {
127  sqlite3_finalize $::STMT
128} {SQLITE_SCHEMA}
129do_test schema-4.3 {
130  set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL]
131  execsql {
132    DROP INDEX abc_index;
133  }
134  sqlite3_step $::STMT
135} {SQLITE_ERROR}
136do_test schema-4.4 {
137  sqlite3_finalize $::STMT
138} {SQLITE_SCHEMA}
139
140#---------------------------------------------------------------------
141# Tests 5.1 to 5.4 check that prepared statements are invalidated when
142# a database is DETACHed (but not when one is ATTACHed).
143#
144do_test schema-5.1 {
145  set sql {SELECT * FROM abc;}
146  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
147  execsql {
148    ATTACH 'test2.db' AS aux;
149  }
150  sqlite3_step $::STMT
151} {SQLITE_DONE}
152do_test schema-5.2 {
153  sqlite3_reset $::STMT
154} {SQLITE_OK}
155do_test schema-5.3 {
156  execsql {
157    DETACH aux;
158  }
159  sqlite3_step $::STMT
160} {SQLITE_ERROR}
161do_test schema-5.4 {
162  sqlite3_finalize $::STMT
163} {SQLITE_SCHEMA}
164
165#---------------------------------------------------------------------
166# Tests 6.* check that prepared statements are invalidated when
167# a user-function is deleted (but not when one is added).
168do_test schema-6.1 {
169  set sql {SELECT * FROM abc;}
170  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
171  db function hello_function {}
172  sqlite3_step $::STMT
173} {SQLITE_DONE}
174do_test schema-6.2 {
175  sqlite3_reset $::STMT
176} {SQLITE_OK}
177do_test schema-6.3 {
178  sqlite_delete_function $::DB hello_function
179  sqlite3_step $::STMT
180} {SQLITE_ERROR}
181do_test schema-6.4 {
182  sqlite3_finalize $::STMT
183} {SQLITE_SCHEMA}
184
185#---------------------------------------------------------------------
186# Tests 7.* check that prepared statements are invalidated when
187# a collation sequence is deleted (but not when one is added).
188#
189ifcapable utf16 {
190  do_test schema-7.1 {
191    set sql {SELECT * FROM abc;}
192    set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
193    add_test_collate $::DB 1 1 1
194    sqlite3_step $::STMT
195  } {SQLITE_DONE}
196  do_test schema-7.2 {
197    sqlite3_reset $::STMT
198  } {SQLITE_OK}
199  do_test schema-7.3 {
200    add_test_collate $::DB 0 0 0
201    sqlite3_step $::STMT
202  } {SQLITE_ERROR}
203  do_test schema-7.4 {
204    sqlite3_finalize $::STMT
205  } {SQLITE_SCHEMA}
206}
207
208#---------------------------------------------------------------------
209# Tests 8.1 and 8.2 check that prepared statements are invalidated when
210# the authorization function is set.
211#
212ifcapable auth {
213  do_test schema-8.1 {
214    set ::STMT [sqlite3_prepare $::DB {SELECT * FROM sqlite_master} -1 TAIL]
215    db auth {}
216    sqlite3_step $::STMT
217  } {SQLITE_ERROR}
218  do_test schema-8.3 {
219    sqlite3_finalize $::STMT
220  } {SQLITE_SCHEMA}
221}
222
223#---------------------------------------------------------------------
224# schema-9.1: Test that if a table is dropped by one database connection,
225#             other database connections are aware of the schema change.
226# schema-9.2: Test that if a view is dropped by one database connection,
227#             other database connections are aware of the schema change.
228#
229do_test schema-9.1 {
230  sqlite3 db2 test.db
231  execsql {
232    DROP TABLE abc;
233  } db2
234  db2 close
235  catchsql {
236    SELECT * FROM abc;
237  }
238} {1 {no such table: abc}}
239execsql {
240  CREATE TABLE abc(a, b, c);
241}
242ifcapable view {
243  do_test schema-9.2 {
244    execsql {
245      CREATE VIEW abcview AS SELECT * FROM abc;
246    }
247    sqlite3 db2 test.db
248    execsql {
249      DROP VIEW abcview;
250    } db2
251    db2 close
252    catchsql {
253      SELECT * FROM abcview;
254    }
255  } {1 {no such table: abcview}}
256}
257
258#---------------------------------------------------------------------
259# Test that if a CREATE TABLE statement fails because there are other
260# btree cursors open on the same database file it does not corrupt
261# the sqlite_master table.
262#
263# 2007-05-02: These tests have been overcome by events.  Open btree
264# cursors no longer block CREATE TABLE.  But there is no reason not
265# to keep the tests in the test suite.
266#
267do_test schema-10.1 {
268  execsql {
269    INSERT INTO abc VALUES(1, 2, 3);
270  }
271  set sql {SELECT * FROM abc}
272  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
273  sqlite3_step $::STMT
274} {SQLITE_ROW}
275do_test schema-10.2 {
276  catchsql {
277    CREATE TABLE t2(a, b, c);
278  }
279} {0 {}}
280do_test schema-10.3 {
281  sqlite3_finalize $::STMT
282} {SQLITE_OK}
283do_test schema-10.4 {
284  sqlite3 db2 test.db
285  execsql {
286    SELECT * FROM abc
287  } db2
288} {1 2 3}
289do_test schema-10.5 {
290  db2 close
291} {}
292
293#---------------------------------------------------------------------
294# Attempting to delete or replace a user-function or collation sequence
295# while there are active statements returns an SQLITE_BUSY error.
296#
297# schema-11.1 - 11.4: User function.
298# schema-11.5 - 11.8: Collation sequence.
299#
300do_test schema-11.1 {
301  db function tstfunc {}
302  set sql {SELECT * FROM abc}
303  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
304  sqlite3_step $::STMT
305} {SQLITE_ROW}
306do_test schema-11.2 {
307  sqlite_delete_function $::DB tstfunc
308} {SQLITE_BUSY}
309do_test schema-11.3 {
310  set rc [catch {
311    db function tstfunc {}
312  } msg]
313  list $rc $msg
314} {1 {Unable to delete/modify user-function due to active statements}}
315do_test schema-11.4 {
316  sqlite3_finalize $::STMT
317} {SQLITE_OK}
318do_test schema-11.5 {
319  db collate tstcollate {}
320  set sql {SELECT * FROM abc}
321  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
322  sqlite3_step $::STMT
323} {SQLITE_ROW}
324do_test schema-11.6 {
325  sqlite_delete_collation $::DB tstcollate
326} {SQLITE_BUSY}
327do_test schema-11.7 {
328  set rc [catch {
329    db collate tstcollate {}
330  } msg]
331  list $rc $msg
332} {1 {Unable to delete/modify collation sequence due to active statements}}
333do_test schema-11.8 {
334  sqlite3_finalize $::STMT
335} {SQLITE_OK}
336
337# The following demonstrates why statements need to be expired whenever
338# there is a rollback (explicit or otherwise).
339#
340do_test schema-12.1 {
341  # Begin a transaction and create a table. This increments
342  # the schema cookie. Then compile an SQL statement, using
343  # the current (incremented) value of the cookie.
344  execsql {
345    BEGIN;
346    CREATE TABLE t3(a, b, c);
347  }
348  set ::STMT [sqlite3_prepare $::DB "CREATE TABLE t4(a,b,c)" -1 TAIL]
349
350  # Rollback the transaction, resetting the schema cookie to the value
351  # it had at the start of this test case. Then create a table,
352  # incrementing the schema cookie.
353  execsql {
354    ROLLBACK;
355    CREATE TABLE t4(a, b, c);
356  }
357
358  # The schema cookie now has the same value as it did when SQL statement
359  # $::STMT was prepared. So unless it has been expired, it would be
360  # possible to run the "CREATE TABLE t4" statement and create a
361  # duplicate table.
362  list [sqlite3_step $::STMT] [sqlite3_finalize $::STMT]
363} {SQLITE_ERROR SQLITE_SCHEMA}
364
365finish_test
366