Add the schema_cookie and user_cookie pragmas. (CVS 2089)

FossilOrigin-Name: d28d1d68e5104726e6088361dfa7bf2cdd9985c7
This commit is contained in:
danielk1977 2004-11-11 05:10:43 +00:00
parent 2df9fabf3c
commit dae2495b1f
6 changed files with 317 additions and 19 deletions

View File

@ -1,5 +1,5 @@
C Add\sdocumentation\sfor\sDEFAULT\sCURRENT_TIME\s&\sco.\s(CVS\s2088)
D 2004-11-11T01:50:30
C Add\sthe\sschema_cookie\sand\suser_cookie\spragmas.\s(CVS\s2089)
D 2004-11-11T05:10:44
F Makefile.in c4d2416860f472a1e3393714d0372074197565df
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
@ -40,7 +40,7 @@ F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
F src/insert.c 8bd40dc5a8e470cba5b9b14211fa88ea0350d2fa
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
F src/main.c ba1b26f03af4b7f8be3394748123dd671b9ea147
F src/main.c c7dc54c62c86cab8b2e2883aef607c179eefa611
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
F src/os.h 38258df2db895499b6e2957dbf17f25e0df71667
F src/os_common.h 0e7f428ba0a6c40a61bc56c4e96f493231301b73
@ -55,7 +55,7 @@ F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c ee88fcecb081e3635c281bc09d604e934429e2f5
F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
F src/parse.y 02e0d88a6d465f6fd5ea79a200a8c23c92a877dc
F src/pragma.c 44074b93216516b01cafacd85cb10621088693dd
F src/pragma.c bb1c76dae9911b9312997b353c1e316fa603a0c6
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c 156990c636102bb6b8de85e7ff3396a62568476b
@ -156,7 +156,7 @@ F test/pager.test 394455707a079804e8a4e431d12edce831a065f0
F test/pager2.test c7e731ac56a2984a605b032ffd19b9deee820377
F test/pager3.test 647f696a9cf7409df00a1e0047c2eb55585a1b85
F test/pagesize.test 6f94b70ed9645dbe6314b627ae765c5dec8036d9
F test/pragma.test bde1271384bc415af04d9dd736c073cf7ef33177
F test/pragma.test 1d2ca2b52e08ed5af81f7f02e4490182bfd2f832
F test/printf.test 92ba4c510b4fc61120ffa4a01820446ed917ae57
F test/progress.test 5ddba78cb6011fba36093973cfb3ac473b8fb96a x
F test/quick.test 9e968949a20b5ed5990c03dc45df3781a03c4b1a
@ -246,7 +246,7 @@ F www/nulls.tcl ec35193f92485b87b90a994a01d0171b58823fcf
F www/oldnews.tcl 7aa4478e64631859770a5fe4b413919ba6ee8a08
F www/omitted.tcl 7bd62b6f0f53b60c5360895b16b3af8407bbca03
F www/opcode.tcl dafa030a5a3cc24a2f9fd4cfbfb7d7323d2151b0
F www/pragma.tcl f954f5c5eb98b4ba33c09d4fd866600e78b0aacb
F www/pragma.tcl 5bac2d73a92136fb711d558003648383ec2b139b
F www/quickstart.tcl 6f6f694b6139be2d967b1492eb9a6bdf7058aa60
F www/speed.tcl de99c82c4729a10b6733463636f15473c4ec95bc
F www/sqlite.tcl b51fd15f0531a54874de785a9efba323eecd5975
@ -255,7 +255,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c
P 0747b55882cf218c03b443e1eadec9eb19889554
R b894ca6622f94383b4e07995b66df8ff
P c85f13f8f252faf423f12a3804f1fe2f950da660
R d714e2a607a79ae47d80cca22b4581aa
U danielk1977
Z e7eb67c45eefd163ea64d3015b6203d0
Z 9c7e9034616e577965e9472de918179e

View File

@ -1 +1 @@
c85f13f8f252faf423f12a3804f1fe2f950da660
d28d1d68e5104726e6088361dfa7bf2cdd9985c7

View File

@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.263 2004/10/06 15:41:17 drh Exp $
** $Id: main.c,v 1.264 2004/11/11 05:10:44 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -202,7 +202,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
** meta[2] Size of the page cache.
** meta[3] Use freelist if 0. Autovacuum if greater than zero.
** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE
** meta[5]
** meta[5] The user cookie. Used by the application.
** meta[6]
** meta[7]
** meta[8]

View File

@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.75 2004/11/09 12:44:38 danielk1977 Exp $
** $Id: pragma.c,v 1.76 2004/11/11 05:10:44 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@ -724,6 +724,65 @@ void sqlite3Pragma(
}
}
}else
/*
** PRAGMA [database.]schema_cookie
** PRAGMA [database.]schema_cookie = <integer>
**
** PRAGMA [database.]user_cookie
** PRAGMA [database.]user_cookie = <integer>
**
** The pragma's schema_cookie and user_cookie are used to set or get
** the value of the schema-cookie and user-cookie, respectively. Both
** the schema-cookie and the user-cookie are 32-bit signed integers
** stored in the database header.
**
** The schema-cookie is usually only manipulated internally by SQLite. It
** is incremented by SQLite whenever the database schema is modified (by
** creating or dropping a table or index). The schema cookie is used by
** SQLite each time a query is executed to ensure that the internal cache
** of the schema used when compiling the SQL query matches the schema of
** the database against which the compiled query is actually executed.
** Subverting this mechanism by using "PRAGMA schema_cookie" to modify
** the schema-cookie is potentially dangerous and may lead to program
** crashes or database corruption. Use with caution!
**
** The user-cookie is not used internally by SQLite. It may be used by
** applications for any purpose.
*/
if( sqlite3StrICmp(zLeft, "schema_cookie")==0 ||
sqlite3StrICmp(zLeft, "user_cookie")==0 ){
int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */
if( zLeft[0]=='s' || zLeft[0]=='S' ){
iCookie = 0;
}else{
iCookie = 5;
}
if( zRight ){
/* Write the specified cookie value */
static const VdbeOpList setCookie[] = {
{ OP_Transaction, 0, 1, 0}, /* 0 */
{ OP_Integer, 0, 0, 0}, /* 1 */
{ OP_SetCookie, 0, 0, 0}, /* 2 */
};
int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP1(v, addr+1, atoi(zRight));
sqlite3VdbeChangeP1(v, addr+2, iDb);
sqlite3VdbeChangeP2(v, addr+2, iCookie);
}else{
/* Read the specified cookie value */
static const VdbeOpList readCookie[] = {
{ OP_ReadCookie, 0, 0, 0}, /* 0 */
{ OP_Callback, 1, 0, 0}
};
int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP2(v, addr, iCookie);
sqlite3VdbeSetNumCols(v, 1);
}
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*

View File

@ -12,7 +12,7 @@
#
# This file implements tests for the PRAGMA command.
#
# $Id: pragma.test,v 1.21 2004/11/04 14:47:13 drh Exp $
# $Id: pragma.test,v 1.22 2004/11/11 05:10:44 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -367,5 +367,210 @@ do_test pragma-7.3 {
} {main unlocked temp closed}
#----------------------------------------------------------------------
# Test cases pragma-8.* test the "PRAGMA schema_cookie" and "PRAGMA
# user_cookie" statements.
#
# pragma-8.1: PRAGMA schema_cookie
# pragma-8.2: PRAGMA user_cookie
#
# First check that we can set the schema cookie and then retrieve the
# same value.
do_test pragma-8.1.1 {
execsql {
PRAGMA schema_cookie = 105;
}
} {}
do_test pragma-8.1.2 {
execsql {
PRAGMA schema_cookie;
}
} 105
do_test pragma-8.1.3 {
execsql {
PRAGMA schema_cookie = 106;
}
} {}
do_test pragma-8.1.4 {
execsql {
PRAGMA schema_cookie;
}
} 106
# Check that creating a table modifies the schema-cookie (this is really
# to verify that the value being read is in fact the schema cookie).
do_test pragma-8.1.5 {
execsql {
CREATE TABLE t4(a, b, c);
INSERT INTO t4 VALUES(1, 2, 3);
SELECT * FROM t4;
}
} {1 2 3}
do_test pragma-8.1.6 {
execsql {
PRAGMA schema_cookie;
}
} 107
# Now open a second connection to the database. Ensure that changing the
# schema-cookie using the first connection forces the second connection
# to reload the schema. This has to be done using the C-API test functions,
# because the TCL API accounts for SCHEMA_ERROR and retries the query.
do_test pragma-8.1.7 {
set ::DB2 [sqlite3 db2 test.db]
execsql {
SELECT * FROM t4;
} db2
} {1 2 3}
do_test pragma-8.1.8 {
execsql {
PRAGMA schema_cookie = 108;
}
} {}
do_test pragma-8.1.9 {
set ::STMT [sqlite3_prepare $::DB2 "SELECT * FROM t4" -1 DUMMY]
sqlite3_step $::STMT
} SQLITE_ERROR
do_test pragma-8.1.10 {
sqlite3_finalize $::STMT
} SQLITE_SCHEMA
# Make sure the schema-cookie can be manipulated in an attached database.
file delete -force test2.db
file delete -force test2.db-journal
do_test pragma-8.1.11 {
execsql {
ATTACH 'test2.db' AS aux;
CREATE TABLE aux.t1(a, b, c);
PRAGMA aux.schema_cookie = 205;
}
} {}
do_test pragma-8.1.12 {
execsql {
PRAGMA aux.schema_cookie;
}
} 205
do_test pragma-8.1.13 {
execsql {
PRAGMA schema_cookie;
}
} 108
# And check that modifying the schema-cookie in an attached database
# forces the second connection to reload the schema.
do_test pragma-8.1.14 {
set ::DB2 [sqlite3 db2 test.db]
execsql {
ATTACH 'test2.db' AS aux;
SELECT * FROM aux.t1;
} db2
} {}
do_test pragma-8.1.15 {
execsql {
PRAGMA aux.schema_cookie = 206;
}
} {}
do_test pragma-8.1.16 {
set ::STMT [sqlite3_prepare $::DB2 "SELECT * FROM aux.t1" -1 DUMMY]
sqlite3_step $::STMT
} SQLITE_ERROR
do_test pragma-8.1.17 {
sqlite3_finalize $::STMT
} SQLITE_SCHEMA
do_test pragma-8.1.18 {
db2 close
} {}
# Now test that the user-cookie can be read and written (and that we aren't
# accidentally manipulating the schema-cookie instead).
do_test pragma-8.2.1 {
execsql {
PRAGMA user_cookie;
}
} {0}
do_test pragma-8.2.2 {
execsql {
PRAGMA user_cookie = 2;
}
} {}
do_test pragma-8.2.3 {
execsql {
PRAGMA user_cookie;
}
} {2}
do_test pragma-8.2.4 {
execsql {
PRAGMA schema_cookie;
}
} {108}
# Check that the user-cookie in the auxilary database can be manipulated (
# and that we aren't accidentally manipulating the same in the main db).
do_test pragma-8.2.5 {
execsql {
PRAGMA aux.user_cookie;
}
} {0}
do_test pragma-8.2.6 {
execsql {
PRAGMA aux.user_cookie = 3;
}
} {}
do_test pragma-8.2.7 {
execsql {
PRAGMA aux.user_cookie;
}
} {3}
do_test pragma-8.2.8 {
execsql {
PRAGMA main.user_cookie;
}
} {2}
# Now check that a ROLLBACK resets the user-cookie if it has been modified
# within a transaction.
do_test pragma-8.2.9 {
execsql {
BEGIN;
PRAGMA aux.user_cookie = 10;
PRAGMA user_cookie = 11;
}
} {}
do_test pragma-8.2.10 {
execsql {
PRAGMA aux.user_cookie;
}
} {10}
do_test pragma-8.2.11 {
execsql {
PRAGMA main.user_cookie;
}
} {11}
do_test pragma-8.2.12 {
execsql {
ROLLBACK;
PRAGMA aux.user_cookie;
}
} {3}
do_test pragma-8.2.13 {
execsql {
PRAGMA main.user_cookie;
}
} {2}
# Try a negative value for the user-cookie
do_test pragma-8.2.14 {
execsql {
PRAGMA user_cookie = -450;
}
} {}
do_test pragma-8.2.15 {
execsql {
PRAGMA user_cookie;
}
} {-450}
finish_test

View File

@ -1,7 +1,7 @@
#
# Run this Tcl script to generate the pragma.html file.
#
set rcsid {$Id: pragma.tcl,v 1.1 2004/11/10 05:48:57 danielk1977 Exp $}
set rcsid {$Id: pragma.tcl,v 1.2 2004/11/11 05:10:44 danielk1977 Exp $}
source common.tcl
header {Pragma statements supported by SQLite}
@ -27,13 +27,15 @@ different in the following important respects:
engine.
</ul>
<p>The available pragma's fall into three basic categories:</p>
<p>The available pragmas fall into four basic categories:</p>
<ul>
<li>Pragmas used to <a href="#schema">query the schema</a> of the current
database.
<li>Pragmas used to <a href="#modify">modify the operation</a> of the
SQLite library in some manner, or to query for the current mode of
operation.
<li>Pragmas used to <a href="#cookie">query or modify the databases two
cookie values</a>, the schema-cookie and the user-cookie.
<li>Pragmas used to <a href="#debug">debug the library</a> and verify that
database files are not corrupted.
</ul>
@ -56,7 +58,7 @@ treated as <b>1</b>, and will not generate an error. When the <i>value</i>
is returned it is as an integer.</p>
}
Section {Pragmas used to modify library operation} modify
Section {Pragmas to modify library operation} modify
puts {
<ul>
@ -210,7 +212,7 @@ puts {
</ul>
}
Section {Pragma's used to query the database schema} schema
Section {Pragmas to query the database schema} schema
puts {
<ul>
@ -247,7 +249,39 @@ puts {
</ul>
}
Section {Pragma's used to debug the library} debug
Section {Pragmas to query/modify cookie values} cookie
puts {
<ul>
<li><p><b>PRAGMA [database.]schema_cookie;
<br>PRAGMA [database.]schema_cookie = </b><i>integer </i><b>;
<br>PRAGMA [database.]user_cookie;
<br>PRAGMA [database.]user_cookie = </b><i>integer </i><b>;</b>
<p> The pragmas schema_cookie and user_cookie are used to set or get
the value of the schema-cookie and user-cookie, respectively. Both
the schema-cookie and the user-cookie are 32-bit signed integers
stored in the database header.</p>
<p> The schema-cookie is usually only manipulated internally by SQLite.
It is incremented by SQLite whenever the database schema is modified
(by creating or dropping a table or index). The schema cookie is
used by SQLite each time a query is executed to ensure that the
internal cache of the schema used when compiling the SQL query matches
the schema of the database against which the compiled query is actually
executed. Subverting this mechanism by using "PRAGMA schema_cookie"
to modify the schema-cookie is potentially dangerous and may lead
to program crashes or database corruption. Use with caution!</p>
<p> The user-cookie is not used internally by SQLite. It may be used by
applications for any purpose.</p>
</li>
</ul>
}
Section {Pragmas to debug the library} debug
puts {
<ul>