]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Remove default_synchronous and temp_store pragmas. Allow the safety-level
authordanielk1977 <danielk1977@noemail.net>
Sat, 26 Jun 2004 06:37:06 +0000 (06:37 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Sat, 26 Jun 2004 06:37:06 +0000 (06:37 +0000)
and cache-size to be set for attached databases. (CVS 1735)

FossilOrigin-Name: 212de3ce66f746036cb2267a9f924fd55fa2f37a

manifest
manifest.uuid
src/attach.c
src/main.c
src/parse.y
src/pragma.c
src/sqliteInt.h
test/pragma.test

index 3b60813fd756b0e50cbea40d3265119688acaa48..b98709235e3ee0bec0c4bcbe46b62295ac842c34 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sbug\sin\sthe\snew\sfull-sync\sjournal\sformat.\s(CVS\s1733)
-D 2004-06-26T01:48:19
+C Remove\sdefault_synchronous\sand\stemp_store\spragmas.\sAllow\sthe\ssafety-level\nand\scache-size\sto\sbe\sset\sfor\sattached\sdatabases.\s(CVS\s1735)
+D 2004-06-26T06:37:07
 F Makefile.in cb7a9889c38723f72b2506c4236ff30a05ff172b
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -24,7 +24,7 @@ F spec.template a38492f1c1dd349fc24cb0565e08afc53045304b
 F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
 F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
 F sqlite3.def 26f4e7b0a3fbaa55701e020fdec429f1594e2866
-F src/attach.c 05102e2e8ac43ce639d07b47a99c7772a62420e6
+F src/attach.c b105aeb8c82fbd097c5067dddde90d5f7fadf8dd
 F src/auth.c 60db23b98bb94c8b0178180faaf49dc116674217
 F src/btree.c 0591368af031a0ecc4620140dfdaa177b82885a1
 F src/btree.h 32f96abef464cf8765b23ca669acfe90d191fcc5
@@ -38,7 +38,7 @@ F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
 F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
 F src/insert.c d99ffe87e1e1397f4233afcd06841d52d6b17b18
 F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
-F src/main.c 2a4f3fe32ee6357b5b914ab5e2bd0979202570f4
+F src/main.c 7a5afce156d14727a49b60ffe6ab21bcae27e6f3
 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
 F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345
 F src/os_common.h ba1b7306e16e2091718f2c48db0fe6c1d7a31bb8
@@ -52,14 +52,14 @@ F src/os_win.c 84549f6cc815237533c5d0eb3697352b03478d96
 F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44
 F src/pager.c e3969171742e7d9681977703feed4853f5ee206a
 F src/pager.h bc58d32a9dee464f7268fb68652c130a4216e438
-F src/parse.y 097438674976355a10cf177bd97326c548820b86
-F src/pragma.c 0750e1c360647dbe0a991f16133b0fe5e42e5039
+F src/parse.y e19e066e726a31d7b2d3e6475bdf55f7e339f8a3
+F src/pragma.c 16713c1bc440ccd9982a27fb4b38e1a1c95ffd29
 F src/printf.c 3090c8ff397d549bc0de09b16d8ab7fd37a0c3f7
 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 F src/select.c f02a65af34231031896e8442161cb5251e191e75
 F src/shell.c 24b641700c9d90f361fcfa4f432c5b4aff704e6d
 F src/sqlite.h.in b70fded2bdfeaddfb06adea3888118b722975136
-F src/sqliteInt.h dd796b6abc6d50505fe33c54f0143d7000681a41
+F src/sqliteInt.h ed55c1f149875b6484798381e6933f5f5ad1a4ce
 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
 F src/tclsqlite.c 8d093146332b2f0cbf2a8ebe8597d481619308a3
 F src/test1.c e4e0ae8af8040c848ef35f92e6a22b2245b9b873
@@ -141,7 +141,7 @@ F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
 F test/null.test 64730a1c32955e5cc510b7632fed6b9929a4029a
 F test/pager.test 059cc5c58d3b5a851343dff8c56cf7286425d03a
 F test/pager2.test 55469c7c1c1a54d6b32d7b3cc99001e90101a1ce
-F test/pragma.test e09ac12edbdac81d21ca88084fef376c7667f5b0
+F test/pragma.test a0dac4320e130e31e855bbdb935645d7c45d6340
 F test/printf.test 1eb584b7272d1abdfe117b2ef7cf3376ae8e4e06
 F test/progress.test 7542a6ac7894a1b7730c1f9a27f3f8b9388a4d25 x
 F test/quick.test 4c0b3eabe2e0e606622d63d7d61ef6efb3ce156b
@@ -229,7 +229,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/version3.tcl 563ba3ac02f64da27ab17f3edbe8e56bfd0293fb
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P dfab1e9ac0fbe57fe4a1cbe6c363ef43b3b075ef
-R e246eb7b8fa1d2e1a6e20fbeb7cc5c16
+P 02bd3acd7efde9cc6b67c97e98db9f4b62d27877
+R 609621fb2d8c2cbffc869dbeea94770a
 U danielk1977
-Z ead895d5ca480d6e5d884e35379e8164
+Z 231b7ef4aa565faa68238895f77436c5
index f5484757e07ed628305afd30c53d03c6bb3d144d..2f56368b9f029629e25adde302979a362341ef0f 100644 (file)
@@ -1 +1 @@
-02bd3acd7efde9cc6b67c97e98db9f4b62d27877
\ No newline at end of file
+212de3ce66f746036cb2267a9f924fd55fa2f37a
\ No newline at end of file
index 9468f203a4c39d81757df56b703b971c867a756d..a8808d47da1f541b7033eab9f4057deca5110a68 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the ATTACH and DETACH commands.
 **
-** $Id: attach.c,v 1.17 2004/06/19 16:06:11 drh Exp $
+** $Id: attach.c,v 1.18 2004/06/26 06:37:07 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -84,6 +84,7 @@ void sqlite3Attach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey)
   sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
   sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
   aNew->zName = zName;
+  aNew->safety_level = 3;
   rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
   if( rc ){
     sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
index 20f7983d601f942c92b03712e4efc12a202321df..7d15ceb7c916f9f0ee52c21bcc12612978592c80 100644 (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.233 2004/06/22 12:13:55 drh Exp $
+** $Id: main.c,v 1.234 2004/06/26 06:37:07 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -218,9 +218,9 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
   **    meta[0]   Schema cookie.  Changes with each schema change.
   **    meta[1]   File format of schema layer.
   **    meta[2]   Size of the page cache.
-  **    meta[3]   Synchronous setting.  1:off, 2:normal, 3:full
+  **    meta[3]
   **    meta[4]   Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE
-  **    meta[5]   Pragma temp_store value.  See comments on BtreeFactory
+  **    meta[5]
   **    meta[6]   
   **    meta[7]
   **    meta[8]
@@ -265,16 +265,11 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
     }
   }
 
-  if( iDb==0 ){
-    size = meta[2];
-    if( size==0 ){ size = MAX_PAGES; }
-    db->cache_size = size;
-    db->safety_level = meta[3];
-    if( meta[5]>0 && meta[5]<=2 && db->temp_store==0 ){
-      db->temp_store = meta[5];
-    }
-    if( db->safety_level==0 ) db->safety_level = 2;
+  size = meta[2];
+  if( size==0 ){ size = MAX_PAGES; }
+  db->aDb[iDb].cache_size = size;
 
+  if( iDb==0 ){
     db->file_format = meta[1];
     if( db->file_format==0 ){
       /* This happens if the database was initially empty */
@@ -291,8 +286,7 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
     return SQLITE_ERROR;
   }
 
-  sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);
-  sqlite3BtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[3]==0 ? 2 : meta[3]);
+  sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);
 
   /* Read the schema information out of the schema tables
   */
@@ -807,22 +801,6 @@ void *sqlite3_commit_hook(
 ** the connection is closed.)  If zFilename is NULL then the database
 ** is for temporary use only and is deleted as soon as the connection
 ** is closed.
-**
-** A temporary database can be either a disk file (that is automatically
-** deleted when the file is closed) or a set of red-black trees held in memory,
-** depending on the values of the TEMP_STORE compile-time macro and the
-** db->temp_store variable, according to the following chart:
-**
-**       TEMP_STORE     db->temp_store     Location of temporary database
-**       ----------     --------------     ------------------------------
-**           0               any             file
-**           1                1              file
-**           1                2              memory
-**           1                0              file
-**           2                1              file
-**           2                2              memory
-**           2                0              memory
-**           3               any             memory
 */
 int sqlite3BtreeFactory(
   const sqlite *db,        /* Main database when opening aux otherwise 0 */
@@ -837,7 +815,10 @@ int sqlite3BtreeFactory(
   if( omitJournal ){
     btree_flags |= BTREE_OMIT_JOURNAL;
   }
-  if( !zFilename ){
+  if( !zFilename || !strcmp(zFilename, ":memory:") ){
+    /* If zFilename is NULL or the magic string ":memory:" then the
+    ** new btree storest data in main memory, not a file.
+    */
     btree_flags |= BTREE_MEMORY;
   }
 
@@ -1127,12 +1108,6 @@ static int openDatabase(
   sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);
 
   /* Open the backend database driver */
-  if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
-    db->temp_store = 2;
-    db->nMaster = 0;    /* Disable atomic multi-file commit for :memory: */
-  }else{
-    db->nMaster = -1;   /* Size of master journal filename initially unknown */
-  }
   rc = sqlite3BtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
   if( rc!=SQLITE_OK ){
     sqlite3Error(db, rc, 0);
@@ -1142,6 +1117,11 @@ static int openDatabase(
   db->aDb[0].zName = "main";
   db->aDb[1].zName = "temp";
 
+  /* The default safety_level for the main database is 'full' for the temp
+  ** database it is 'NONE'. This matches the pager layer defaults.  */
+  db->aDb[0].safety_level = 3;
+  db->aDb[1].safety_level = 1;
+
   /* Register all built-in functions, but do not attempt to read the
   ** database schema yet. This is delayed until the first time the database
   ** is accessed.
index 5e0e1cc84751e3bb0e8c709bdedb379a5ec0e60c..567d2280084db0861b9be99c9ca3e0883ea159a6 100644 (file)
@@ -14,7 +14,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.127 2004/06/09 09:55:18 danielk1977 Exp $
+** @(#) $Id: parse.y,v 1.128 2004/06/26 06:37:07 danielk1977 Exp $
 */
 %token_prefix TK_
 %token_type {Token}
@@ -782,12 +782,14 @@ cmd ::= VACUUM nm(X).         {sqlite3Vacuum(pParse,&X);}
 
 ///////////////////////////// The PRAGMA command /////////////////////////////
 //
-cmd ::= PRAGMA ids(X) EQ nm(Y).         {sqlite3Pragma(pParse,&X,&Y,0);}
-cmd ::= PRAGMA ids(X) EQ ON(Y).          {sqlite3Pragma(pParse,&X,&Y,0);}
-cmd ::= PRAGMA ids(X) EQ plus_num(Y).    {sqlite3Pragma(pParse,&X,&Y,0);}
-cmd ::= PRAGMA ids(X) EQ minus_num(Y).   {sqlite3Pragma(pParse,&X,&Y,1);}
-cmd ::= PRAGMA ids(X) LP nm(Y) RP.      {sqlite3Pragma(pParse,&X,&Y,0);}
-cmd ::= PRAGMA ids(X).                   {sqlite3Pragma(pParse,&X,&X,0);}
+cmd ::= PRAGMA nm(X) dbnm(Z) EQ nm(Y).  {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
+cmd ::= PRAGMA nm(X) dbnm(Z) EQ ON(Y).  {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
+cmd ::= PRAGMA nm(X) dbnm(Z) EQ plus_num(Y). {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
+cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y). {
+  sqlite3Pragma(pParse,&X,&Z,&Y,1);
+}
+cmd ::= PRAGMA nm(X) dbnm(Z) LP nm(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
+cmd ::= PRAGMA nm(X) dbnm(Z).  {sqlite3Pragma(pParse,&X,&Z,0,0);}
 plus_num(A) ::= plus_opt number(X).   {A = X;}
 minus_num(A) ::= MINUS number(X).     {A = X;}
 number(A) ::= INTEGER(X).  {A = X;}
index a4fba9fa2332212ee17a8647b40352e25d8ef589..54c9391ce98f1541de3e22354ac38f6843492f85 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.52 2004/06/21 09:06:42 danielk1977 Exp $
+** $Id: pragma.c,v 1.53 2004/06/26 06:37:07 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -71,46 +71,6 @@ static int getSafetyLevel(char *z){
   return 1;
 }
 
-/*
-** Interpret the given string as a temp db location. Return 1 for file
-** backed temporary databases, 2 for the Red-Black tree in memory database
-** and 0 to use the compile-time default.
-*/
-static int getTempStore(const char *z){
-  if( z[0]>='0' && z[0]<='2' ){
-    return z[0] - '0';
-  }else if( sqlite3StrICmp(z, "file")==0 ){
-    return 1;
-  }else if( sqlite3StrICmp(z, "memory")==0 ){
-    return 2;
-  }else{
-    return 0;
-  }
-}
-
-/*
-** If the TEMP database is open, close it and mark the database schema
-** as needing reloading.  This must be done when using the TEMP_STORE
-** or DEFAULT_TEMP_STORE pragmas.
-*/
-static int changeTempStorage(Parse *pParse, const char *zStorageType){
-  int ts = getTempStore(zStorageType);
-  sqlite *db = pParse->db;
-  if( db->temp_store==ts ) return SQLITE_OK;
-  if( db->aDb[1].pBt!=0 ){
-    if( !db->autoCommit ){
-      sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
-        "from within a transaction");
-      return SQLITE_ERROR;
-    }
-    sqlite3BtreeClose(db->aDb[1].pBt);
-    db->aDb[1].pBt = 0;
-    sqlite3ResetInternalSchema(db, 0);
-  }
-  db->temp_store = ts;
-  return SQLITE_OK;
-}
-
 /*
 ** Check to see if zRight and zLeft refer to a pragma that queries
 ** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.
@@ -157,27 +117,43 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
 **
 ** Pragmas are of this form:
 **
-**      PRAGMA id = value
+**      PRAGMA [database.]id [= value]
 **
 ** The identifier might also be a string.  The value is a string, and
 ** identifier, or a number.  If minusFlag is true, then the value is
 ** a number that was preceded by a minus sign.
 */
-void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
-  char *zLeft = 0;
-  char *zRight = 0;
+void sqlite3Pragma(
+  Parse *pParse, 
+  Token *pId1,        /* First part of [database.]id field */
+  Token *pId2,        /* Second part of [database.]id field, or NULL */
+  Token *pValue,      /* Token for <value>, or NULL */
+  int minusFlag       /* True if a '-' sign preceded <value> */
+){
+  char *zLeft = 0;       /* Nul-terminated UTF-8 string <id> */
+  char *zRight = 0;      /* Nul-terminated UTF-8 string <value>, or NULL */
+  const char *zDb = 0;   /* The database name */
+  Token *pId;            /* Pointer to <id> token */
+  int iDb;               /* Database index for <database> */
   sqlite *db = pParse->db;
   Vdbe *v = sqlite3GetVdbe(pParse);
   if( v==0 ) return;
 
-  zLeft = sqlite3NameFromToken(pLeft);
+  /* Interpret the [database.] part of the pragma statement. iDb is the
+  ** index of the database this pragma is being applied to in db.aDb[]. */
+  iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
+  if( iDb<0 ) return;
+
+  zLeft = sqlite3NameFromToken(pId);
   if( minusFlag ){
     zRight = 0;
-    sqlite3SetNString(&zRight, "-", 1, pRight->z, pRight->n, 0);
+    sqlite3SetNString(&zRight, "-", 1, pValue->z, pValue->n, 0);
   }else{
-    zRight = sqlite3NameFromToken(pRight);
+    zRight = sqlite3NameFromToken(pValue);
   }
-  if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, 0) ){
+
+  zDb = ((iDb>0)?db->aDb[iDb].zName:0);
+  if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
     goto pragma_out;
   }
  
@@ -199,7 +175,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
   */
   if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
     static VdbeOpList getCacheSize[] = {
-      { OP_ReadCookie,  0, 2,        0},
+      { OP_ReadCookie,  0, 2,        0},  /* 0 */
       { OP_AbsValue,    0, 0,        0},
       { OP_Dup,         0, 0,        0},
       { OP_Integer,     0, 0,        0},
@@ -212,24 +188,25 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
       pParse->nErr++;
       goto pragma_out;
     }
-    if( pRight->z==pLeft->z ){
+    if( !zRight ){
       sqlite3VdbeSetNumCols(v, 1);
       sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
       addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
+      sqlite3VdbeChangeP1(v, addr, iDb);
       sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
     }else{
       int size = atoi(zRight);
       if( size<0 ) size = -size;
-      sqlite3BeginWriteOperation(pParse, 0, 0);
+      sqlite3BeginWriteOperation(pParse, 0, iDb);
       sqlite3VdbeAddOp(v, OP_Integer, size, 0);
-      sqlite3VdbeAddOp(v, OP_ReadCookie, 0, 2);
+      sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2);
       addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
       sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
       sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
-      sqlite3VdbeAddOp(v, OP_SetCookie, 0, 2);
+      sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
       sqlite3EndWriteOperation(pParse);
-      db->cache_size = db->cache_size<0 ? -size : size;
-      sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
+      db->aDb[iDb].cache_size = size;
+      sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);
     }
   }else
 
@@ -255,9 +232,9 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
       pParse->nErr++;
       goto pragma_out;
     }
-    if( pRight->z==pLeft->z ){
-      int size = db->cache_size;;
-      if( size<0 ) size = -size;
+    if( !zRight ){
+      int size = db->aDb[iDb].cache_size;
+      assert( size>0 );
       sqlite3VdbeAddOp(v, OP_Integer, size, 0);
       sqlite3VdbeSetNumCols(v, 1);
       sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
@@ -265,77 +242,8 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
     }else{
       int size = atoi(zRight);
       if( size<0 ) size = -size;
-      if( db->cache_size<0 ) size = -size;
-      db->cache_size = size;
-      sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
-    }
-  }else
-
-  /*
-  **  PRAGMA default_synchronous
-  **  PRAGMA default_synchronous=ON|OFF|NORMAL|FULL
-  **
-  ** The first form returns the persistent value of the "synchronous" setting
-  ** that is stored in the database.  This is the synchronous setting that
-  ** is used whenever the database is opened unless overridden by a separate
-  ** "synchronous" pragma.  The second form changes the persistent and the
-  ** local synchronous setting to the value given.
-  **
-  ** If synchronous is OFF, SQLite does not attempt any fsync() systems calls
-  ** to make sure data is committed to disk.  Write operations are very fast,
-  ** but a power failure can leave the database in an inconsistent state.
-  ** If synchronous is ON or NORMAL, SQLite will do an fsync() system call to
-  ** make sure data is being written to disk.  The risk of corruption due to
-  ** a power loss in this mode is negligible but non-zero.  If synchronous
-  ** is FULL, extra fsync()s occur to reduce the risk of corruption to near
-  ** zero, but with a write performance penalty.  The default mode is NORMAL.
-  */
-  if( sqlite3StrICmp(zLeft,"default_synchronous")==0 ){
-    static VdbeOpList getSync[] = {
-      { OP_ReadCookie,  0, 3,        0},
-      { OP_Dup,         0, 0,        0},
-      { OP_If,          0, 0,        0},  /* 2 */
-      { OP_ReadCookie,  0, 2,        0},
-      { OP_Integer,     0, 0,        0},
-      { OP_Lt,          0, 5,        0},
-      { OP_AddImm,      1, 0,        0},
-      { OP_Callback,    1, 0,        0},
-      { OP_Halt,        0, 0,        0},
-      { OP_AddImm,     -1, 0,        0},  /* 9 */
-      { OP_Callback,    1, 0,        0}
-    };
-    int addr;
-    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
-      pParse->nErr++;
-      goto pragma_out;
-    }
-    if( pRight->z==pLeft->z ){
-      sqlite3VdbeSetNumCols(v, 1);
-      sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
-      addr = sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
-      sqlite3VdbeChangeP2(v, addr+2, addr+9);
-    }else{
-      int size = db->cache_size;
-      if( size<0 ) size = -size;
-      sqlite3BeginWriteOperation(pParse, 0, 0);
-      sqlite3VdbeAddOp(v, OP_ReadCookie, 0, 2);
-      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
-      addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
-      sqlite3VdbeAddOp(v, OP_Ne, 0, addr+3);
-      sqlite3VdbeAddOp(v, OP_AddImm, MAX_PAGES, 0);
-      sqlite3VdbeAddOp(v, OP_AbsValue, 0, 0);
-      db->safety_level = getSafetyLevel(zRight)+1;
-      if( db->safety_level==1 ){
-        sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
-        size = -size;
-      }
-      sqlite3VdbeAddOp(v, OP_SetCookie, 0, 2);
-      sqlite3VdbeAddOp(v, OP_Integer, db->safety_level, 0);
-      sqlite3VdbeAddOp(v, OP_SetCookie, 0, 3);
-      sqlite3EndWriteOperation(pParse);
-      db->cache_size = size;
-      sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
-      sqlite3BtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
+      db->aDb[iDb].cache_size = size;
+      sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);
     }
   }else
 
@@ -356,19 +264,19 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
       pParse->nErr++;
       goto pragma_out;
     }
-    if( pRight->z==pLeft->z ){
+    if( !zRight ){
       sqlite3VdbeSetNumCols(v, 1);
       sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
-      sqlite3VdbeAddOp(v, OP_Integer, db->safety_level-1, 0);
+      sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].safety_level-1, 0);
       sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
     }else{
-      int size = db->cache_size;
-      if( size<0 ) size = -size;
-      db->safety_level = getSafetyLevel(zRight)+1;
-      if( db->safety_level==1 ) size = -size;
-      db->cache_size = size;
-      sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
-      sqlite3BtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
+      if( !db->autoCommit ){
+        sqlite3ErrorMsg(pParse, 
+            "Safety level may not be changed inside a transaction");
+      }else{
+        db->aDb[iDb].safety_level = getSafetyLevel(zRight)+1;
+        sqlite3BtreeSetSafetyLevel(db->aDb[iDb].pBt,db->aDb[iDb].safety_level);
+      }
     }
   }else
 
@@ -386,6 +294,18 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
     /* The flagPragma() call also generates any necessary code */
   }else
 
+  /*
+  **   PRAGMA table_info(<table>)
+  **
+  ** Return a single row for each column of the named table. The columns of
+  ** the returned data set are:
+  **
+  ** cid:        Column id (numbered from left to right, starting at 0)
+  ** name:       Column name
+  ** type:       Column declaration type.
+  ** notnull:    True if 'NOT NULL' is part of column declaration
+  ** dflt_value: The default value for the column, if any.
+  */
   if( sqlite3StrICmp(zLeft, "table_info")==0 ){
     Table *pTab;
     if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
@@ -530,67 +450,6 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
     }
   }else
 
-
-  /*
-  **   PRAGMA temp_store
-  **   PRAGMA temp_store = "default"|"memory"|"file"
-  **
-  ** Return or set the local value of the temp_store flag.  Changing
-  ** the local value does not make changes to the disk file and the default
-  ** value will be restored the next time the database is opened.
-  **
-  ** Note that it is possible for the library compile-time options to
-  ** override this setting
-  */
-  if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
-    static VdbeOpList getTmpDbLoc[] = {
-      { OP_Callback,    1, 0,        0},
-    };
-    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
-      pParse->nErr++;
-      goto pragma_out;
-    }
-    if( pRight->z==pLeft->z ){
-      sqlite3VdbeAddOp(v, OP_Integer, db->temp_store, 0);
-      sqlite3VdbeSetNumCols(v, 1);
-      sqlite3VdbeSetColName(v, 0, "temp_store", P3_STATIC);
-      sqlite3VdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
-    }else{
-      changeTempStorage(pParse, zRight);
-    }
-  }else
-
-  /*
-  **   PRAGMA default_temp_store
-  **   PRAGMA default_temp_store = "default"|"memory"|"file"
-  **
-  ** Return or set the value of the persistent temp_store flag.  Any
-  ** change does not take effect until the next time the database is
-  ** opened.
-  **
-  ** Note that it is possible for the library compile-time options to
-  ** override this setting
-  */
-  if( sqlite3StrICmp(zLeft, "default_temp_store")==0 ){
-    static VdbeOpList getTmpDbLoc[] = {
-      { OP_ReadCookie,  0, 5,        0},
-      { OP_Callback,    1, 0,        0}};
-    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
-      pParse->nErr++;
-      goto pragma_out;
-    }
-    if( pRight->z==pLeft->z ){
-      sqlite3VdbeSetNumCols(v, 1);
-      sqlite3VdbeSetColName(v, 0, "temp_store", P3_STATIC);
-      sqlite3VdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
-    }else{
-      sqlite3BeginWriteOperation(pParse, 0, 0);
-      sqlite3VdbeAddOp(v, OP_Integer, getTempStore(zRight), 0);
-      sqlite3VdbeAddOp(v, OP_SetCookie, 0, 5);
-      sqlite3EndWriteOperation(pParse);
-    }
-  }else
-
 #ifndef NDEBUG
   if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
     extern void sqlite3ParserTrace(FILE*, char *);
@@ -779,7 +638,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
     };
     struct EncName *pEnc;
     encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;
-    if( pRight->z==pLeft->z ){    /* "PRAGMA encoding" */
+    if( !zRight ){    /* "PRAGMA encoding" */
       if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
         pParse->nErr++;
         goto pragma_out;
index e6ad4a517dfe2aa6e09efb5743e079be8d59169e..deaca08262beef124d1a27a9fe24aa1c0641b2a0 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.299 2004/06/22 12:13:55 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.300 2004/06/26 06:37:07 danielk1977 Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
 */
 #define MAX_ATTACHED 10
 
-/*
-** The next macro is used to determine where TEMP tables and indices
-** are stored.  Possible values:
-**
-**   0    Always use a temporary files
-**   1    Use a file unless overridden by "PRAGMA temp_store"
-**   2    Use memory unless overridden by "PRAGMA temp_store"
-**   3    Always use memory
-*/
-#ifndef TEMP_STORE
-# define TEMP_STORE 1
-#endif
-
 /*
 ** When building SQLite for embedded systems where memory is scarce,
 ** you can define one or more of the following macros to omit extra
@@ -290,6 +277,8 @@ struct Db {
   Hash aFKey;          /* Foreign keys indexed by to-table */
   u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
   u16 flags;           /* Flags associated with this database */
+  u8 safety_level;     /* How aggressive at synching data to disk */
+  int cache_size;      /* Number of pages to use in the cache */
   void *pAux;          /* Auxiliary data.  Usually NULL */
   void (*xFreeAux)(void*);  /* Routine to free pAux */
 };
@@ -335,11 +324,6 @@ struct BusyHandler {
 /*
 ** Each database is an instance of the following structure.
 **
-** The sqlite.temp_store determines where temporary database files
-** are stored.  If 1, then a file is created to hold those tables.  If
-** 2, then they are held in memory.  0 means use the default value in
-** the TEMP_STORE macro.
-**
 ** The sqlite.lastRowid records the last insert rowid generated by an
 ** insert statement.  Inserts on views do not affect its value.  Each
 ** trigger has its own context, so that lastRowid can be updated inside
@@ -369,9 +353,6 @@ struct sqlite {
   Db aDbStatic[2];              /* Static space for the 2 default backends */
   int flags;                    /* Miscellanous flags. See below */
   u8 file_format;               /* What file format version is this database? */
-  u8 safety_level;              /* How aggressive at synching data to disk */
-  u8 temp_store;                /* 1=file, 2=memory, 0=compile-time default */
-  int cache_size;               /* Number of pages to use in the cache */
   int nTable;                   /* Number of tables in the database */
   BusyHandler busyHandler;      /* Busy callback */
   void *pCommitArg;             /* Argument to xCommitCallback() */   
@@ -1225,7 +1206,7 @@ void sqlite3ExprDelete(Expr*);
 ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
 void sqlite3ExprListDelete(ExprList*);
 int sqlite3Init(sqlite*, char**);
-void sqlite3Pragma(Parse*,Token*,Token*,int);
+void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
 void sqlite3ResetInternalSchema(sqlite*, int);
 void sqlite3BeginParse(Parse*,int);
 void sqlite3RollbackInternalChanges(sqlite*);
index 365c67a56b83a1edd9199986c5e4129b9bb8f71b..a0c7f37f7e8cb660f51010c24b08519a14bb9b04 100644 (file)
 #
 # This file implements tests for the PRAGMA command.
 #
-# $Id: pragma.test,v 1.13 2004/06/19 00:16:31 drh Exp $
+# $Id: pragma.test,v 1.14 2004/06/26 06:37:07 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 
+# Test organization:
+#
+# pragma-1.*: Test cache_size, default_cache_size and synchronous on main db.
+# pragma-2.*: Test synchronous on attached db.
+# pragma-3.*: Test detection of table/index inconsistency by integrity_check.
+# pragma-4.*: Test cache_size and default_cache_size on attached db.
+# pragma-5.*: Test that pragma synchronous may not be used inside of a
+#             transaction.
+#
+
 # Delete the preexisting database to avoid the special setup
 # that the "all.test" script does.
 #
@@ -29,18 +39,16 @@ do_test pragma-1.1 {
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {2000 2000 1 1}
+} {2000 2000 2}
 do_test pragma-1.2 {
   execsql {
     PRAGMA cache_size=1234;
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {1234 2000 1 1}
+} {1234 2000 2}
 do_test pragma-1.3 {
   db close
   sqlite3 db test.db
@@ -48,36 +56,32 @@ do_test pragma-1.3 {
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {2000 2000 1 1}
+} {2000 2000 2}
 do_test pragma-1.4 {
   execsql {
     PRAGMA synchronous=OFF;
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {2000 2000 0 1}
+} {2000 2000 0}
 do_test pragma-1.5 {
   execsql {
     PRAGMA cache_size=4321;
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {4321 2000 0 1}
+} {4321 2000 0}
 do_test pragma-1.6 {
   execsql {
     PRAGMA synchronous=ON;
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {4321 2000 1 1}
+} {4321 2000 1}
 do_test pragma-1.7 {
   db close
   sqlite3 db test.db
@@ -85,84 +89,78 @@ do_test pragma-1.7 {
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {2000 2000 1 1}
+} {2000 2000 2}
 do_test pragma-1.8 {
-  execsql {
-    PRAGMA default_synchronous=OFF;
-    PRAGMA cache_size;
-    PRAGMA default_cache_size;
-    PRAGMA synchronous;
-    PRAGMA default_synchronous;
-  }
-} {2000 2000 0 0}
-do_test pragma-1.9 {
   execsql {
     PRAGMA default_cache_size=123;
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {123 123 0 0}
-do_test pragma-1.10 {
+} {123 123 2}
+do_test pragma-1.9 {
   db close
   set ::DB [sqlite3 db test.db]
   execsql {
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {123 123 0 0}
-do_test pragma-1.11 {
+} {123 123 2}
+do_test pragma-1.10 {
   execsql {
     PRAGMA synchronous=NORMAL;
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {123 123 1 0}
-do_test pragma-1.12 {
+} {123 123 1}
+do_test pragma-1.11 {
   execsql {
     PRAGMA synchronous=FULL;
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {123 123 2 0}
-do_test pragma-1.13 {
+} {123 123 2}
+do_test pragma-1.12 {
   db close
   set ::DB [sqlite3 db test.db]
   execsql {
     PRAGMA cache_size;
     PRAGMA default_cache_size;
     PRAGMA synchronous;
-    PRAGMA default_synchronous;
   }
-} {123 123 0 0}
-do_test pragma-1.14 {
+} {123 123 2}
+
+# Test modifying the safety_level of an attached database.
+do_test pragma-2.1 {
+  file delete -force test2.db
+  file delete -force test2.db-journal
   execsql {
-    PRAGMA default_synchronous=FULL;
-    PRAGMA cache_size;
-    PRAGMA default_cache_size;
-    PRAGMA synchronous;
-    PRAGMA default_synchronous;
-  }
-} {123 123 2 2}
-do_test pragma-1.15 {
-  db close
-  set ::DB [sqlite3 db test.db]
+    ATTACH 'test2.db' AS aux;
+  } 
+} {}
+do_test pragma-2.2 {
   execsql {
-    PRAGMA cache_size;
-    PRAGMA default_cache_size;
-    PRAGMA synchronous;
-    PRAGMA default_synchronous;
-  }
-} {123 123 2 2}
+    pragma aux.synchronous;
+  } 
+} {2}
+do_test pragma-2.3 {
+  execsql {
+    pragma aux.synchronous = OFF;
+    pragma aux.synchronous;
+    pragma synchronous;
+  } 
+} {0 2}
+do_test pragma-2.4 {
+  execsql {
+    pragma aux.synchronous = ON;
+    pragma synchronous;
+    pragma aux.synchronous;
+  } 
+} {2 1}
 
 # Construct a corrupted index and make sure the integrity_check
 # pragma finds it.
@@ -192,150 +190,73 @@ do_test pragma-3.2 {
 } {{rowid 1 missing from index i2} {wrong # of entries in index i2}}
 }; # endif has-codec
 
-# Test the temp_store and default_temp_store pragmas
-#
+do_test pragma-3.3 {
+  execsql {
+    DROP INDEX i2;
+  } 
+} {}
+
+# Test modifying the cache_size of an attached database.
+do_test pragma-4.1 {
+  execsql {
+    pragma aux.cache_size;
+    pragma aux.default_cache_size;
+  } 
+} {2000 2000}
 do_test pragma-4.2 {
   execsql {
-    PRAGMA temp_store='default';
-    PRAGMA temp_store;
-  }
-} {0}
+    pragma aux.cache_size = 50;
+    pragma aux.cache_size;
+    pragma aux.default_cache_size;
+  } 
+} {50 2000}
 do_test pragma-4.3 {
   execsql {
-    PRAGMA temp_store='file';
-    PRAGMA temp_store;
-  }
-} {1}
+    pragma aux.default_cache_size = 456;
+    pragma aux.cache_size;
+    pragma aux.default_cache_size;
+  } 
+} {456 456}
 do_test pragma-4.4 {
   execsql {
-    PRAGMA temp_store='memory';
-    PRAGMA temp_store;
-  }
-} {2}
+    pragma cache_size;
+    pragma default_cache_size;
+  } 
+} {123 123}
 do_test pragma-4.5 {
   execsql {
-    PRAGMA default_temp_store='default';
-    PRAGMA default_temp_store;
-  }
-} {0}
+    DETACH aux;
+    ATTACH 'test3.db' AS aux;
+    pragma aux.cache_size;
+    pragma aux.default_cache_size;
+  } 
+} {2000 2000}
 do_test pragma-4.6 {
   execsql {
-    PRAGMA temp_store;
-  }
-} {2}
-do_test pragma-4.7 {
-  db close
-  sqlite3 db test.db
-  execsql {
-    PRAGMA temp_store;
-  }
-} {0}
-do_test pragma-4.8 {
-  execsql {
-    PRAGMA default_temp_store;
-  }
-} {0}
-do_test pragma-4.9 {
-  execsql {
-    PRAGMA default_temp_store='file';
-    PRAGMA default_temp_store;
-  }
-} {1}
-do_test pragma-4.10 {
-  execsql {
-    PRAGMA temp_store;
-  }
-} {0}
-do_test pragma-4.11 {
-  db close
-  sqlite3 db test.db
-  execsql {
-    PRAGMA temp_store;
-  }
-} {1}
-do_test pragma-4.12 {
-  execsql {
-    PRAGMA default_temp_store;
-  }
-} {1}
-do_test pragma-4.13 {
-  execsql {
-    PRAGMA default_temp_store='memory';
-    PRAGMA default_temp_store;
-  }
-} {2}
-do_test pragma-4.14 {
-  execsql {
-    PRAGMA temp_store;
-  }
-} {1}
-do_test pragma-4.15 {
-  db close
-  sqlite3 db test.db
-  execsql {
-    PRAGMA temp_store;
-  }
-} {2}
-do_test pragma-4.16 {
-  execsql {
-    PRAGMA default_temp_store;
-  }
-} {2}
-do_test pragma-4.17 {
-  execsql {
-    PRAGMA temp_store='file';
-    PRAGMA temp_store
-  }
-} {1}
-do_test pragma-4.18 {
-  execsql {
-    PRAGMA default_temp_store
-  }
-} {2}
-do_test pragma-4.19 {
-  db close
-  sqlite3 db test.db
-  execsql {
-    PRAGMA temp_store
-  }
-} {2}
+    DETACH aux;
+    ATTACH 'test2.db' AS aux;
+    pragma aux.cache_size;
+    pragma aux.default_cache_size;
+  } 
+} {456 456}
 
-# Changing the TEMP_STORE deletes any existing temporary tables
-#
-do_test pragma-4.20 {
-  execsql {SELECT name FROM sqlite_temp_master}
-} {}
-do_test pragma-4.21 {
-  execsql {
-    CREATE TEMP TABLE test1(a,b,c);
-    SELECT name FROM sqlite_temp_master;
-  }
-} {test1}
-do_test pragma-4.22 {
+# Test that modifying the sync-level in the middle of a transaction is
+# disallowed.
+do_test pragma-5.0 {
   execsql {
-    PRAGMA temp_store='file';
-    SELECT name FROM sqlite_temp_master;
-  }
-} {}
-do_test pragma-4.23 {
-  execsql {
-    CREATE TEMP TABLE test1(a,b,c);
-    SELECT name FROM sqlite_temp_master;
-  }
-} {test1}
-do_test pragma-4.24 {
-  execsql {
-    PRAGMA temp_store='memory';
-    SELECT name FROM sqlite_temp_master;
-  }
-} {}
-do_test pragma-4.25 {
+    pragma synchronous;
+  } 
+} {2}
+do_test pragma-5.1 {
   catchsql {
     BEGIN;
-    PRAGMA temp_store='default';
-    COMMIT;
-  }
-} {1 {temporary storage cannot be changed from within a transaction}}
-catchsql {COMMIT}
+    pragma synchronous = OFF;
+  } 
+} {1 {Safety level may not be changed inside a transaction}}
+do_test pragma-5.2 {
+  execsql {
+    pragma synchronous;
+  } 
+} {2}
 
 finish_test