xref: /sqlite-3.40.0/test/misc7.test (revision 0227d930)
1a713f2c3Sdanielk1977# 2006 September 4
2a713f2c3Sdanielk1977#
3a713f2c3Sdanielk1977# The author disclaims copyright to this source code.  In place of
4a713f2c3Sdanielk1977# a legal notice, here is a blessing:
5a713f2c3Sdanielk1977#
6a713f2c3Sdanielk1977#    May you do good and not evil.
7a713f2c3Sdanielk1977#    May you find forgiveness for yourself and forgive others.
8a713f2c3Sdanielk1977#    May you share freely, never taking more than you give.
9a713f2c3Sdanielk1977#
10a713f2c3Sdanielk1977#***********************************************************************
11a713f2c3Sdanielk1977# This file implements regression tests for SQLite library.
12a713f2c3Sdanielk1977#
13e64ca7baSdrh# $Id: misc7.test,v 1.29 2009/07/16 18:21:18 drh Exp $
14a713f2c3Sdanielk1977
15a713f2c3Sdanielk1977set testdir [file dirname $argv0]
16a713f2c3Sdanielk1977source $testdir/tester.tcl
17a688ca5eSdanset testprefix misc7
18a713f2c3Sdanielk1977
19afcf9bd8Sdanif {[clang_sanitize_address]==0} {
2001495b99Sdrh  do_test misc7-1-misuse {
2101495b99Sdrh    c_misuse_test
2201495b99Sdrh  } {}
23afcf9bd8Sdan}
24a713f2c3Sdanielk1977
25a713f2c3Sdanielk1977do_test misc7-2 {
26a713f2c3Sdanielk1977  c_realloc_test
27a713f2c3Sdanielk1977} {}
28a713f2c3Sdanielk1977
29a713f2c3Sdanielk1977do_test misc7-3 {
30a713f2c3Sdanielk1977  c_collation_test
31a713f2c3Sdanielk1977} {}
32a713f2c3Sdanielk1977
3369b637b5Sdanielk1977# Try to open a directory:
3469b637b5Sdanielk1977#
3569b637b5Sdanielk1977do_test misc7-4 {
36fda06befSmistachkin  delete_file mydir
3769b637b5Sdanielk1977  file mkdir mydir
3869b637b5Sdanielk1977  set rc [catch {
3969b637b5Sdanielk1977    sqlite3 db2 ./mydir
4069b637b5Sdanielk1977  } msg]
4169b637b5Sdanielk1977  list $rc $msg
4269b637b5Sdanielk1977} {1 {unable to open database file}}
4369b637b5Sdanielk1977
4485b623f2Sdrh# Try to open a file with a directory where its journal file should be.
4569b637b5Sdanielk1977#
46b8fff29cSdanif {[atomic_batch_write test.db]==0} {
4769b637b5Sdanielk1977  do_test misc7-5 {
48fda06befSmistachkin    delete_file mydir
4969b637b5Sdanielk1977    file mkdir mydir-journal
5069b637b5Sdanielk1977    sqlite3 db2 ./mydir
5169b637b5Sdanielk1977    catchsql {
5269b637b5Sdanielk1977      CREATE TABLE abc(a, b, c);
5369b637b5Sdanielk1977    } db2
5469b637b5Sdanielk1977  } {1 {unable to open database file}}
5569b637b5Sdanielk1977  db2 close
56b8fff29cSdan}
5769b637b5Sdanielk1977
5869b637b5Sdanielk1977#--------------------------------------------------------------------
5969b637b5Sdanielk1977# The following tests, misc7-6.* test the libraries behaviour when
6069b637b5Sdanielk1977# it cannot open a file. To force this condition, we use up all the
6169b637b5Sdanielk1977# file-descriptors before running sqlite. This probably only works
6269b637b5Sdanielk1977# on unix.
6369b637b5Sdanielk1977#
6469b637b5Sdanielk1977
6569b637b5Sdanielk1977proc use_up_files {} {
6669b637b5Sdanielk1977  set ret [list]
6769b637b5Sdanielk1977  catch {
6869b637b5Sdanielk1977    while 1 { lappend ret [open test.db] }
6969b637b5Sdanielk1977  }
7069b637b5Sdanielk1977  return $ret
7169b637b5Sdanielk1977}
7269b637b5Sdanielk1977
7395b289b6Sdanielk1977proc do_fileopen_test {prefix sql} {
7469b637b5Sdanielk1977  set fd_list [use_up_files]
7569b637b5Sdanielk1977  set ::go 1
7669b637b5Sdanielk1977  set ::n 1
7795b289b6Sdanielk1977  set ::sql $sql
7869b637b5Sdanielk1977  while {$::go} {
7969b637b5Sdanielk1977    catch {db close}
8095b289b6Sdanielk1977    do_test ${prefix}.${::n} {
8169b637b5Sdanielk1977      set rc [catch {
8269b637b5Sdanielk1977        sqlite db test.db
8395b289b6Sdanielk1977        db eval $::sql
8469b637b5Sdanielk1977      } msg]
8569b637b5Sdanielk1977      if {$rc == 0} {set ::go 0}
8669b637b5Sdanielk1977
8795b289b6Sdanielk1977      expr {$rc == 0 || ($rc == 1 && [string first unable $msg]==0)}
8869b637b5Sdanielk1977    } 1
8969b637b5Sdanielk1977
9069b637b5Sdanielk1977    close [lindex $fd_list 0]
9169b637b5Sdanielk1977    set fd_list [lrange $fd_list 1 end]
9269b637b5Sdanielk1977    incr ::n
9369b637b5Sdanielk1977  }
9469b637b5Sdanielk1977  foreach fd $fd_list {
9569b637b5Sdanielk1977    close $fd
9669b637b5Sdanielk1977  }
97b5584c0cSdanielk1977  db close
9895b289b6Sdanielk1977}
9995b289b6Sdanielk1977
10095b289b6Sdanielk1977execsql { CREATE TABLE abc(a PRIMARY KEY, b, c); }
10195b289b6Sdanielk1977db close
10295b289b6Sdanielk1977
1030b3d55d4Sdrhif {$tcl_platform(platform)!="windows"} {
10495b289b6Sdanielk1977  do_fileopen_test misc7-6.1 {
10595b289b6Sdanielk1977    BEGIN;
10695b289b6Sdanielk1977    INSERT INTO abc VALUES(1, 2, 3);
10795b289b6Sdanielk1977    INSERT INTO abc VALUES(2, 3, 4);
10895b289b6Sdanielk1977    INSERT INTO abc SELECT a+2, b, c FROM abc;
10995b289b6Sdanielk1977    COMMIT;
11095b289b6Sdanielk1977  }
11195b289b6Sdanielk1977
11295b289b6Sdanielk1977  do_fileopen_test misc7-6.2 {
11395b289b6Sdanielk1977    PRAGMA temp.cache_size = 1000;
11495b289b6Sdanielk1977  }
1150b3d55d4Sdrh}
11695b289b6Sdanielk1977
117b5584c0cSdanielk1977#
118b5584c0cSdanielk1977# End of tests for out-of-file-descriptors condition.
119b5584c0cSdanielk1977#--------------------------------------------------------------------
120b5584c0cSdanielk1977
121073d3efaSdrhsqlite3 db test.db
1220b3d55d4Sdrhexecsql {
1230b3d55d4Sdrh  DELETE FROM abc;
1240b3d55d4Sdrh  INSERT INTO abc VALUES(1, 2, 3);
1250b3d55d4Sdrh  INSERT INTO abc VALUES(2, 3, 4);
1260b3d55d4Sdrh  INSERT INTO abc SELECT a+2, b, c FROM abc;
1270b3d55d4Sdrh}
1280b3d55d4Sdrh
1290b3d55d4Sdrh
130b5584c0cSdanielk1977#--------------------------------------------------------------------
131b5584c0cSdanielk1977# Test that the sqlite3_busy_timeout call seems to delay approximately
132b5584c0cSdanielk1977# the right amount of time.
133b5584c0cSdanielk1977#
13495b289b6Sdanielk1977do_test misc7-7.0 {
135b5584c0cSdanielk1977  sqlite3 db2 test.db
136b5584c0cSdanielk1977  sqlite3_busy_timeout [sqlite3_connection_pointer db] 2000
137b5584c0cSdanielk1977  execsql {
138b5584c0cSdanielk1977    BEGIN EXCLUSIVE;
139b5584c0cSdanielk1977  } db2
140b5584c0cSdanielk1977
141b5584c0cSdanielk1977  # Now db2 has an exclusive lock on the database file, and db has
142b5584c0cSdanielk1977  # a busy-timeout of 2000 milliseconds. So check that trying to
143b5584c0cSdanielk1977  # access the database using connection db delays for at least 1500 ms.
144b5584c0cSdanielk1977  #
145073d3efaSdrh  set tm [time {
146073d3efaSdrh    set result [catchsql {
147b5584c0cSdanielk1977        SELECT * FROM sqlite_master;
148073d3efaSdrh      } db]
149073d3efaSdrh  }]
150073d3efaSdrh  set delay [lindex $tm 0]  ;# In microseconds
1510b3d55d4Sdrh  lappend result [expr {$delay>1500000 && $delay<4000000}]
152073d3efaSdrh} {1 {database is locked} 1}
153b5584c0cSdanielk1977db2 close
154b5584c0cSdanielk1977
155b5584c0cSdanielk1977#--------------------------------------------------------------------
156b5584c0cSdanielk1977# Test that nothing goes horribly wrong when attaching a database
157b5584c0cSdanielk1977# after the omit_readlock pragma has been exercised.
158b5584c0cSdanielk1977#
15933f111dcSdrh# Note:  The PRAGMA omit_readlock was an early hack to disable the
16033f111dcSdrh# fcntl() calls for read-only databases so that read-only databases could
16133f111dcSdrh# be read on broken NFS systems.  That pragma has now been removed.
16233f111dcSdrh# (Use the unix-none VFS as a replacement, if needed.)  But these tests
16333f111dcSdrh# do not really depend on omit_readlock, so we left them in place.
16433f111dcSdrh#
165935ed5eaSdanielk1977do_test misc7-7.1 {
166fda06befSmistachkin  forcedelete test2.db
167fda06befSmistachkin  forcedelete test2.db-journal
168b5584c0cSdanielk1977  execsql {
169b5584c0cSdanielk1977    PRAGMA omit_readlock = 1;
170b5584c0cSdanielk1977    ATTACH 'test2.db' AS aux;
171b5584c0cSdanielk1977    CREATE TABLE aux.hello(world);
172b5584c0cSdanielk1977    SELECT name FROM aux.sqlite_master;
173b5584c0cSdanielk1977  }
174b5584c0cSdanielk1977} {hello}
175935ed5eaSdanielk1977do_test misc7-7.2 {
176935ed5eaSdanielk1977  execsql {
177935ed5eaSdanielk1977    DETACH aux;
178935ed5eaSdanielk1977  }
179935ed5eaSdanielk1977} {}
1800371f1b2Sdanielk1977do_test misc7-7.3 {
1810371f1b2Sdanielk1977  db close
1820371f1b2Sdanielk1977  sqlite3 db test.db -readonly 1
1830371f1b2Sdanielk1977  execsql {
1840371f1b2Sdanielk1977    PRAGMA omit_readlock = 1;
1850371f1b2Sdanielk1977    ATTACH 'test2.db' AS aux;
1860371f1b2Sdanielk1977    SELECT name FROM aux.sqlite_master;
1870371f1b2Sdanielk1977    SELECT name FROM aux.sqlite_master;
1880371f1b2Sdanielk1977  }
1890371f1b2Sdanielk1977} {hello hello}
1900371f1b2Sdanielk1977do_test misc7-7.3 {
1910371f1b2Sdanielk1977  db close
1920371f1b2Sdanielk1977  sqlite3 db test.db
1930371f1b2Sdanielk1977  set ::DB [sqlite3_connection_pointer db]
1940371f1b2Sdanielk1977  list
1950371f1b2Sdanielk1977} {}
196b5584c0cSdanielk1977
19724168728Sdanielk1977# Test the UTF-16 version of the "out of memory" message (used when
19824168728Sdanielk1977# malloc fails during sqlite3_open() ).
199b5584c0cSdanielk1977#
200b5584c0cSdanielk1977ifcapable utf16 {
201b5584c0cSdanielk1977  do_test misc7-8 {
202b5584c0cSdanielk1977    encoding convertfrom unicode [sqlite3_errmsg16 0x00000000]
203b5584c0cSdanielk1977  } {out of memory}
204b5584c0cSdanielk1977}
205b5584c0cSdanielk1977
206935ed5eaSdanielk1977do_test misc7-9 {
207935ed5eaSdanielk1977  execsql {
208935ed5eaSdanielk1977    SELECT *
209935ed5eaSdanielk1977    FROM (SELECT name+1 AS one FROM sqlite_master LIMIT 1 OFFSET 1)
210935ed5eaSdanielk1977    WHERE one LIKE 'hello%';
211935ed5eaSdanielk1977  }
212935ed5eaSdanielk1977} {}
213b5584c0cSdanielk1977
214935ed5eaSdanielk1977#--------------------------------------------------------------------
215780b1d94Sdanielk1977# Improve coverage for vtab code.
216935ed5eaSdanielk1977#
217935ed5eaSdanielk1977ifcapable vtab {
218780b1d94Sdanielk1977  # Run some debug code to improve reported coverage
219780b1d94Sdanielk1977  #
220780b1d94Sdanielk1977
221780b1d94Sdanielk1977  # set sqlite_where_trace 1
222935ed5eaSdanielk1977  do_test misc7-10 {
223935ed5eaSdanielk1977    register_echo_module [sqlite3_connection_pointer db]
224935ed5eaSdanielk1977    execsql {
225935ed5eaSdanielk1977      CREATE VIRTUAL TABLE t1 USING echo(abc);
226935ed5eaSdanielk1977      SELECT a FROM t1 WHERE a = 1 ORDER BY b;
227935ed5eaSdanielk1977    }
228935ed5eaSdanielk1977  } {1}
229780b1d94Sdanielk1977  set sqlite_where_trace 0
230b042d921Sdrh  do_catchsql_test misc7-10.1 {
231b042d921Sdrh    INSERT INTO t1(a,b,c) VALUES(12345,2,3) ON CONFLICT(a) DO NOTHING;
232b042d921Sdrh  } {1 {UPSERT not implemented for virtual table "t1"}}
233780b1d94Sdanielk1977
234780b1d94Sdanielk1977  # Specify an ORDER BY clause that cannot be indexed.
235780b1d94Sdanielk1977  do_test misc7-11 {
236780b1d94Sdanielk1977    execsql {
237780b1d94Sdanielk1977      SELECT t1.a, t2.a FROM t1, t1 AS t2 ORDER BY 2 LIMIT 1;
238935ed5eaSdanielk1977    }
239780b1d94Sdanielk1977  } {1 1}
240780b1d94Sdanielk1977
241780b1d94Sdanielk1977  # The whole point of this is to test an error code other than
242780b1d94Sdanielk1977  # SQLITE_NOMEM from the vtab xBestIndex callback.
243780b1d94Sdanielk1977  #
244780b1d94Sdanielk1977  do_ioerr_test misc7-12 -tclprep {
245780b1d94Sdanielk1977    sqlite3 db2 test.db
246780b1d94Sdanielk1977    register_echo_module [sqlite3_connection_pointer db2]
247780b1d94Sdanielk1977    db2 eval {
248780b1d94Sdanielk1977      CREATE TABLE abc(a PRIMARY KEY, b, c);
249780b1d94Sdanielk1977      INSERT INTO abc VALUES(1, 2, 3);
250780b1d94Sdanielk1977      CREATE VIRTUAL TABLE t1 USING echo(abc);
251780b1d94Sdanielk1977    }
252780b1d94Sdanielk1977    db2 close
253780b1d94Sdanielk1977  } -tclbody {
254780b1d94Sdanielk1977    register_echo_module [sqlite3_connection_pointer db]
255780b1d94Sdanielk1977    execsql {SELECT * FROM t1 WHERE a = 1;}
256780b1d94Sdanielk1977  }
257780b1d94Sdanielk1977
258780b1d94Sdanielk1977  # The case where the virtual table module returns a very large number
259780b1d94Sdanielk1977  # as the cost of a scan (greater than SQLITE_BIG_DOUBLE in the code).
260780b1d94Sdanielk1977  #
261780b1d94Sdanielk1977  do_test misc7-13 {
262780b1d94Sdanielk1977    sqlite3 db test.db
263780b1d94Sdanielk1977    register_echo_module [sqlite3_connection_pointer db]
264780b1d94Sdanielk1977    set ::echo_module_cost 2.0e+99
265780b1d94Sdanielk1977    execsql {SELECT * FROM t1 WHERE a = 1;}
266780b1d94Sdanielk1977  } {1 2 3}
267780b1d94Sdanielk1977  unset ::echo_module_cost
268780b1d94Sdanielk1977}
269780b1d94Sdanielk1977
27095b289b6Sdanielk1977db close
271fda06befSmistachkinforcedelete test.db
272fda06befSmistachkinforcedelete test.db-journal
27395b289b6Sdanielk1977sqlite3 db test.db
27495b289b6Sdanielk1977
27595b289b6Sdanielk1977ifcapable explain {
276d3e17ffbSdan  do_execsql_test misc7-14.0 {
27795b289b6Sdanielk1977    CREATE TABLE abc(a PRIMARY KEY, b, c);
278d3e17ffbSdan  }
279d3e17ffbSdan  do_eqp_test misc7-14.1 {
280d3e17ffbSdan    SELECT * FROM abc AS t2 WHERE rowid = 1;
281659816e9Sdan  } {
282d3e17ffbSdan  QUERY PLAN
283*0227d930Sdrh  `--SEARCH t2 USING INTEGER PRIMARY KEY (rowid=?)
28495b289b6Sdanielk1977}
285d3e17ffbSdan  do_eqp_test misc7-14.2 {
286d3e17ffbSdan    SELECT * FROM abc AS t2 WHERE a = 1;
287d3e17ffbSdan} {
288d3e17ffbSdan  QUERY PLAN
289*0227d930Sdrh  `--SEARCH t2 USING INDEX sqlite_autoindex_abc_1 (a=?)
29095b289b6Sdanielk1977}
291d3e17ffbSdan  do_eqp_test misc7-14.3 {
292d3e17ffbSdan    SELECT * FROM abc AS t2 ORDER BY a;
293d3e17ffbSdan  } {
294d3e17ffbSdan  QUERY PLAN
295*0227d930Sdrh  `--SCAN t2 USING INDEX sqlite_autoindex_abc_1
296701bb3b4Sdrh}
29795b289b6Sdanielk1977}
29869b637b5Sdanielk1977
2993546947dSdanielk1977db close
300fda06befSmistachkinforcedelete test.db
301fda06befSmistachkinforcedelete test.db-journal
3023546947dSdanielk1977sqlite3 db test.db
3033546947dSdanielk1977
3043546947dSdanielk1977#--------------------------------------------------------------------
3053546947dSdanielk1977# This is all to force the pager_remove_from_stmt_list() function
3063546947dSdanielk1977# (inside pager.c) to remove a pager from the middle of the
3073546947dSdanielk1977# statement-list.
3083546947dSdanielk1977#
3093546947dSdanielk1977do_test misc7-15.1 {
3103546947dSdanielk1977  execsql {
3113546947dSdanielk1977    PRAGMA cache_size = 10;
3123546947dSdanielk1977    BEGIN;
3133546947dSdanielk1977    CREATE TABLE abc(a PRIMARY KEY, b, c);
3143546947dSdanielk1977    INSERT INTO abc
3153546947dSdanielk1977    VALUES(randstr(100,100), randstr(100,100), randstr(100,100));
3163546947dSdanielk1977    INSERT INTO abc SELECT
3173546947dSdanielk1977            randstr(100,100), randstr(100,100), randstr(100,100) FROM abc;
3183546947dSdanielk1977    INSERT INTO abc SELECT
3193546947dSdanielk1977            randstr(100,100), randstr(100,100), randstr(100,100) FROM abc;
3203546947dSdanielk1977    INSERT INTO abc SELECT
3213546947dSdanielk1977            randstr(100,100), randstr(100,100), randstr(100,100) FROM abc;
3223546947dSdanielk1977    INSERT INTO abc SELECT
3233546947dSdanielk1977            randstr(100,100), randstr(100,100), randstr(100,100) FROM abc;
3243546947dSdanielk1977    INSERT INTO abc SELECT
3253546947dSdanielk1977            randstr(100,100), randstr(100,100), randstr(100,100) FROM abc;
3263546947dSdanielk1977    INSERT INTO abc SELECT
3273546947dSdanielk1977            randstr(100,100), randstr(100,100), randstr(100,100) FROM abc;
3283546947dSdanielk1977    INSERT INTO abc SELECT
3293546947dSdanielk1977            randstr(100,100), randstr(100,100), randstr(100,100) FROM abc;
3303546947dSdanielk1977    INSERT INTO abc SELECT
3313546947dSdanielk1977            randstr(100,100), randstr(100,100), randstr(100,100) FROM abc;
3323546947dSdanielk1977    COMMIT;
3333546947dSdanielk1977  }
3343546947dSdanielk1977  expr {[file size test.db]>10240}
3353546947dSdanielk1977} {1}
3363546947dSdanielk1977do_test misc7-15.2 {
3373546947dSdanielk1977  execsql {
3383546947dSdanielk1977    DELETE FROM abc WHERE rowid > 12;
3393546947dSdanielk1977    INSERT INTO abc SELECT
3403546947dSdanielk1977            randstr(100,100), randstr(100,100), randstr(100,100) FROM abc;
3413546947dSdanielk1977  }
3423546947dSdanielk1977} {}
3433546947dSdanielk1977
344393f0689Sdanielk1977db close
345fda06befSmistachkinforcedelete test.db
346fda06befSmistachkinforcedelete test.db-journal
347393f0689Sdanielk1977sqlite3 db test.db
348393f0689Sdanielk1977
349393f0689Sdanielk1977do_ioerr_test misc7-16 -sqlprep {
350393f0689Sdanielk1977   PRAGMA cache_size = 10;
351393f0689Sdanielk1977   PRAGMA default_cache_size = 10;
352393f0689Sdanielk1977   CREATE TABLE t3(a, b, UNIQUE(a, b));
353393f0689Sdanielk1977   INSERT INTO t3 VALUES( randstr(100, 100), randstr(100, 100) );
354393f0689Sdanielk1977   INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3;
355393f0689Sdanielk1977   INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3;
356393f0689Sdanielk1977   INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3;
357393f0689Sdanielk1977   INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3;
358393f0689Sdanielk1977   INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3;
359393f0689Sdanielk1977   UPDATE t3
360393f0689Sdanielk1977   SET b = 'hello world'
361393f0689Sdanielk1977   WHERE rowid >= (SELECT max(rowid)-1 FROM t3);
362393f0689Sdanielk1977} -tclbody {
363393f0689Sdanielk1977  set rc [catch {db eval {
364393f0689Sdanielk1977    BEGIN;
365393f0689Sdanielk1977      PRAGMA cache_size = 10;
366393f0689Sdanielk1977      INSERT INTO t3 VALUES( randstr(100, 100), randstr(100, 100) );
367393f0689Sdanielk1977      UPDATE t3 SET a = b;
368393f0689Sdanielk1977    COMMIT;
369393f0689Sdanielk1977  }} msg]
370393f0689Sdanielk1977
37114386751Sdrh  if {!$rc || ($rc && [string first "UNIQUE" $msg]==0)} {
372393f0689Sdanielk1977    set msg
373393f0689Sdanielk1977  } else {
374393f0689Sdanielk1977    error $msg
375393f0689Sdanielk1977  }
376393f0689Sdanielk1977}
377393f0689Sdanielk1977
37824168728Sdanielk1977sqlite3 db test.db
37908d31a2aSdanielk1977
38008d31a2aSdanielk1977do_test misc7-16.X {
38108d31a2aSdanielk1977  execsql {
38208d31a2aSdanielk1977    SELECT count(*) FROM t3;
38308d31a2aSdanielk1977  }
38408d31a2aSdanielk1977} {32}
38508d31a2aSdanielk1977
38608d31a2aSdanielk1977#----------------------------------------------------------------------
38708d31a2aSdanielk1977# Test the situation where a hot-journal is discovered but write-access
38808d31a2aSdanielk1977# to it is denied. This should return SQLITE_BUSY.
38908d31a2aSdanielk1977#
3900b3d55d4Sdrh# These tests do not work on windows due to restrictions in the
3910b3d55d4Sdrh# windows file system.
3920b3d55d4Sdrh#
393f1c6bc5cSmistachkinif {$tcl_platform(platform)!="windows"} {
39417fe6c1dSdrh
39517fe6c1dSdrh  # Some network filesystems (ex: AFP) do not support setting read-only
39617fe6c1dSdrh  # permissions.  Only run these tests if full unix permission setting
39717fe6c1dSdrh  # capabilities are supported.
39817fe6c1dSdrh  #
39917fe6c1dSdrh  file attributes test.db -permissions rw-r--r--
40017fe6c1dSdrh  if {[file attributes test.db -permissions]==0644} {
40117fe6c1dSdrh
40208d31a2aSdanielk1977    do_test misc7-17.1 {
40308d31a2aSdanielk1977      execsql {
40408d31a2aSdanielk1977        BEGIN;
40508d31a2aSdanielk1977        DELETE FROM t3 WHERE (oid%3)==0;
40608d31a2aSdanielk1977      }
407fda06befSmistachkin      forcecopy test.db bak.db
408fda06befSmistachkin      forcecopy test.db-journal bak.db-journal
40908d31a2aSdanielk1977      execsql {
41008d31a2aSdanielk1977        COMMIT;
41108d31a2aSdanielk1977      }
41208d31a2aSdanielk1977
413ead8e3f4Sdanielk1977      db close
414fda06befSmistachkin      forcecopy bak.db test.db
415fda06befSmistachkin      forcecopy bak.db-journal test.db-journal
416ead8e3f4Sdanielk1977      sqlite3 db test.db
41708d31a2aSdanielk1977
4180b3d55d4Sdrh      catch {file attributes test.db-journal -permissions r--------}
4190b3d55d4Sdrh      catch {file attributes test.db-journal -readonly 1}
42008d31a2aSdanielk1977      catchsql {
42108d31a2aSdanielk1977        SELECT count(*) FROM t3;
42208d31a2aSdanielk1977      }
42399dfe5ebSdrh    } {1 {unable to open database file}}
42408d31a2aSdanielk1977    do_test misc7-17.2 {
425382e28faSdanielk1977      # Note that the -readonly flag must be cleared before the -permissions
426382e28faSdanielk1977      # are set. Otherwise, when using tcl 8.5 on mac, the fact that the
427382e28faSdanielk1977      # -readonly flag is set causes the attempt to set the permissions
428382e28faSdanielk1977      # to fail.
4290b3d55d4Sdrh      catch {file attributes test.db-journal -readonly 0}
430382e28faSdanielk1977      catch {file attributes test.db-journal -permissions rw-------}
43108d31a2aSdanielk1977      catchsql {
43208d31a2aSdanielk1977        SELECT count(*) FROM t3;
43308d31a2aSdanielk1977      }
434ead8e3f4Sdanielk1977    } {0 32}
435ead8e3f4Sdanielk1977
4368e3e881aSdanielk1977    # sqlite3_test_control_pending_page [expr ($::sqlite_pending_byte / 1024) + 1]
4378e3e881aSdanielk1977    set ::pending_byte_page [expr ($::sqlite_pending_byte / 1024) + 1]
4388e3e881aSdanielk1977    sqlite3_test_control_pending_byte $::sqlite_pending_byte
439ead8e3f4Sdanielk1977    do_test misc7-17.3 {
440b7c2cf0aSdrh      sqlite3_db_config db DEFENSIVE 0
441ead8e3f4Sdanielk1977      db eval {
442ead8e3f4Sdanielk1977        pragma writable_schema = true;
443ead8e3f4Sdanielk1977        UPDATE sqlite_master
444ead8e3f4Sdanielk1977          SET rootpage = $pending_byte_page
445ead8e3f4Sdanielk1977          WHERE type = 'table' AND name = 't3';
446ead8e3f4Sdanielk1977      }
447ead8e3f4Sdanielk1977      execsql {
448ead8e3f4Sdanielk1977        SELECT rootpage FROM sqlite_master WHERE type = 'table' AND name = 't3';
449ead8e3f4Sdanielk1977      }
450ead8e3f4Sdanielk1977    } $::pending_byte_page
451ead8e3f4Sdanielk1977
452ead8e3f4Sdanielk1977    do_test misc7-17.4 {
453ead8e3f4Sdanielk1977      db close
454ead8e3f4Sdanielk1977      sqlite3 db test.db
455ead8e3f4Sdanielk1977      catchsql {
456ead8e3f4Sdanielk1977        SELECT count(*) FROM t3;
457ead8e3f4Sdanielk1977      }
45880aff084Sdan    } {1 {malformed database schema (t3) - invalid rootpage}}
4590b3d55d4Sdrh  }
46017fe6c1dSdrh}
461ead8e3f4Sdanielk1977
4626bd00bfdSdrh# Ticket #2470
4636bd00bfdSdrh#
46480aff084Sdanreset_db
4656bd00bfdSdrhdo_test misc7-18.1 {
4666bd00bfdSdrh  execsql {
4676bd00bfdSdrh    CREATE TABLE table_1 (col_10);
4686bd00bfdSdrh    CREATE TABLE table_2 (
4696bd00bfdSdrh      col_1, col_2, col_3, col_4, col_5,
4706bd00bfdSdrh      col_6, col_7, col_8, col_9, col_10
4716bd00bfdSdrh    );
4728278ce79Sdrh    SELECT a.col_10
4736bd00bfdSdrh    FROM
4748278ce79Sdrh      (SELECT table_1.col_10 AS col_10 FROM table_1) a,
4756bd00bfdSdrh      (SELECT table_1.col_10, table_2.col_9 AS qcol_9
4766bd00bfdSdrh         FROM table_1, table_2
4776bd00bfdSdrh        GROUP BY table_1.col_10, qcol_9);
4786bd00bfdSdrh  }
4796bd00bfdSdrh} {}
4806bd00bfdSdrh
481af005fbcSdrh# Testing boundary conditions on sqlite3_status()
482af005fbcSdrh#
483af005fbcSdrhdo_test misc7-19.1 {
484af005fbcSdrh  sqlite3_status -1 0
485af005fbcSdrh} {21 0 0}
486af005fbcSdrhdo_test misc7-19.2 {
487af005fbcSdrh  sqlite3_status 1000 0
488af005fbcSdrh} {21 0 0}
489af005fbcSdrh
490af005fbcSdrh
491e2a7c6e0Sdrh# sqlite3_global_recover() is a no-op.  But we might as well test it
492e2a7c6e0Sdrh# if only to get the test coverage.
493e2a7c6e0Sdrh#
494e2a7c6e0Sdrhdo_test misc7-20.1 {
495e2a7c6e0Sdrh  sqlite3_global_recover
496e2a7c6e0Sdrh} {SQLITE_OK}
497e2a7c6e0Sdrh
4980371f1b2Sdanielk1977# Try to open a really long file name.
4990371f1b2Sdanielk1977#
5000371f1b2Sdanielk1977do_test misc7-21.1 {
501f8a78464Smistachkin  set zFile [file join [get_pwd] "[string repeat abcde 104].db"]
5020371f1b2Sdanielk1977  set rc [catch {sqlite3 db2 $zFile} msg]
5030371f1b2Sdanielk1977  list $rc $msg
5040371f1b2Sdanielk1977} {1 {unable to open database file}}
5050371f1b2Sdanielk1977
506e3664fb0Sdan# Try to do hot-journal rollback with a read-only connection. The
507e3664fb0Sdan# error code should be SQLITE_READONLY_ROLLBACK.
508e3664fb0Sdan#
509e3664fb0Sdando_test misc7-22.1 {
510e3664fb0Sdan  db close
511e3664fb0Sdan  forcedelete test.db copy.db-journal
512e3664fb0Sdan  sqlite3 db test.db
513e3664fb0Sdan  execsql {
514e3664fb0Sdan    CREATE TABLE t1(a, b);
515e3664fb0Sdan    INSERT INTO t1 VALUES(1, 2);
516e3664fb0Sdan    INSERT INTO t1 VALUES(3, 4);
517e3664fb0Sdan  }
518e3664fb0Sdan  db close
519e3664fb0Sdan  sqlite3 db test.db -readonly 1
520e3664fb0Sdan  catchsql {
521e3664fb0Sdan    INSERT INTO t1 VALUES(5, 6);
522e3664fb0Sdan  }
523e3664fb0Sdan} {1 {attempt to write a readonly database}}
524e3664fb0Sdando_test misc7-22.2 { execsql { SELECT * FROM t1 } } {1 2 3 4}
525e3664fb0Sdando_test misc7-22.3 {
526e3664fb0Sdan  set fd [open test.db-journal w]
527e3664fb0Sdan  puts $fd [string repeat abc 1000]
528e3664fb0Sdan  close $fd
529e3664fb0Sdan  catchsql { SELECT * FROM t1 }
530e3664fb0Sdan} {1 {attempt to write a readonly database}}
531e3664fb0Sdando_test misc7-22.4 {
532e3664fb0Sdan  sqlite3_extended_errcode db
533e3664fb0Sdan} SQLITE_READONLY_ROLLBACK
534a688ca5eSdancatch { db close }
535fda06befSmistachkinforcedelete test.db
53608d31a2aSdanielk1977
537b8fff29cSdanif {$::tcl_platform(platform)=="unix"
538b8fff29cSdan && [atomic_batch_write test.db]==0
539b8fff29cSdan} {
540a688ca5eSdan  reset_db
541a688ca5eSdan  do_execsql_test 23.0 {
542a688ca5eSdan    CREATE TABLE t1(x, y);
543a688ca5eSdan    INSERT INTO t1 VALUES(1, 2);
544a688ca5eSdan  }
545a688ca5eSdan
546a688ca5eSdan  do_test 23.1 {
547a688ca5eSdan    db close
548a688ca5eSdan    forcedelete tst
549a688ca5eSdan    file mkdir tst
550a688ca5eSdan    forcecopy test.db tst/test.db
551a688ca5eSdan    file attributes tst -permissions r-xr-xr-x
552a688ca5eSdan  } {}
553a688ca5eSdan
554a688ca5eSdan  sqlite3 db tst/test.db
555a688ca5eSdan  do_execsql_test 23.2 {
556a688ca5eSdan    SELECT * FROM t1;
557a688ca5eSdan  } {1 2}
558a688ca5eSdan
559a688ca5eSdan  do_catchsql_test 23.3 {
560a688ca5eSdan    INSERT INTO t1 VALUES(3, 4);
561a688ca5eSdan  } {1 {attempt to write a readonly database}}
562a688ca5eSdan
563a688ca5eSdan  do_test 23.4 {
564a688ca5eSdan    sqlite3_extended_errcode db
565a688ca5eSdan  } {SQLITE_READONLY_DIRECTORY}
566a688ca5eSdan
567a688ca5eSdan  do_test 23.5 {
568a688ca5eSdan    db close
569a688ca5eSdan    forcedelete tst
570a688ca5eSdan  } {}
571a688ca5eSdan}
572a688ca5eSdan
573a713f2c3Sdanielk1977finish_test
574