]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add pragma to set/get text encoding. Also fix an obscure problem where a
authordanielk1977 <danielk1977@noemail.net>
Mon, 7 Jun 2004 07:52:17 +0000 (07:52 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Mon, 7 Jun 2004 07:52:17 +0000 (07:52 +0000)
temp trigger could be accidently dropped. (CVS 1537)

FossilOrigin-Name: 983221b038813c5a7892564896e39597c223c4c3

manifest
manifest.uuid
src/attach.c
src/build.c
src/main.c
src/pragma.c
src/sqliteInt.h
src/trigger.c
test/attach3.test
test/enc2.test

index 0fb31e989184ea2d80e8d987149c3106745ff704..84c236d7e236365790ad76a00c5011aa7e484c0c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Progress\stowards\sgetting\slocking\sto\swork\son\swindows.\s(CVS\s1536)
-D 2004-06-07T01:52:14
+C Add\spragma\sto\sset/get\stext\sencoding.\sAlso\sfix\san\sobscure\sproblem\swhere\sa\ntemp\strigger\scould\sbe\saccidently\sdropped.\s(CVS\s1537)
+D 2004-06-07T07:52:18
 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -23,11 +23,11 @@ F spec.template a38492f1c1dd349fc24cb0565e08afc53045304b
 F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
 F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f
 F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
-F src/attach.c c315c58cb16fd6e913b3bfa6412aedecb4567fa5
+F src/attach.c e76e4590ec5dd389e5646b171881b5243a6ef391
 F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79
 F src/btree.c 3f0c22ab8c0c000ee5de4ad875836c111c4191c6
 F src/btree.h 589427ac13bb544d298cd99726e2572a6fe4bdaa
-F src/build.c e12e602f06e37a0fbcb49af17cba68ad85e101b6
+F src/build.c 92144f30d30fa00cb21c9c9e51de49cfb948d113
 F src/date.c 8e6fa3173386fb29fdef012ee08a853c1e9908b2
 F src/delete.c b30f08250c9ed53a25a13c7c04599c1e8753992d
 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
@@ -37,7 +37,7 @@ F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
 F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
 F src/insert.c 4268d9e3959cc845ea243fb4ec7507269404dad9
 F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
-F src/main.c 2e4d37f0f8f31694b79823a530ea4b52c8e1a7fd
+F src/main.c d34e173296473c9626f2560a0c86e694fc8e5a2b
 F src/md5.c 4302e84ae516c616bb079c4e6d038c0addb33481
 F src/os.h 4e480eb92737ebcdd1e1136bdbf5cd22223bd1b4
 F src/os_common.h 7b0f4ae0d9f66888f90ab28f126b42bfefe0bbd4
@@ -50,13 +50,13 @@ F src/os_win.h 004eec47b1780fcaf07420ddc2072294b698d48c
 F src/pager.c 944f6b071279887574081281f27bb2af88b42905
 F src/pager.h 0c7b5ac45c69e690c45d160d03bdc8fbd2d4657b
 F src/parse.y 27c1ce09f9d309be91f9e537df2fb00892990af4
-F src/pragma.c 1b58d852b84b36a8b84e2245dd29b63c377414ec
+F src/pragma.c 54b4d67fa81fd38b911aa3325348dcae9ceac5a4
 F src/printf.c 77ee9ec6dbf1b7512b17d63ccf8322ea9466278b
 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
 F src/select.c 02d711160100ef3a730060f7cfb5bc85fde06d72
 F src/shell.c 79af86d39b2149c7f16219fcbe636e7c2da9df8e
 F src/sqlite.h.in 4705697dd7213f322d59ffc69b48b8ac32b23373
-F src/sqliteInt.h 306256532411cc7b9019b82d3697c534a322e2a7
+F src/sqliteInt.h 845d2a3ffdb9a9050a1b55044d4856227b649b84
 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
 F src/tclsqlite.c 3db6b868bd844bfb71720c8e573f4c9b0d536bd5
 F src/test1.c 4a3cc1b628a29f24c0a43227a035d0f2a96eb634
@@ -65,7 +65,7 @@ F src/test3.c beafd0ccf7b9ae784744be1b1e66ffe8f64c25da
 F src/test4.c caf675e443460ec76b04d78e1688986c17c82cec
 F src/test5.c 44178ce85c3afd2004ab4eeb5cfd7487116ce366
 F src/tokenize.c 183c5d7da11affab5d70d903d33409c8c0ce6c5b
-F src/trigger.c 04b2c310d0d056b213609cab6df5fff03d5eaf88
+F src/trigger.c 532daca4972bbf1165bdeecf48d9949eee8c24c0
 F src/update.c 259f06e7b22c684b2d3dda54a18185892d6e9573
 F src/utf.c c2c8e445bfea724f3502609d6389fe66651f02ab
 F src/util.c 8b3680271111bcdf5b395916b08b9a6684e0e73d
@@ -80,7 +80,7 @@ F src/where.c 444a7c3a8b1eb7bba072e489af628555d21d92a4
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
 F test/attach.test 1635022d7e1d95dc92fe381cc62f9bf25cb29d73
 F test/attach2.test e98aab312722d05fc1837bf103baeebc582c64f8
-F test/attach3.test d384ac2e59f305743f73aec4b3d97b36fa5c6975
+F test/attach3.test 8259ab833b5dcdf4acd75d9653f42f703ce2e013
 F test/auth.test 95809b8f6a9bec18b94d28cafd03fe27d2f8a9e9
 F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81
 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
@@ -99,7 +99,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
 F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d
 F test/delete.test ddb1d4e172a01c0165804f82f81df556fb48a856
 F test/enc.test a55481d45ff493804e8d88357feb4642fc50a6b2
-F test/enc2.test 8ab83839b73ce3a571b1396379f2f8ae3c895d74
+F test/enc2.test a46170cc3a3fdc3e8647abf8eebca584886cf611
 F test/expr.test 521588701dae8cf5aa2b8a18c5c897711f754332
 F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7
 F test/func.test 9816fbed0a5e87e00f4fc88b4cdcd638abc524c4
@@ -215,7 +215,7 @@ F www/support.tcl 1801397edd271cc39a2aadd54e701184b5181248
 F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 30b81507fc404355751705c6f9856c178249eff1
-R f549135a3da153baeae9af57b4d41e2b
-U drh
-Z 564efee24b8b93a5d228cb5bc9c253cb
+P 4f7c0961ad6cb7082bf7716f0c7ca16a8742c039
+R ec69eb8a9c750d8d0b48358a8267ec3f
+U danielk1977
+Z 53de26870eaceb80255c757bed464dd0
index e8d06e14dfe82b1d6f4be99b97f7965de271ab9c..1b432f643fc633a7ebbca714aeea46fc07702614 100644 (file)
@@ -1 +1 @@
-4f7c0961ad6cb7082bf7716f0c7ca16a8742c039
\ No newline at end of file
+983221b038813c5a7892564896e39597c223c4c3
\ No newline at end of file
index 89c3b3b57455305580cb8fc0d713605cec35d8b5..46f2226475ac79f58ccc3e3aec71aa3bcc0cbfa3 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the ATTACH and DETACH commands.
 **
-** $Id: attach.c,v 1.12 2004/05/11 07:11:52 danielk1977 Exp $
+** $Id: attach.c,v 1.13 2004/06/07 07:52:18 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -105,7 +105,7 @@ void sqlite3Attach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey)
   db->flags &= ~SQLITE_Initialized;
   if( pParse->nErr ) return;
   if( rc==SQLITE_OK ){
-    rc = sqlite3Init(pParse->db, &pParse->zErrMsg);
+    rc = sqlite3ReadSchema(pParse->db);
   }
   if( rc ){
     int i = db->nDb - 1;
index 30f8d04b9e52052ca876c2f4180985f2ebb2ab4e..a0cd3b589c4774a1dc1bd52ec092f674cc35cc30 100644 (file)
@@ -23,7 +23,7 @@
 **     ROLLBACK
 **     PRAGMA
 **
-** $Id: build.c,v 1.206 2004/06/03 16:08:41 danielk1977 Exp $
+** $Id: build.c,v 1.207 2004/06/07 07:52:18 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -38,6 +38,7 @@ void sqlite3BeginParse(Parse *pParse, int explainFlag){
   sqlite *db = pParse->db;
   int i;
   pParse->explain = explainFlag;
+#if 0
   if((db->flags & SQLITE_Initialized)==0 && db->init.busy==0 ){
     int rc = sqlite3Init(db, &pParse->zErrMsg);
     if( rc!=SQLITE_OK ){
@@ -45,6 +46,7 @@ void sqlite3BeginParse(Parse *pParse, int explainFlag){
       pParse->nErr++;
     }
   }
+#endif
   for(i=0; i<db->nDb; i++){
     DbClearProperty(db, i, DB_Locked);
     if( !db->aDb[i].inTrans ){
@@ -105,7 +107,8 @@ void sqlite3Exec(Parse *pParse){
 Table *sqlite3FindTable(sqlite *db, const char *zName, const char *zDatabase){
   Table *p = 0;
   int i;
-  for(i=0; i<db->nDb; i++){
+  int rc = sqlite3ReadSchema(db);
+  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
     int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
     if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
     p = sqlite3HashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1);
@@ -157,7 +160,8 @@ Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){
 Index *sqlite3FindIndex(sqlite *db, const char *zName, const char *zDb){
   Index *p = 0;
   int i;
-  for(i=0; i<db->nDb; i++){
+  int rc = sqlite3ReadSchema(db);
+  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
     int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
     if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
     p = sqlite3HashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1);
@@ -931,16 +935,6 @@ void sqlite3ChangeCookie(sqlite *db, Vdbe *v, int iDb){
   db->flags |= SQLITE_InternChanges;
   sqlite3VdbeAddOp(v, OP_Integer, *pSchemaCookie, 0);
   sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
-/*
-  if( db->next_cookie==db->aDb[0].schema_cookie ){
-    unsigned char r;
-    sqlite3Randomness(1, &r);
-    db->next_cookie = db->aDb[0].schema_cookie + r + 1;
-    db->flags |= SQLITE_InternChanges;
-    sqlite3VdbeAddOp(v, OP_Integer, db->next_cookie, 0);
-    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
-  }
-*/
 }
 
 /*
@@ -1404,22 +1398,28 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
   v = sqlite3GetVdbe(pParse);
   if( v ){
     static VdbeOpList dropTable[] = {
-      { OP_Rewind,     0, ADDR(10), 0},
-      { OP_String8,     0, 0,        0}, /* 1 */
+      { OP_Rewind,     0, ADDR(13), 0},
+      { OP_String8,    0, 0,        0}, /* 1 */
       { OP_MemStore,   1, 1,        0},
       { OP_MemLoad,    1, 0,        0}, /* 3 */
-      { OP_Column,     0, 2,        0},
-      { OP_Ne,         0, ADDR(9),  0},
+      { OP_Column,     0, 2,        0}, /* sqlite_master.tbl_name */
+      { OP_Ne,         0, ADDR(12), 0},
+      { OP_String8,    0, 0,        "trigger"},
+      { OP_Column,     0, 2,        0}, /* sqlite_master.type */
+      { OP_Eq,         0, ADDR(12), 0},
       { OP_Delete,     0, 0,        0},
-      { OP_Rewind,     0, ADDR(10), 0},
+      { OP_Rewind,     0, ADDR(13), 0},
       { OP_Goto,       0, ADDR(3),  0},
-      { OP_Next,       0, ADDR(3),  0}, /* 9 */
+      { OP_Next,       0, ADDR(3),  0}, /* 12 */
     };
     Index *pIdx;
     Trigger *pTrigger;
     sqlite3BeginWriteOperation(pParse, 0, pTab->iDb);
 
-    /* Drop all triggers associated with the table being dropped */
+    /* Drop all triggers associated with the table being dropped. Code
+    ** is generated to remove entries from sqlite_master and/or
+    ** sqlite_temp_master if required.
+    */
     pTrigger = pTab->pTrigger;
     while( pTrigger ){
       assert( pTrigger->iDb==pTab->iDb || pTrigger->iDb==1 );
@@ -1431,21 +1431,17 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
       }
     }
 
-    /* Drop all SQLITE_MASTER entries that refer to the table */
+    /* Drop all SQLITE_MASTER table and index entries that refer to the
+    ** table. The program name loops through the master table and deletes
+    ** every row that refers to a table of the same name as the one being
+    ** dropped. Triggers are handled seperately because a trigger can be
+    ** created in the temp database that refers to a table in another
+    ** database.
+    */
     sqlite3OpenMasterTable(v, pTab->iDb);
     base = sqlite3VdbeAddOpList(v, ArraySize(dropTable), dropTable);
     sqlite3VdbeChangeP3(v, base+1, pTab->zName, 0);
-
-    /* Drop all SQLITE_TEMP_MASTER entries that refer to the table */
-    if( pTab->iDb!=1 ){
-      sqlite3OpenMasterTable(v, 1);
-      base = sqlite3VdbeAddOpList(v, ArraySize(dropTable), dropTable);
-      sqlite3VdbeChangeP3(v, base+1, pTab->zName, 0);
-    }
-
-    if( pTab->iDb!=1 ){  /* Temp database has no schema cookie */
-      sqlite3ChangeCookie(db, v, pTab->iDb);
-    }
+    sqlite3ChangeCookie(db, v, pTab->iDb);
     sqlite3VdbeAddOp(v, OP_Close, 0, 0);
     if( !isView ){
       sqlite3VdbeAddOp(v, OP_Destroy, pTab->tnum, pTab->iDb);
@@ -2262,7 +2258,7 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
   Vdbe *v = sqlite3GetVdbe(pParse);
   if( v==0 ) return;
   sqlite3VdbeAddOp(v, OP_Transaction, iDb, 1);
-  if( iDb!=1 && (iDb>63 || !(pParse->cookieMask & ((u64)1<<iDb))) ){
+  if( (iDb>63 || !(pParse->cookieMask & ((u64)1<<iDb))) ){
     sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, db->aDb[iDb].schema_cookie);
     pParse->cookieMask |= ((u64)1<<iDb);
   }
index c0dada0a64fc5f003d581d3c68c1b435b9a6608e..216763195588b8dad57b4e179b0440f28feae5dd 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.205 2004/06/06 09:44:04 danielk1977 Exp $
+** $Id: main.c,v 1.206 2004/06/07 07:52:18 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -349,11 +349,7 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
 ** error occurs, write an error message into *pzErrMsg.
 **
 ** After the database is initialized, the SQLITE_Initialized
-** bit is set in the flags field of the sqlite structure.  An
-** attempt is made to initialize the database as soon as it
-** is opened.  If that fails (perhaps because another process
-** has the sqlite_master table locked) than another attempt
-** is made the first time the database is accessed.
+** bit is set in the flags field of the sqlite structure. 
 */
 int sqlite3Init(sqlite *db, char **pzErrMsg){
   int i, rc;
@@ -382,6 +378,28 @@ int sqlite3Init(sqlite *db, char **pzErrMsg){
   return rc;
 }
 
+/*
+** This routine is a no-op if the database schema is already initialised.
+** Otherwise, the schema is loaded. An error code is returned.
+*/
+int sqlite3ReadSchema(sqlite *db){
+  int rc = SQLITE_OK;
+  char *zErrMsg = 0;
+
+  if( !db->init.busy ){
+    if( (db->flags & SQLITE_Initialized)==0 ){
+      rc = sqlite3Init(db, &zErrMsg);
+    }
+  }
+  assert( (db->flags & SQLITE_Initialized)!=0 || db->init.busy );
+
+  sqlite3Error(db, rc, zErrMsg);
+  if( zErrMsg ){
+    sqliteFree(zErrMsg);
+  }
+  return rc;
+}
+
 /*
 ** The version of the library
 */
@@ -845,21 +863,6 @@ int sqlite3_prepare(
     goto prepare_out;
   }
 
-  if( !db->init.busy ){
-    if( (db->flags & SQLITE_Initialized)==0 ){
-      int cnt = 1;
-      rc = sqlite3Init(db, &zErrMsg);
-      if( rc!=SQLITE_OK ){
-        goto prepare_out;
-      }
-      if( zErrMsg ){
-        sqliteFree(zErrMsg);
-        zErrMsg = 0;
-      }
-    }
-  }
-  assert( (db->flags & SQLITE_Initialized)!=0 || db->init.busy );
-
   if( db->pVdbe==0 ){ db->nChange = 0; }
   memset(&sParse, 0, sizeof(sParse));
   sParse.db = db;
@@ -974,27 +977,12 @@ int sqlite3_prepare16(
 */
 static int openDatabase(
   const char *zFilename, /* Database filename UTF-8 encoded */
-  sqlite3 **ppDb,        /* OUT: Returned database handle */
-  const char **options,  /* Null terminated list of db options, or null */
-  u8 def_enc             /* One of TEXT_Utf8, TEXT_Utf16le or TEXT_Utf16be */
+  sqlite3 **ppDb         /* OUT: Returned database handle */
 ){
   sqlite3 *db;
   int rc, i;
   char *zErrMsg = 0;
 
-#ifdef SQLITE_TEST
-  for(i=0; options && options[i]; i++){
-    char const *zOpt = options[i];
-    if( 0==sqlite3StrICmp(zOpt, "-utf8") ){
-      def_enc = TEXT_Utf8;
-    }else if( 0==sqlite3StrICmp(zOpt, "-utf16le") ){
-      def_enc = TEXT_Utf16le;
-    }else if( 0==sqlite3StrICmp(zOpt, "-utf16be") ){
-      def_enc = TEXT_Utf16be;
-    }
-  }
-#endif
-
   /* Allocate the sqlite data structure */
   db = sqliteMalloc( sizeof(sqlite) );
   if( db==0 ) goto opendb_out;
@@ -1002,7 +990,7 @@ static int openDatabase(
   db->magic = SQLITE_MAGIC_BUSY;
   db->nDb = 2;
   db->aDb = db->aDbStatic;
-  db->enc = def_enc;
+  db->enc = TEXT_Utf8;
   db->autoCommit = 1;
   /* db->flags |= SQLITE_ShortColNames; */
   sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
@@ -1030,20 +1018,18 @@ static int openDatabase(
   db->aDb[0].zName = "main";
   db->aDb[1].zName = "temp";
 
-  /* Attempt to read the schema */
+  /* 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.
+  */
   sqlite3RegisterBuiltinFunctions(db);
-  rc = sqlite3Init(db, &zErrMsg);
-  if( sqlite3_malloc_failed ){
-    sqlite3_close(db);
-    db = 0;
-    goto opendb_out;
-  }else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
+  if( rc==SQLITE_OK ){
+    db->magic = SQLITE_MAGIC_OPEN;
+  }else{
     sqlite3Error(db, rc, "%s", zErrMsg, 0);
+    if( zErrMsg ) sqliteFree(zErrMsg);
     db->magic = SQLITE_MAGIC_CLOSED;
-  }else{
-    db->magic = SQLITE_MAGIC_OPEN;
   }
-  if( zErrMsg ) sqliteFree(zErrMsg);
 
 opendb_out:
   *ppDb = db;
@@ -1058,7 +1044,7 @@ int sqlite3_open(
   sqlite3 **ppDb, 
   const char **options
 ){
-  return openDatabase(zFilename, ppDb, options, TEXT_Utf8);
+  return openDatabase(zFilename, ppDb);
 }
 
 /*
@@ -1079,16 +1065,12 @@ int sqlite3_open16(
     *ppDb = 0;
     return SQLITE_NOMEM;
   }
-
-  /* FIX ME: Also need to translate the option strings */
-
-  if( SQLITE_BIGENDIAN ){
-    rc = openDatabase(zFilename8, ppDb, options, TEXT_Utf16be);
-  }else{
-    rc = openDatabase(zFilename8, ppDb, options, TEXT_Utf16le);
+  rc = openDatabase(zFilename8, ppDb);
+  if( rc==SQLITE_OK && *ppDb ){
+    sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
   }
-
   sqliteFree(zFilename8);
+
   return rc;
 }
 
index 8df5cd381a9913ac9e35624489bbbb604a7717a7..85bb495fdcc1f10f991448fab7c747b448dceb9d 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.36 2004/06/03 16:08:42 danielk1977 Exp $
+** $Id: pragma.c,v 1.37 2004/06/07 07:52:18 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -203,6 +203,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
       { OP_Callback,    1, 0,        0},
     };
     int addr;
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     if( pRight->z==pLeft->z ){
       sqlite3VdbeSetNumCols(v, 1);
       sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
@@ -242,6 +243,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
     static VdbeOpList getCacheSize[] = {
       { OP_Callback,    1, 0,        0},
     };
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     if( pRight->z==pLeft->z ){
       int size = db->cache_size;;
       if( size<0 ) size = -size;
@@ -292,6 +294,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
       { OP_Callback,    1, 0,        0}
     };
     int addr;
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     if( pRight->z==pLeft->z ){
       sqlite3VdbeSetNumCols(v, 1);
       sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
@@ -335,6 +338,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
     static VdbeOpList getSync[] = {
       { OP_Callback,    1, 0,        0},
     };
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     if( pRight->z==pLeft->z ){
       sqlite3VdbeSetNumCols(v, 1);
       sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
@@ -367,6 +371,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
 
   if( sqlite3StrICmp(zLeft, "table_info")==0 ){
     Table *pTab;
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     pTab = sqlite3FindTable(db, zRight, 0);
     if( pTab ){
       int i;
@@ -395,6 +400,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
   if( sqlite3StrICmp(zLeft, "index_info")==0 ){
     Index *pIdx;
     Table *pTab;
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     pIdx = sqlite3FindIndex(db, zRight, 0);
     if( pIdx ){
       int i;
@@ -417,6 +423,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
   if( sqlite3StrICmp(zLeft, "index_list")==0 ){
     Index *pIdx;
     Table *pTab;
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     pTab = sqlite3FindTable(db, zRight, 0);
     if( pTab ){
       v = sqlite3GetVdbe(pParse);
@@ -442,6 +449,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
   if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 ){
     FKey *pFK;
     Table *pTab;
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     pTab = sqlite3FindTable(db, zRight, 0);
     if( pTab ){
       v = sqlite3GetVdbe(pParse);
@@ -474,6 +482,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
 
   if( sqlite3StrICmp(zLeft, "database_list")==0 ){
     int i;
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     sqlite3VdbeSetNumCols(v, 3);
     sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
     sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
@@ -505,6 +514,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
     static VdbeOpList getTmpDbLoc[] = {
       { OP_Callback,    1, 0,        0},
     };
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     if( pRight->z==pLeft->z ){
       sqlite3VdbeAddOp(v, OP_Integer, db->temp_store, 0);
       sqlite3VdbeSetNumCols(v, 1);
@@ -530,6 +540,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
     static VdbeOpList getTmpDbLoc[] = {
       { OP_ReadCookie,  0, 5,        0},
       { OP_Callback,    1, 0,        0}};
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     if( pRight->z==pLeft->z ){
       sqlite3VdbeSetNumCols(v, 1);
       sqlite3VdbeSetColName(v, 0, "temp_store", P3_STATIC);
@@ -545,6 +556,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
 #ifndef NDEBUG
   if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
     extern void sqlite3ParserTrace(FILE*, char *);
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     if( getBoolean(zRight) ){
       sqlite3ParserTrace(stdout, "parser: ");
     }else{
@@ -577,6 +589,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
     };
 
     /* Initialize the VDBE program */
+    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
     sqlite3VdbeSetNumCols(v, 1);
     sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
     sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode);
@@ -680,6 +693,76 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
     addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
     sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
   }else
+  /*
+  **   PRAGMA encoding
+  **   PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
+  **
+  ** In it's first form, this pragma returns the encoding of the main
+  ** database. If the database is not initialized, it is initialized now.
+  **
+  ** The second form of this pragma is a no-op if the main database file
+  ** has not already been initialized. In this case it sets the default
+  ** encoding that will be used for the main database file if a new file
+  ** is created. If an existing main database file is opened, then the
+  ** default text encoding for the existing database is used.
+  ** 
+  ** In all cases new databases created using the ATTACH command are
+  ** created to use the same default text encoding as the main database. If
+  ** the main database has not been initialized and/or created when ATTACH
+  ** is executed, this is done before the ATTACH operation.
+  **
+  ** In the second form this pragma sets the text encoding to be used in
+  ** new database files created using this database handle. It is only
+  ** useful if invoked immediately after the main database i
+  */
+  if( sqlite3StrICmp(zLeft, "encoding")==0 ){
+    struct EncName {
+      char *zName;
+      u8 enc;
+    } encnames[] = {
+      { "UTF-8", TEXT_Utf8 },
+      { "UTF-16le", TEXT_Utf16le },
+      { "UTF-16be", TEXT_Utf16be },
+      { "UTF-16", TEXT_Utf16 },
+      { "UTF8", TEXT_Utf8 },
+      { "UTF16le", TEXT_Utf16le },
+      { "UTF16be", TEXT_Utf16be },
+      { "UTF16", TEXT_Utf16 },
+      { 0, 0 }
+    };
+    struct EncName *pEnc;
+    if( pRight->z==pLeft->z ){    /* "PRAGMA encoding" */
+      if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
+      sqlite3VdbeSetNumCols(v, 1);
+      sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
+      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
+      for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
+        if( pEnc->enc==pParse->db->enc ){
+          sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);
+          break;
+        }
+      }
+      sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
+    }else{                        /* "PRAGMA encoding = XXX" */
+      /* Only change the value of sqlite.enc if the database handle is not
+      ** initialized. If the main database exists, the new sqlite.enc value
+      ** will be overwritten when the schema is next loaded. If it does not
+      ** already exists, it will be created to use the new encoding value.
+      */
+      if( !(pParse->db->flags&SQLITE_Initialized) ){
+        for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
+          if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
+            pParse->db->enc = pEnc->enc;
+            break;
+          }
+        }
+        if( !pEnc->zName ){
+          sqlite3Error(pParse->db, SQLITE_ERROR, 
+              "Unsupported encoding: %s", zRight);
+        }
+      }
+    }
+  }else
 
   {}
   sqliteFree(zLeft);
index ba9231158a71856cadc92f5908228fd23707628d..bc73f021d222af3c567881b9f7d6fe9be1c941be 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.270 2004/06/07 01:52:14 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.271 2004/06/07 07:52:18 danielk1977 Exp $
 */
 #include "config.h"
 #include "sqlite3.h"
@@ -1374,3 +1374,4 @@ void *sqlite3HexToBlob(const char *z);
 int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
 const char *sqlite3ErrStr(int);
 int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold);
+int sqlite3ReadSchema(sqlite *db);
index 20f71b57de24263a01aee89ee61b5e83bcf67579..b40ae7d2fe06849e7d62f6725f914b8389fde6b4 100644 (file)
@@ -421,6 +421,8 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
   sqlite *db = pParse->db;
 
   if( sqlite3_malloc_failed ) goto drop_trigger_cleanup;
+  if( SQLITE_OK!=sqlite3ReadSchema(db) ) goto drop_trigger_cleanup;
+
   assert( pName->nSrc==1 );
   zDb = pName->a[0].zDatabase;
   zName = pName->a[0].zName;
@@ -470,7 +472,7 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
 
   /* Generate code to destroy the database record of the trigger.
   */
-  if( pTable!=0 && !nested && (v = sqlite3GetVdbe(pParse))!=0 ){
+  if( pTable!=0 && (v = sqlite3GetVdbe(pParse))!=0 ){
     int base;
     static VdbeOpList dropTrigger[] = {
       { OP_Rewind,     0, ADDR(9),  0},
@@ -488,16 +490,13 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
     sqlite3OpenMasterTable(v, pTrigger->iDb);
     base = sqlite3VdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
     sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0);
-    if( pTrigger->iDb!=1 ){
-      sqlite3ChangeCookie(db, v, pTrigger->iDb);
-    }
+    sqlite3ChangeCookie(db, v, pTrigger->iDb);
     sqlite3VdbeAddOp(v, OP_Close, 0, 0);
-    sqlite3EndWriteOperation(pParse);
   }
 
   /*
-   * If this is not an "explain", then delete the trigger structure.
-   */
+  ** If this is not an "explain", then delete the trigger structure.
+  */
   if( !pParse->explain ){
     const char *zName = pTrigger->name;
     int nName = strlen(zName);
index a0f6696b2ef8b8caecb61cb0630912b61700f224..f6d9a536b305537e31a68ce0f5cad569bbea595b 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this script is testing the ATTACH and DETACH commands
 # and schema changes to attached databases.
 #
-# $Id: attach3.test,v 1.5 2004/05/29 10:23:20 danielk1977 Exp $
+# $Id: attach3.test,v 1.6 2004/06/07 07:52:19 danielk1977 Exp $
 #
 
 
@@ -188,6 +188,30 @@ do_test attach3-8.2 {
   }
 } {}
 
+# Try to trick SQLite into dropping the wrong temp trigger.
+do_test attach3-9.0 {
+  execsql {
+    CREATE TABLE main.t4(a, b, c);
+    CREATE TABLE aux.t4(a, b, c);
+    CREATE TEMP TRIGGER tst_trigger BEFORE INSERT ON aux.t4 BEGIN 
+      SELECT 'hello world';
+    END;
+    SELECT count(*) FROM sqlite_temp_master;
+  }
+} {1}
+do_test attach3-9.1 {
+  execsql {
+    DROP TABLE main.t4;
+    SELECT count(*) FROM sqlite_temp_master;
+  }
+} {1}
+do_test attach3-9.2 {
+  execsql {
+    DROP TABLE aux.t4;
+    SELECT count(*) FROM sqlite_temp_master;
+  }
+} {0}
+
 finish_test
 
 
index 9e56bdc4741f0885b2af0c0b3de54933fb2f874a..5c1f35511b093d8900c3274b2ba9ca8f54a2a163 100644 (file)
@@ -13,7 +13,7 @@
 # various suported unicode encodings (UTF-8, UTF-16, UTF-16le and
 # UTF-16be).
 #
-# $Id: enc2.test,v 1.4 2004/05/27 17:22:56 drh Exp $
+# $Id: enc2.test,v 1.5 2004/06/07 07:52:19 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -45,7 +45,7 @@ set dbcontents {
 # database, and that it is possible to retreive values in
 # various text encodings.
 #
-proc run_test_script {t} {
+proc run_test_script {t enc} {
 
 # Open the database and pull out a (the) row.
 do_test $t.1 {
@@ -102,22 +102,23 @@ do_test $t.9 {
   sqlite3_finalize $STMT
 } SQLITE_OK
 
-do_test $t.99 {
-  db close
-} {}
+do_test $t.10 {
+  db eval {PRAGMA encoding}
+} $enc
 
 }
 
 # The three unicode encodings understood by SQLite.
-set encodings [list -utf8 -utf16be -utf16le]
+set encodings [list UTF-8 UTF-16le UTF-16be]
 
 set i 1
 foreach enc $encodings {
   file delete -force test.db
   sqlite db test.db $enc
+  db eval "PRAGMA encoding = \"$enc\""
   execsql $dbcontents
   db close
-  run_test_script enc2-$i
+  run_test_script enc2-$i $enc
   incr i
 }