xref: /sqlite-3.40.0/test/vtab_shared.test (revision a23bc8a3)
1113e545fSdanielk1977# 2007 April 16
2113e545fSdanielk1977#
3113e545fSdanielk1977# The author disclaims copyright to this source code.  In place of
4113e545fSdanielk1977# a legal notice, here is a blessing:
5113e545fSdanielk1977#
6113e545fSdanielk1977#    May you do good and not evil.
7113e545fSdanielk1977#    May you find forgiveness for yourself and forgive others.
8113e545fSdanielk1977#    May you share freely, never taking more than you give.
9113e545fSdanielk1977#
10113e545fSdanielk1977#***********************************************************************
11113e545fSdanielk1977# This file tests interactions between the virtual table and
12113e545fSdanielk1977# shared-schema functionality.
13113e545fSdanielk1977#
14595a523aSdanielk1977# $Id: vtab_shared.test,v 1.3 2009/07/24 17:58:53 danielk1977 Exp $
15113e545fSdanielk1977
16113e545fSdanielk1977set testdir [file dirname $argv0]
17113e545fSdanielk1977source $testdir/tester.tcl
18*d88e521fSdanset testprefix vtab_shared
19113e545fSdanielk1977
20113e545fSdanielk1977ifcapable !vtab||!shared_cache {
21113e545fSdanielk1977  finish_test
22113e545fSdanielk1977  return
23113e545fSdanielk1977}
24113e545fSdanielk1977
25113e545fSdanielk1977db close
26113e545fSdanielk1977sqlite3_enable_shared_cache 1
27113e545fSdanielk1977sqlite3 db  test.db
28595a523aSdanielk1977sqlite3 db2 test.db
29113e545fSdanielk1977
30113e545fSdanielk1977do_test vtab_shared-1.1 {
31113e545fSdanielk1977  register_echo_module [sqlite3_connection_pointer db]
32595a523aSdanielk1977  execsql {
33595a523aSdanielk1977    CREATE TABLE t0(a, b, c);
34595a523aSdanielk1977    INSERT INTO t0 VALUES(1, 2, 3);
35113e545fSdanielk1977    CREATE VIRTUAL TABLE t1 USING echo(t0);
36113e545fSdanielk1977  }
37595a523aSdanielk1977} {}
38113e545fSdanielk1977
39113e545fSdanielk1977do_test vtab_shared-1.2 {
40595a523aSdanielk1977  execsql { SELECT * FROM t1 } db
41595a523aSdanielk1977} {1 2 3}
42595a523aSdanielk1977
43595a523aSdanielk1977# Fails because the 'echo' module has not been registered with connection db2
44595a523aSdanielk1977do_test vtab_shared-1.3 {
45595a523aSdanielk1977  catchsql { SELECT * FROM t1 } db2
46595a523aSdanielk1977} {1 {no such module: echo}}
47595a523aSdanielk1977
48595a523aSdanielk1977do_test vtab_shared-1.4 {
49595a523aSdanielk1977  execsql { SELECT * FROM t0 } db2
50595a523aSdanielk1977} {1 2 3}
51595a523aSdanielk1977
52595a523aSdanielk1977do_test vtab_shared-1.5 {
53595a523aSdanielk1977  register_echo_module [sqlite3_connection_pointer db2]
54595a523aSdanielk1977  execsql { SELECT * FROM t1 } db
55595a523aSdanielk1977} {1 2 3}
56595a523aSdanielk1977
57595a523aSdanielk1977# Works after the module is registered with db2
58595a523aSdanielk1977do_test vtab_shared-1.6 {
59595a523aSdanielk1977  execsql { SELECT * FROM t1 } db2
60595a523aSdanielk1977} {1 2 3}
61595a523aSdanielk1977
62595a523aSdanielk1977# Set a write-lock on table t0 using connection [db]. Then try to read from
63595a523aSdanielk1977# virtual table t1 using [db2]. That this returns an SQLITE_LOCKED error
64595a523aSdanielk1977# shows that the correct sqlite3_vtab is being used.
65595a523aSdanielk1977#
66595a523aSdanielk1977do_test vtab_shared-1.8.1 {
67595a523aSdanielk1977  execsql {
68595a523aSdanielk1977    BEGIN;
69595a523aSdanielk1977    INSERT INTO t1 VALUES(4, 5, 6);
70113e545fSdanielk1977    SELECT * FROM t1;
71113e545fSdanielk1977  }
72595a523aSdanielk1977} {1 2 3 4 5 6}
73595a523aSdanielk1977do_test vtab_shared-1.8.2 {
74595a523aSdanielk1977  catchsql { SELECT * FROM t1 } db2
75595a523aSdanielk1977} {1 {database table is locked}}
76595a523aSdanielk1977do_test vtab_shared-1.8.3 {
77595a523aSdanielk1977  catchsql { SELECT *  FROM t0 } db2
78595a523aSdanielk1977} {1 {database table is locked: t0}}
79595a523aSdanielk1977do_test vtab_shared-1.8.4 {
80595a523aSdanielk1977  execsql { SELECT * FROM t0 } db
81595a523aSdanielk1977} {1 2 3 4 5 6}
82595a523aSdanielk1977do_test vtab_shared-1.8.5 {
83595a523aSdanielk1977  execsql { COMMIT } db
84595a523aSdanielk1977  execsql { SELECT *  FROM t1 } db2
85595a523aSdanielk1977} {1 2 3 4 5 6}
86595a523aSdanielk1977
87595a523aSdanielk1977# While a SELECT is active on virtual table t1 via connection [db], close
88595a523aSdanielk1977# [db2]. This causes the schema to be reset internally. Verify that this
89595a523aSdanielk1977# does not cause a problem.
90595a523aSdanielk1977#
91595a523aSdanielk1977foreach {iTest dbSelect dbClose} {
92595a523aSdanielk1977  1 db  db2
93595a523aSdanielk1977  2 db  db2
94595a523aSdanielk1977  3 db2 db
95595a523aSdanielk1977} {
96595a523aSdanielk1977  do_test vtab_shared-1.9.$iTest {
97595a523aSdanielk1977    set res [list]
98595a523aSdanielk1977    $dbSelect eval { SELECT * FROM t1 } {
99595a523aSdanielk1977      if {$a == 1} {$dbClose close}
100595a523aSdanielk1977      lappend res $a $b $c
101595a523aSdanielk1977    }
102595a523aSdanielk1977    sqlite3 $dbClose test.db
103595a523aSdanielk1977    register_echo_module [sqlite3_connection_pointer $dbClose]
104595a523aSdanielk1977    set res
105595a523aSdanielk1977  } {1 2 3 4 5 6}
106595a523aSdanielk1977}
107595a523aSdanielk1977
108595a523aSdanielk1977# Ensure that it is not possible for one connection to DROP a virtual
109595a523aSdanielk1977# table while a second connection is reading from the database.
110595a523aSdanielk1977#
111595a523aSdanielk1977do_test vtab_shared-1.10 {
112595a523aSdanielk1977  db eval { SELECT * FROM t1 } {
113595a523aSdanielk1977    set error [catchsql { DROP TABLE t1 } db2]
114595a523aSdanielk1977    break
115595a523aSdanielk1977  }
116595a523aSdanielk1977  set error
117595a523aSdanielk1977} {1 {database table is locked: sqlite_master}}
118595a523aSdanielk1977
119595a523aSdanielk1977do_test vtab_shared-1.11 {
120595a523aSdanielk1977  execsql {
121595a523aSdanielk1977    CREATE VIRTUAL TABLE t2 USING echo(t0);
122595a523aSdanielk1977    CREATE VIRTUAL TABLE t3 USING echo(t0);
123595a523aSdanielk1977  }
124595a523aSdanielk1977  execsql { SELECT * FROM t3 } db2
125595a523aSdanielk1977} {1 2 3 4 5 6}
126595a523aSdanielk1977
1272f56da3fSdanifcapable compound {
128595a523aSdanielk1977  do_test vtab_shared-1.12.1 {
129595a523aSdanielk1977    db close
130595a523aSdanielk1977    execsql {
131595a523aSdanielk1977      SELECT * FROM t1 UNION ALL
132595a523aSdanielk1977      SELECT * FROM t2 UNION ALL
133595a523aSdanielk1977      SELECT * FROM t3
134595a523aSdanielk1977    } db2
135595a523aSdanielk1977  } {1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6}
136595a523aSdanielk1977  do_test vtab_shared-1.12.2 {
137595a523aSdanielk1977    sqlite3 db test.db
138595a523aSdanielk1977    register_echo_module [sqlite3_connection_pointer db]
139595a523aSdanielk1977    execsql {
140595a523aSdanielk1977      SELECT * FROM t1 UNION ALL
141595a523aSdanielk1977      SELECT * FROM t2 UNION ALL
142595a523aSdanielk1977      SELECT * FROM t3
143595a523aSdanielk1977    } db
144595a523aSdanielk1977  } {1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6}
1452f56da3fSdan}
146595a523aSdanielk1977
147595a523aSdanielk1977# Try a rename or two.
148595a523aSdanielk1977#
149856ef1a5Sdanifcapable altertable {
150595a523aSdanielk1977  do_test vtab_shared-1.13.1 {
151595a523aSdanielk1977    execsql { ALTER TABLE t1 RENAME TO t4 }
152595a523aSdanielk1977    execsql { SELECT * FROM t4 } db
153595a523aSdanielk1977  } {1 2 3 4 5 6}
154595a523aSdanielk1977  do_test vtab_shared-1.13.2 {
155595a523aSdanielk1977    execsql { SELECT * FROM t4 } db2
156595a523aSdanielk1977  } {1 2 3 4 5 6}
157595a523aSdanielk1977  do_test vtab_shared-1.13.3 {
158595a523aSdanielk1977    execsql { ALTER TABLE t2 RENAME TO t5 }
159595a523aSdanielk1977    execsql { SELECT * FROM t4 } db2
160595a523aSdanielk1977  } {1 2 3 4 5 6}
161856ef1a5Sdan}
162595a523aSdanielk1977
163595a523aSdanielk1977# Try an UPDATE/INSERT/DELETE on a shared vtab as the first statement after a
164595a523aSdanielk1977# schema is loaded.
165595a523aSdanielk1977do_test vtab_shared_1.14.1 {
166595a523aSdanielk1977  db2 close
167595a523aSdanielk1977  sqlite3 db2 test.db
168595a523aSdanielk1977  register_echo_module [sqlite3_connection_pointer db2]
169595a523aSdanielk1977  execsql { SELECT * FROM t3 }
170595a523aSdanielk1977} {1 2 3 4 5 6}
171595a523aSdanielk1977do_test vtab_shared_1.14.2 {
172595a523aSdanielk1977  execsql {
173595a523aSdanielk1977    UPDATE t3 SET c = 'six' WHERE c = 6;
174595a523aSdanielk1977    SELECT * FROM t3;
175595a523aSdanielk1977  } db2
176595a523aSdanielk1977} {1 2 3 4 5 six}
177595a523aSdanielk1977do_test vtab_shared_1.14.3 {
178595a523aSdanielk1977  db2 close
179595a523aSdanielk1977  sqlite3 db2 test.db
180595a523aSdanielk1977  register_echo_module [sqlite3_connection_pointer db2]
181595a523aSdanielk1977  execsql { SELECT * FROM t3 }
182595a523aSdanielk1977} {1 2 3 4 5 six}
183595a523aSdanielk1977do_test vtab_shared_1.14.4 {
184595a523aSdanielk1977  execsql {
185595a523aSdanielk1977    DELETE FROM t3 WHERE c = 'six';
186595a523aSdanielk1977    SELECT * FROM t3;
187595a523aSdanielk1977  } db2
188595a523aSdanielk1977} {1 2 3}
189595a523aSdanielk1977do_test vtab_shared_1.14.5 {
190595a523aSdanielk1977  db2 close
191595a523aSdanielk1977  sqlite3 db2 test.db
192595a523aSdanielk1977  register_echo_module [sqlite3_connection_pointer db2]
193595a523aSdanielk1977  execsql { SELECT * FROM t3 }
194595a523aSdanielk1977} {1 2 3}
195595a523aSdanielk1977do_test vtab_shared_1.14.6 {
196595a523aSdanielk1977  execsql {
197595a523aSdanielk1977    INSERT INTO t3 VALUES(4, 5, 6);
198595a523aSdanielk1977    SELECT * FROM t3;
199595a523aSdanielk1977  } db2
200595a523aSdanielk1977} {1 2 3 4 5 6}
201595a523aSdanielk1977
202595a523aSdanielk1977do_test vtab_shared_1.15.1 {
203595a523aSdanielk1977  db2 close
204595a523aSdanielk1977  sqlite3 db2 test.db
205595a523aSdanielk1977  register_echo_module [sqlite3_connection_pointer db2]
206595a523aSdanielk1977  execsql {
207595a523aSdanielk1977    UPDATE t3 SET c = 'six' WHERE c = 6;
208595a523aSdanielk1977    SELECT * FROM t3;
209595a523aSdanielk1977  } db2
210595a523aSdanielk1977} {1 2 3 4 5 six}
211595a523aSdanielk1977do_test vtab_shared_1.15.2 {
212595a523aSdanielk1977  db2 close
213595a523aSdanielk1977  sqlite3 db2 test.db
214595a523aSdanielk1977  register_echo_module [sqlite3_connection_pointer db2]
215595a523aSdanielk1977  execsql {
216595a523aSdanielk1977    DELETE FROM t3 WHERE c = 'six';
217595a523aSdanielk1977    SELECT * FROM t3;
218595a523aSdanielk1977  } db2
219595a523aSdanielk1977} {1 2 3}
220595a523aSdanielk1977do_test vtab_shared_1.15.3 {
221595a523aSdanielk1977  db2 close
222595a523aSdanielk1977  sqlite3 db2 test.db
223595a523aSdanielk1977  register_echo_module [sqlite3_connection_pointer db2]
224595a523aSdanielk1977  execsql {
225595a523aSdanielk1977    INSERT INTO t3 VALUES(4, 5, 6);
226595a523aSdanielk1977    SELECT * FROM t3;
227595a523aSdanielk1977  }
228595a523aSdanielk1977} {1 2 3 4 5 6}
229113e545fSdanielk1977
230113e545fSdanielk1977db close
231595a523aSdanielk1977db2 close
232*d88e521fSdan
233*d88e521fSdan#---------------------------------------------------------------
234*d88e521fSdan# Test calling sqlite3_close() with vtabs on the disconnect list.
235*d88e521fSdan#
236*d88e521fSdanifcapable rtree {
237*d88e521fSdan  reset_db
238*d88e521fSdan  do_test 2.1.1 {
239*d88e521fSdan    sqlite3 db  test.db
240*d88e521fSdan    sqlite3 db2 test.db
241*d88e521fSdan
242*d88e521fSdan    # Create a virtual table using [db].
243*d88e521fSdan    execsql {
244*d88e521fSdan      CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
245*d88e521fSdan      INSERT INTO rt VALUES(1, 2 ,3);
246*d88e521fSdan      SELECT * FROM rt;
247*d88e521fSdan    }
248*d88e521fSdan
249*d88e521fSdan    # Drop the virtual table using [db2]. The sqlite3_vtab object belonging
250*d88e521fSdan    # to [db] is moved to the sqlite3.pDisconnect list.
251*d88e521fSdan    execsql { DROP TABLE rt } db2
252*d88e521fSdan
253*d88e521fSdan    # Immediately close [db]. At one point this would fail due to the
254*d88e521fSdan    # unfinalized statements held by the un-xDisconnect()ed sqlite3_vtab.
255*d88e521fSdan    db close
256*d88e521fSdan  } {}
257*d88e521fSdan  db2 close
258*d88e521fSdan}
259*d88e521fSdan
260*d88e521fSdanifcapable fts3 {
261*d88e521fSdan  # Same test as above, except using fts3 instead of rtree.
262*d88e521fSdan  reset_db
263*d88e521fSdan  do_test 2.2.1 {
264*d88e521fSdan    sqlite3 db  test.db
265*d88e521fSdan    sqlite3 db2 test.db
266*d88e521fSdan    execsql {
267*d88e521fSdan      CREATE VIRTUAL TABLE ft USING fts3;
268*d88e521fSdan      INSERT INTO ft VALUES('hello world');
269*d88e521fSdan      SELECT * FROM ft;
270*d88e521fSdan    }
271*d88e521fSdan    execsql { DROP TABLE ft } db2
272*d88e521fSdan    db close
273*d88e521fSdan  } {}
274*d88e521fSdan  db2 close
275*d88e521fSdan}
276*d88e521fSdan
277113e545fSdanielk1977sqlite3_enable_shared_cache 0
278113e545fSdanielk1977finish_test
279