xref: /sqlite-3.40.0/test/pragma.test (revision 4dcbdbff)
1# 2002 March 6
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 implements tests for the PRAGMA command.
14#
15# $Id: pragma.test,v 1.36 2005/05/22 20:30:39 drh Exp $
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
20# Test organization:
21#
22# pragma-1.*: Test cache_size, default_cache_size and synchronous on main db.
23# pragma-2.*: Test synchronous on attached db.
24# pragma-3.*: Test detection of table/index inconsistency by integrity_check.
25# pragma-4.*: Test cache_size and default_cache_size on attached db.
26# pragma-5.*: Test that pragma synchronous may not be used inside of a
27#             transaction.
28# pragma-6.*: Test schema-query pragmas.
29# pragma-7.*: Miscellaneous tests.
30# pragma-8.*: Test user_version and schema_version pragmas.
31# pragma-9.*: Test temp_store and temp_store_directory.
32# pragma-10.*: Test the count_changes pragma in the presence of triggers.
33# pragma-11.*: Test the collation_list pragma.
34#
35
36# Delete the preexisting database to avoid the special setup
37# that the "all.test" script does.
38#
39db close
40file delete test.db
41set DB [sqlite3 db test.db]
42
43ifcapable pager_pragmas {
44do_test pragma-1.1 {
45  execsql {
46    PRAGMA cache_size;
47    PRAGMA default_cache_size;
48    PRAGMA synchronous;
49  }
50} {2000 2000 2}
51do_test pragma-1.2 {
52  execsql {
53    PRAGMA synchronous=OFF;
54    PRAGMA cache_size=1234;
55    PRAGMA cache_size;
56    PRAGMA default_cache_size;
57    PRAGMA synchronous;
58  }
59} {1234 2000 0}
60do_test pragma-1.3 {
61  db close
62  sqlite3 db test.db
63  execsql {
64    PRAGMA cache_size;
65    PRAGMA default_cache_size;
66    PRAGMA synchronous;
67  }
68} {2000 2000 2}
69do_test pragma-1.4 {
70  execsql {
71    PRAGMA synchronous=OFF;
72    PRAGMA cache_size;
73    PRAGMA default_cache_size;
74    PRAGMA synchronous;
75  }
76} {2000 2000 0}
77do_test pragma-1.5 {
78  execsql {
79    PRAGMA cache_size=4321;
80    PRAGMA cache_size;
81    PRAGMA default_cache_size;
82    PRAGMA synchronous;
83  }
84} {4321 2000 0}
85do_test pragma-1.6 {
86  execsql {
87    PRAGMA synchronous=ON;
88    PRAGMA cache_size;
89    PRAGMA default_cache_size;
90    PRAGMA synchronous;
91  }
92} {4321 2000 1}
93do_test pragma-1.7 {
94  db close
95  sqlite3 db test.db
96  execsql {
97    PRAGMA cache_size;
98    PRAGMA default_cache_size;
99    PRAGMA synchronous;
100  }
101} {2000 2000 2}
102do_test pragma-1.8 {
103  execsql {
104    PRAGMA default_cache_size=123;
105    PRAGMA cache_size;
106    PRAGMA default_cache_size;
107    PRAGMA synchronous;
108  }
109} {123 123 2}
110do_test pragma-1.9.1 {
111  db close
112  set ::DB [sqlite3 db test.db]
113  execsql {
114    PRAGMA cache_size;
115    PRAGMA default_cache_size;
116    PRAGMA synchronous;
117  }
118} {123 123 2}
119ifcapable vacuum {
120  do_test pragma-1.9.2 {
121    execsql {
122      VACUUM;
123      PRAGMA cache_size;
124      PRAGMA default_cache_size;
125      PRAGMA synchronous;
126    }
127  } {123 123 2}
128}
129do_test pragma-1.10 {
130  execsql {
131    PRAGMA synchronous=NORMAL;
132    PRAGMA cache_size;
133    PRAGMA default_cache_size;
134    PRAGMA synchronous;
135  }
136} {123 123 1}
137do_test pragma-1.11 {
138  execsql {
139    PRAGMA synchronous=FULL;
140    PRAGMA cache_size;
141    PRAGMA default_cache_size;
142    PRAGMA synchronous;
143  }
144} {123 123 2}
145do_test pragma-1.12 {
146  db close
147  set ::DB [sqlite3 db test.db]
148  execsql {
149    PRAGMA cache_size;
150    PRAGMA default_cache_size;
151    PRAGMA synchronous;
152  }
153} {123 123 2}
154
155# Make sure the pragma handler understands numeric values in addition
156# to keywords like "off" and "full".
157#
158do_test pragma-1.13 {
159  execsql {
160    PRAGMA synchronous=0;
161    PRAGMA synchronous;
162  }
163} {0}
164do_test pragma-1.14 {
165  execsql {
166    PRAGMA synchronous=2;
167    PRAGMA synchronous;
168  }
169} {2}
170} ;# ifcapable pager_pragmas
171
172# Test turning "flag" pragmas on and off.
173#
174do_test pragma-1.15 {
175  execsql {
176    PRAGMA vdbe_listing=YES;
177    PRAGMA vdbe_listing;
178  }
179} {1}
180do_test pragma-1.16 {
181  execsql {
182    PRAGMA vdbe_listing=NO;
183    PRAGMA vdbe_listing;
184  }
185} {0}
186do_test pragma-1.17 {
187  execsql {
188    PRAGMA parser_trace=ON;
189    PRAGMA parser_trace=OFF;
190  }
191} {}
192do_test pragma-1.18 {
193  execsql {
194    PRAGMA bogus = -1234;  -- Parsing of negative values
195  }
196} {}
197
198# Test modifying the safety_level of an attached database.
199do_test pragma-2.1 {
200  file delete -force test2.db
201  file delete -force test2.db-journal
202  execsql {
203    ATTACH 'test2.db' AS aux;
204  }
205} {}
206ifcapable pager_pragmas {
207do_test pragma-2.2 {
208  execsql {
209    pragma aux.synchronous;
210  }
211} {2}
212do_test pragma-2.3 {
213  execsql {
214    pragma aux.synchronous = OFF;
215    pragma aux.synchronous;
216    pragma synchronous;
217  }
218} {0 2}
219do_test pragma-2.4 {
220  execsql {
221    pragma aux.synchronous = ON;
222    pragma synchronous;
223    pragma aux.synchronous;
224  }
225} {2 1}
226} ;# ifcapable pager_pragmas
227
228# Construct a corrupted index and make sure the integrity_check
229# pragma finds it.
230#
231# These tests won't work if the database is encrypted
232#
233do_test pragma-3.1 {
234  execsql {
235    BEGIN;
236    CREATE TABLE t2(a,b,c);
237    CREATE INDEX i2 ON t2(a);
238    INSERT INTO t2 VALUES(11,2,3);
239    INSERT INTO t2 VALUES(22,3,4);
240    COMMIT;
241    SELECT rowid, * from t2;
242  }
243} {1 11 2 3 2 22 3 4}
244if {![sqlite3 -has-codec] && $sqlite_options(integrityck)} {
245  do_test pragma-3.2 {
246    set rootpage [execsql {SELECT rootpage FROM sqlite_master WHERE name='i2'}]
247    set db [btree_open test.db 100 0]
248    btree_begin_transaction $db
249    set c [btree_cursor $db $rootpage 1]
250    btree_first $c
251    btree_delete $c
252    btree_commit $db
253    btree_close $db
254    execsql {PRAGMA integrity_check}
255  } {{rowid 1 missing from index i2} {wrong # of entries in index i2}}
256}
257do_test pragma-3.3 {
258  execsql {
259    DROP INDEX i2;
260  }
261} {}
262
263# Test modifying the cache_size of an attached database.
264ifcapable pager_pragmas {
265do_test pragma-4.1 {
266  execsql {
267    pragma aux.cache_size;
268    pragma aux.default_cache_size;
269  }
270} {2000 2000}
271do_test pragma-4.2 {
272  execsql {
273    pragma aux.cache_size = 50;
274    pragma aux.cache_size;
275    pragma aux.default_cache_size;
276  }
277} {50 2000}
278do_test pragma-4.3 {
279  execsql {
280    pragma aux.default_cache_size = 456;
281    pragma aux.cache_size;
282    pragma aux.default_cache_size;
283  }
284} {456 456}
285do_test pragma-4.4 {
286  execsql {
287    pragma cache_size;
288    pragma default_cache_size;
289  }
290} {123 123}
291do_test pragma-4.5 {
292  execsql {
293    DETACH aux;
294    ATTACH 'test3.db' AS aux;
295    pragma aux.cache_size;
296    pragma aux.default_cache_size;
297  }
298} {2000 2000}
299do_test pragma-4.6 {
300  execsql {
301    DETACH aux;
302    ATTACH 'test2.db' AS aux;
303    pragma aux.cache_size;
304    pragma aux.default_cache_size;
305  }
306} {456 456}
307} ;# ifcapable pager_pragmas
308
309# Test that modifying the sync-level in the middle of a transaction is
310# disallowed.
311ifcapable pager_pragmas {
312do_test pragma-5.0 {
313  execsql {
314    pragma synchronous;
315  }
316} {2}
317do_test pragma-5.1 {
318  catchsql {
319    BEGIN;
320    pragma synchronous = OFF;
321  }
322} {1 {Safety level may not be changed inside a transaction}}
323do_test pragma-5.2 {
324  execsql {
325    pragma synchronous;
326  }
327} {2}
328catchsql {COMMIT;}
329} ;# ifcapable pager_pragmas
330
331# Test schema-query pragmas
332#
333ifcapable schema_pragmas {
334ifcapable tempdb {
335  do_test pragma-6.1 {
336    set res {}
337    execsql {SELECT * FROM sqlite_temp_master}
338    foreach {idx name file} [execsql {pragma database_list}] {
339      lappend res $idx $name
340    }
341    set res
342  } {0 main 1 temp 2 aux}
343}
344do_test pragma-6.2 {
345  execsql {
346    pragma table_info(t2)
347  }
348} {0 a numeric 0 {} 0 1 b numeric 0 {} 0 2 c numeric 0 {} 0}
349ifcapable {foreignkey} {
350  do_test pragma-6.3 {
351    execsql {
352      CREATE TABLE t3(a int references t2(b), b UNIQUE);
353      pragma foreign_key_list(t3);
354    }
355  } {0 0 t2 a b}
356  do_test pragma-6.4 {
357    execsql {
358      pragma index_list(t3);
359    }
360  } {0 sqlite_autoindex_t3_1 1}
361}
362ifcapable {!foreignkey} {
363  execsql {CREATE TABLE t3(a,b UNIQUE)}
364}
365do_test pragma-6.5 {
366  execsql {
367    CREATE INDEX t3i1 ON t3(a,b);
368    pragma index_info(t3i1);
369  }
370} {0 0 a 1 1 b}
371} ;# ifcapable schema_pragmas
372# Miscellaneous tests
373#
374ifcapable schema_pragmas {
375do_test pragma-7.1 {
376  # Make sure a pragma knows to read the schema if it needs to
377  db close
378  sqlite3 db test.db
379  execsql {
380    pragma index_list(t3);
381  }
382} {0 t3i1 0 1 sqlite_autoindex_t3_1 1}
383} ;# ifcapable schema_pragmas
384ifcapable {utf16} {
385  do_test pragma-7.2 {
386    db close
387    sqlite3 db test.db
388    catchsql {
389      pragma encoding=bogus;
390    }
391  } {1 {unsupported encoding: bogus}}
392}
393ifcapable tempdb {
394  do_test pragma-7.3 {
395    db close
396    sqlite3 db test.db
397    execsql {
398      pragma lock_status;
399    }
400  } {main unlocked temp closed}
401} else {
402  do_test pragma-7.3 {
403    db close
404    sqlite3 db test.db
405    execsql {
406      pragma lock_status;
407    }
408  } {main unlocked}
409}
410
411
412#----------------------------------------------------------------------
413# Test cases pragma-8.* test the "PRAGMA schema_version" and "PRAGMA
414# user_version" statements.
415#
416# pragma-8.1: PRAGMA schema_version
417# pragma-8.2: PRAGMA user_version
418#
419
420ifcapable schema_version {
421
422# First check that we can set the schema version and then retrieve the
423# same value.
424do_test pragma-8.1.1 {
425  execsql {
426    PRAGMA schema_version = 105;
427  }
428} {}
429do_test pragma-8.1.2 {
430  execsql {
431    PRAGMA schema_version;
432  }
433} 105
434do_test pragma-8.1.3 {
435  execsql {
436    PRAGMA schema_version = 106;
437  }
438} {}
439do_test pragma-8.1.4 {
440  execsql {
441    PRAGMA schema_version;
442  }
443} 106
444
445# Check that creating a table modifies the schema-version (this is really
446# to verify that the value being read is in fact the schema version).
447do_test pragma-8.1.5 {
448  execsql {
449    CREATE TABLE t4(a, b, c);
450    INSERT INTO t4 VALUES(1, 2, 3);
451    SELECT * FROM t4;
452  }
453} {1 2 3}
454do_test pragma-8.1.6 {
455  execsql {
456    PRAGMA schema_version;
457  }
458} 107
459
460# Now open a second connection to the database. Ensure that changing the
461# schema-version using the first connection forces the second connection
462# to reload the schema. This has to be done using the C-API test functions,
463# because the TCL API accounts for SCHEMA_ERROR and retries the query.
464do_test pragma-8.1.7 {
465  set ::DB2 [sqlite3 db2 test.db]
466  execsql {
467    SELECT * FROM t4;
468  } db2
469} {1 2 3}
470do_test pragma-8.1.8 {
471  execsql {
472    PRAGMA schema_version = 108;
473  }
474} {}
475do_test pragma-8.1.9 {
476  set ::STMT [sqlite3_prepare $::DB2 "SELECT * FROM t4" -1 DUMMY]
477  sqlite3_step $::STMT
478} SQLITE_ERROR
479do_test pragma-8.1.10 {
480  sqlite3_finalize $::STMT
481} SQLITE_SCHEMA
482
483# Make sure the schema-version can be manipulated in an attached database.
484file delete -force test2.db
485file delete -force test2.db-journal
486do_test pragma-8.1.11 {
487  execsql {
488    ATTACH 'test2.db' AS aux;
489    CREATE TABLE aux.t1(a, b, c);
490    PRAGMA aux.schema_version = 205;
491  }
492} {}
493do_test pragma-8.1.12 {
494  execsql {
495    PRAGMA aux.schema_version;
496  }
497} 205
498do_test pragma-8.1.13 {
499  execsql {
500    PRAGMA schema_version;
501  }
502} 108
503
504# And check that modifying the schema-version in an attached database
505# forces the second connection to reload the schema.
506do_test pragma-8.1.14 {
507  set ::DB2 [sqlite3 db2 test.db]
508  execsql {
509    ATTACH 'test2.db' AS aux;
510    SELECT * FROM aux.t1;
511  } db2
512} {}
513do_test pragma-8.1.15 {
514  execsql {
515    PRAGMA aux.schema_version = 206;
516  }
517} {}
518do_test pragma-8.1.16 {
519  set ::STMT [sqlite3_prepare $::DB2 "SELECT * FROM aux.t1" -1 DUMMY]
520  sqlite3_step $::STMT
521} SQLITE_ERROR
522do_test pragma-8.1.17 {
523  sqlite3_finalize $::STMT
524} SQLITE_SCHEMA
525do_test pragma-8.1.18 {
526  db2 close
527} {}
528
529# Now test that the user-version can be read and written (and that we aren't
530# accidentally manipulating the schema-version instead).
531do_test pragma-8.2.1 {
532  execsql {
533    PRAGMA user_version;
534  }
535} {0}
536do_test pragma-8.2.2 {
537  execsql {
538    PRAGMA user_version = 2;
539  }
540} {}
541do_test pragma-8.2.3.1 {
542  execsql {
543    PRAGMA user_version;
544  }
545} {2}
546do_test pragma-8.2.3.2 {
547  db close
548  sqlite3 db test.db
549  execsql {
550    PRAGMA user_version;
551  }
552} {2}
553do_test pragma-8.2.4.1 {
554  execsql {
555    PRAGMA schema_version;
556  }
557} {108}
558ifcapable vacuum {
559  do_test pragma-8.2.4.2 {
560    execsql {
561      VACUUM;
562      PRAGMA user_version;
563    }
564  } {2}
565  do_test pragma-8.2.4.3 {
566    execsql {
567      PRAGMA schema_version;
568    }
569  } {109}
570}
571db eval {ATTACH 'test2.db' AS aux}
572
573# Check that the user-version in the auxilary database can be manipulated (
574# and that we aren't accidentally manipulating the same in the main db).
575do_test pragma-8.2.5 {
576  execsql {
577    PRAGMA aux.user_version;
578  }
579} {0}
580do_test pragma-8.2.6 {
581  execsql {
582    PRAGMA aux.user_version = 3;
583  }
584} {}
585do_test pragma-8.2.7 {
586  execsql {
587    PRAGMA aux.user_version;
588  }
589} {3}
590do_test pragma-8.2.8 {
591  execsql {
592    PRAGMA main.user_version;
593  }
594} {2}
595
596# Now check that a ROLLBACK resets the user-version if it has been modified
597# within a transaction.
598do_test pragma-8.2.9 {
599  execsql {
600    BEGIN;
601    PRAGMA aux.user_version = 10;
602    PRAGMA user_version = 11;
603  }
604} {}
605do_test pragma-8.2.10 {
606  execsql {
607    PRAGMA aux.user_version;
608  }
609} {10}
610do_test pragma-8.2.11 {
611  execsql {
612    PRAGMA main.user_version;
613  }
614} {11}
615do_test pragma-8.2.12 {
616  execsql {
617    ROLLBACK;
618    PRAGMA aux.user_version;
619  }
620} {3}
621do_test pragma-8.2.13 {
622  execsql {
623    PRAGMA main.user_version;
624  }
625} {2}
626
627# Try a negative value for the user-version
628do_test pragma-8.2.14 {
629  execsql {
630    PRAGMA user_version = -450;
631  }
632} {}
633do_test pragma-8.2.15 {
634  execsql {
635    PRAGMA user_version;
636  }
637} {-450}
638} ; # ifcapable schema_version
639
640
641# Test temp_store and temp_store_directory pragmas
642#
643ifcapable pager_pragmas {
644do_test pragma-9.1 {
645  db close
646  sqlite3 db test.db
647  execsql {
648    PRAGMA temp_store;
649  }
650} {0}
651do_test pragma-9.2 {
652  execsql {
653    PRAGMA temp_store=file;
654    PRAGMA temp_store;
655  }
656} {1}
657do_test pragma-9.3 {
658  execsql {
659    PRAGMA temp_store=memory;
660    PRAGMA temp_store;
661  }
662} {2}
663do_test pragma-9.4 {
664  execsql {
665    PRAGMA temp_store_directory;
666  }
667} {}
668do_test pragma-9.5 {
669  set pwd [string map {' ''} [pwd]]
670  execsql "
671    PRAGMA temp_store_directory='$pwd';
672  "
673} {}
674do_test pragma-9.6 {
675  execsql {
676    PRAGMA temp_store_directory;
677  }
678} [pwd]
679do_test pragma-9.7 {
680  catchsql {
681    PRAGMA temp_store_directory='/NON/EXISTENT/PATH/FOOBAR';
682  }
683} {1 {not a writable directory}}
684do_test pragma-9.8 {
685  execsql {
686    PRAGMA temp_store_directory='';
687  }
688} {}
689ifcapable tempdb {
690  do_test pragma-9.9 {
691    execsql {
692      PRAGMA temp_store_directory;
693      PRAGMA temp_store=FILE;
694      CREATE TEMP TABLE temp_store_directory_test(a integer);
695      INSERT INTO temp_store_directory_test values (2);
696      SELECT * FROM temp_store_directory_test;
697    }
698  } {2}
699}
700do_test pragma-9.10 {
701  catchsql "
702    PRAGMA temp_store_directory='$pwd';
703    SELECT * FROM temp_store_directory_test;
704  "
705} {1 {no such table: temp_store_directory_test}}
706} ;# ifcapable pager_pragmas
707
708ifcapable trigger {
709
710do_test pragma-10.0 {
711  catchsql {
712    DROP TABLE main.t1;
713  }
714  execsql {
715    PRAGMA count_changes = 1;
716
717    CREATE TABLE t1(a PRIMARY KEY);
718    CREATE TABLE t1_mirror(a);
719    CREATE TABLE t1_mirror2(a);
720    CREATE TRIGGER t1_bi BEFORE INSERT ON t1 BEGIN
721      INSERT INTO t1_mirror VALUES(new.a);
722    END;
723    CREATE TRIGGER t1_ai AFTER INSERT ON t1 BEGIN
724      INSERT INTO t1_mirror2 VALUES(new.a);
725    END;
726    CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 BEGIN
727      UPDATE t1_mirror SET a = new.a WHERE a = old.a;
728    END;
729    CREATE TRIGGER t1_au AFTER UPDATE ON t1 BEGIN
730      UPDATE t1_mirror2 SET a = new.a WHERE a = old.a;
731    END;
732    CREATE TRIGGER t1_bd BEFORE DELETE ON t1 BEGIN
733      DELETE FROM t1_mirror WHERE a = old.a;
734    END;
735    CREATE TRIGGER t1_ad AFTER DELETE ON t1 BEGIN
736      DELETE FROM t1_mirror2 WHERE a = old.a;
737    END;
738  }
739} {}
740
741do_test pragma-10.1 {
742  execsql {
743    INSERT INTO t1 VALUES(randstr(10,10));
744  }
745} {1}
746do_test pragma-10.2 {
747  execsql {
748    UPDATE t1 SET a = randstr(10,10);
749  }
750} {1}
751do_test pragma-10.3 {
752  execsql {
753    DELETE FROM t1;
754  }
755} {1}
756
757} ;# ifcapable trigger
758
759ifcapable schema_pragmas {
760  do_test pragma-11.1 {
761    execsql2 {
762      pragma collation_list;
763    }
764  } {seq 0 name NOCASE seq 1 name BINARY}
765  do_test pragma-11.2 {
766    db collate New_Collation blah...
767    execsql {
768      pragma collation_list;
769    }
770  } {0 New_Collation 1 NOCASE 2 BINARY}
771}
772
773# Reset the sqlite3_temp_directory variable for the next run of tests:
774sqlite3 dbX :memory:
775dbX eval {PRAGMA temp_store_directory = ""}
776dbX close
777
778finish_test
779