1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Add pragma to set/get text encoding. Also fix an obscure problem where a

temp trigger could be accidently dropped. (CVS 1537)

FossilOrigin-Name: 983221b038813c5a7892564896e39597c223c4c3
This commit is contained in:
danielk1977
2004-06-07 07:52:17 +00:00
parent e54ca3fe2e
commit 8e227875dd
10 changed files with 211 additions and 125 deletions

View File

@@ -1,5 +1,5 @@
C Progress\stowards\sgetting\slocking\sto\swork\son\swindows.\s(CVS\s1536) 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-07T01:52:14 D 2004-06-07T07:52:18
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -23,11 +23,11 @@ F spec.template a38492f1c1dd349fc24cb0565e08afc53045304b
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f
F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2 F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
F src/attach.c c315c58cb16fd6e913b3bfa6412aedecb4567fa5 F src/attach.c e76e4590ec5dd389e5646b171881b5243a6ef391
F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79 F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79
F src/btree.c 3f0c22ab8c0c000ee5de4ad875836c111c4191c6 F src/btree.c 3f0c22ab8c0c000ee5de4ad875836c111c4191c6
F src/btree.h 589427ac13bb544d298cd99726e2572a6fe4bdaa F src/btree.h 589427ac13bb544d298cd99726e2572a6fe4bdaa
F src/build.c e12e602f06e37a0fbcb49af17cba68ad85e101b6 F src/build.c 92144f30d30fa00cb21c9c9e51de49cfb948d113
F src/date.c 8e6fa3173386fb29fdef012ee08a853c1e9908b2 F src/date.c 8e6fa3173386fb29fdef012ee08a853c1e9908b2
F src/delete.c b30f08250c9ed53a25a13c7c04599c1e8753992d F src/delete.c b30f08250c9ed53a25a13c7c04599c1e8753992d
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
@@ -37,7 +37,7 @@ F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
F src/insert.c 4268d9e3959cc845ea243fb4ec7507269404dad9 F src/insert.c 4268d9e3959cc845ea243fb4ec7507269404dad9
F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
F src/main.c 2e4d37f0f8f31694b79823a530ea4b52c8e1a7fd F src/main.c d34e173296473c9626f2560a0c86e694fc8e5a2b
F src/md5.c 4302e84ae516c616bb079c4e6d038c0addb33481 F src/md5.c 4302e84ae516c616bb079c4e6d038c0addb33481
F src/os.h 4e480eb92737ebcdd1e1136bdbf5cd22223bd1b4 F src/os.h 4e480eb92737ebcdd1e1136bdbf5cd22223bd1b4
F src/os_common.h 7b0f4ae0d9f66888f90ab28f126b42bfefe0bbd4 F src/os_common.h 7b0f4ae0d9f66888f90ab28f126b42bfefe0bbd4
@@ -50,13 +50,13 @@ F src/os_win.h 004eec47b1780fcaf07420ddc2072294b698d48c
F src/pager.c 944f6b071279887574081281f27bb2af88b42905 F src/pager.c 944f6b071279887574081281f27bb2af88b42905
F src/pager.h 0c7b5ac45c69e690c45d160d03bdc8fbd2d4657b F src/pager.h 0c7b5ac45c69e690c45d160d03bdc8fbd2d4657b
F src/parse.y 27c1ce09f9d309be91f9e537df2fb00892990af4 F src/parse.y 27c1ce09f9d309be91f9e537df2fb00892990af4
F src/pragma.c 1b58d852b84b36a8b84e2245dd29b63c377414ec F src/pragma.c 54b4d67fa81fd38b911aa3325348dcae9ceac5a4
F src/printf.c 77ee9ec6dbf1b7512b17d63ccf8322ea9466278b F src/printf.c 77ee9ec6dbf1b7512b17d63ccf8322ea9466278b
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c 02d711160100ef3a730060f7cfb5bc85fde06d72 F src/select.c 02d711160100ef3a730060f7cfb5bc85fde06d72
F src/shell.c 79af86d39b2149c7f16219fcbe636e7c2da9df8e F src/shell.c 79af86d39b2149c7f16219fcbe636e7c2da9df8e
F src/sqlite.h.in 4705697dd7213f322d59ffc69b48b8ac32b23373 F src/sqlite.h.in 4705697dd7213f322d59ffc69b48b8ac32b23373
F src/sqliteInt.h 306256532411cc7b9019b82d3697c534a322e2a7 F src/sqliteInt.h 845d2a3ffdb9a9050a1b55044d4856227b649b84
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
F src/tclsqlite.c 3db6b868bd844bfb71720c8e573f4c9b0d536bd5 F src/tclsqlite.c 3db6b868bd844bfb71720c8e573f4c9b0d536bd5
F src/test1.c 4a3cc1b628a29f24c0a43227a035d0f2a96eb634 F src/test1.c 4a3cc1b628a29f24c0a43227a035d0f2a96eb634
@@ -65,7 +65,7 @@ F src/test3.c beafd0ccf7b9ae784744be1b1e66ffe8f64c25da
F src/test4.c caf675e443460ec76b04d78e1688986c17c82cec F src/test4.c caf675e443460ec76b04d78e1688986c17c82cec
F src/test5.c 44178ce85c3afd2004ab4eeb5cfd7487116ce366 F src/test5.c 44178ce85c3afd2004ab4eeb5cfd7487116ce366
F src/tokenize.c 183c5d7da11affab5d70d903d33409c8c0ce6c5b F src/tokenize.c 183c5d7da11affab5d70d903d33409c8c0ce6c5b
F src/trigger.c 04b2c310d0d056b213609cab6df5fff03d5eaf88 F src/trigger.c 532daca4972bbf1165bdeecf48d9949eee8c24c0
F src/update.c 259f06e7b22c684b2d3dda54a18185892d6e9573 F src/update.c 259f06e7b22c684b2d3dda54a18185892d6e9573
F src/utf.c c2c8e445bfea724f3502609d6389fe66651f02ab F src/utf.c c2c8e445bfea724f3502609d6389fe66651f02ab
F src/util.c 8b3680271111bcdf5b395916b08b9a6684e0e73d F src/util.c 8b3680271111bcdf5b395916b08b9a6684e0e73d
@@ -80,7 +80,7 @@ F src/where.c 444a7c3a8b1eb7bba072e489af628555d21d92a4
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F test/attach.test 1635022d7e1d95dc92fe381cc62f9bf25cb29d73 F test/attach.test 1635022d7e1d95dc92fe381cc62f9bf25cb29d73
F test/attach2.test e98aab312722d05fc1837bf103baeebc582c64f8 F test/attach2.test e98aab312722d05fc1837bf103baeebc582c64f8
F test/attach3.test d384ac2e59f305743f73aec4b3d97b36fa5c6975 F test/attach3.test 8259ab833b5dcdf4acd75d9653f42f703ce2e013
F test/auth.test 95809b8f6a9bec18b94d28cafd03fe27d2f8a9e9 F test/auth.test 95809b8f6a9bec18b94d28cafd03fe27d2f8a9e9
F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81 F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
@@ -99,7 +99,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d
F test/delete.test ddb1d4e172a01c0165804f82f81df556fb48a856 F test/delete.test ddb1d4e172a01c0165804f82f81df556fb48a856
F test/enc.test a55481d45ff493804e8d88357feb4642fc50a6b2 F test/enc.test a55481d45ff493804e8d88357feb4642fc50a6b2
F test/enc2.test 8ab83839b73ce3a571b1396379f2f8ae3c895d74 F test/enc2.test a46170cc3a3fdc3e8647abf8eebca584886cf611
F test/expr.test 521588701dae8cf5aa2b8a18c5c897711f754332 F test/expr.test 521588701dae8cf5aa2b8a18c5c897711f754332
F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7 F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7
F test/func.test 9816fbed0a5e87e00f4fc88b4cdcd638abc524c4 F test/func.test 9816fbed0a5e87e00f4fc88b4cdcd638abc524c4
@@ -215,7 +215,7 @@ F www/support.tcl 1801397edd271cc39a2aadd54e701184b5181248
F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075 F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
P 30b81507fc404355751705c6f9856c178249eff1 P 4f7c0961ad6cb7082bf7716f0c7ca16a8742c039
R f549135a3da153baeae9af57b4d41e2b R ec69eb8a9c750d8d0b48358a8267ec3f
U drh U danielk1977
Z 564efee24b8b93a5d228cb5bc9c253cb Z 53de26870eaceb80255c757bed464dd0

View File

@@ -1 +1 @@
4f7c0961ad6cb7082bf7716f0c7ca16a8742c039 983221b038813c5a7892564896e39597c223c4c3

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands. ** 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" #include "sqliteInt.h"
@@ -105,7 +105,7 @@ void sqlite3Attach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey)
db->flags &= ~SQLITE_Initialized; db->flags &= ~SQLITE_Initialized;
if( pParse->nErr ) return; if( pParse->nErr ) return;
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqlite3Init(pParse->db, &pParse->zErrMsg); rc = sqlite3ReadSchema(pParse->db);
} }
if( rc ){ if( rc ){
int i = db->nDb - 1; int i = db->nDb - 1;

View File

@@ -23,7 +23,7 @@
** ROLLBACK ** ROLLBACK
** PRAGMA ** 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 "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -38,6 +38,7 @@ void sqlite3BeginParse(Parse *pParse, int explainFlag){
sqlite *db = pParse->db; sqlite *db = pParse->db;
int i; int i;
pParse->explain = explainFlag; pParse->explain = explainFlag;
#if 0
if((db->flags & SQLITE_Initialized)==0 && db->init.busy==0 ){ if((db->flags & SQLITE_Initialized)==0 && db->init.busy==0 ){
int rc = sqlite3Init(db, &pParse->zErrMsg); int rc = sqlite3Init(db, &pParse->zErrMsg);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
@@ -45,6 +46,7 @@ void sqlite3BeginParse(Parse *pParse, int explainFlag){
pParse->nErr++; pParse->nErr++;
} }
} }
#endif
for(i=0; i<db->nDb; i++){ for(i=0; i<db->nDb; i++){
DbClearProperty(db, i, DB_Locked); DbClearProperty(db, i, DB_Locked);
if( !db->aDb[i].inTrans ){ if( !db->aDb[i].inTrans ){
@@ -105,7 +107,8 @@ void sqlite3Exec(Parse *pParse){
Table *sqlite3FindTable(sqlite *db, const char *zName, const char *zDatabase){ Table *sqlite3FindTable(sqlite *db, const char *zName, const char *zDatabase){
Table *p = 0; Table *p = 0;
int i; 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 */ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue; if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
p = sqlite3HashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1); 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 *sqlite3FindIndex(sqlite *db, const char *zName, const char *zDb){
Index *p = 0; Index *p = 0;
int i; 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 */ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue; if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
p = sqlite3HashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1); 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; db->flags |= SQLITE_InternChanges;
sqlite3VdbeAddOp(v, OP_Integer, *pSchemaCookie, 0); sqlite3VdbeAddOp(v, OP_Integer, *pSchemaCookie, 0);
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 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); v = sqlite3GetVdbe(pParse);
if( v ){ if( v ){
static VdbeOpList dropTable[] = { static VdbeOpList dropTable[] = {
{ OP_Rewind, 0, ADDR(10), 0}, { OP_Rewind, 0, ADDR(13), 0},
{ OP_String8, 0, 0, 0}, /* 1 */ { OP_String8, 0, 0, 0}, /* 1 */
{ OP_MemStore, 1, 1, 0}, { OP_MemStore, 1, 1, 0},
{ OP_MemLoad, 1, 0, 0}, /* 3 */ { OP_MemLoad, 1, 0, 0}, /* 3 */
{ OP_Column, 0, 2, 0}, { OP_Column, 0, 2, 0}, /* sqlite_master.tbl_name */
{ OP_Ne, 0, ADDR(9), 0}, { 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_Delete, 0, 0, 0},
{ OP_Rewind, 0, ADDR(10), 0}, { OP_Rewind, 0, ADDR(13), 0},
{ OP_Goto, 0, ADDR(3), 0}, { OP_Goto, 0, ADDR(3), 0},
{ OP_Next, 0, ADDR(3), 0}, /* 9 */ { OP_Next, 0, ADDR(3), 0}, /* 12 */
}; };
Index *pIdx; Index *pIdx;
Trigger *pTrigger; Trigger *pTrigger;
sqlite3BeginWriteOperation(pParse, 0, pTab->iDb); 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; pTrigger = pTab->pTrigger;
while( pTrigger ){ while( pTrigger ){
assert( pTrigger->iDb==pTab->iDb || pTrigger->iDb==1 ); 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); sqlite3OpenMasterTable(v, pTab->iDb);
base = sqlite3VdbeAddOpList(v, ArraySize(dropTable), dropTable); base = sqlite3VdbeAddOpList(v, ArraySize(dropTable), dropTable);
sqlite3VdbeChangeP3(v, base+1, pTab->zName, 0); 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); sqlite3VdbeAddOp(v, OP_Close, 0, 0);
if( !isView ){ if( !isView ){
sqlite3VdbeAddOp(v, OP_Destroy, pTab->tnum, pTab->iDb); sqlite3VdbeAddOp(v, OP_Destroy, pTab->tnum, pTab->iDb);
@@ -2262,7 +2258,7 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
Vdbe *v = sqlite3GetVdbe(pParse); Vdbe *v = sqlite3GetVdbe(pParse);
if( v==0 ) return; if( v==0 ) return;
sqlite3VdbeAddOp(v, OP_Transaction, iDb, 1); 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); sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, db->aDb[iDb].schema_cookie);
pParse->cookieMask |= ((u64)1<<iDb); pParse->cookieMask |= ((u64)1<<iDb);
} }

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be ** other files are for internal use by SQLite and should not be
** accessed by users of the library. ** 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 "sqliteInt.h"
#include "os.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. ** error occurs, write an error message into *pzErrMsg.
** **
** After the database is initialized, the SQLITE_Initialized ** After the database is initialized, the SQLITE_Initialized
** bit is set in the flags field of the sqlite structure. An ** bit is set in the flags field of the sqlite structure.
** 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.
*/ */
int sqlite3Init(sqlite *db, char **pzErrMsg){ int sqlite3Init(sqlite *db, char **pzErrMsg){
int i, rc; int i, rc;
@@ -382,6 +378,28 @@ int sqlite3Init(sqlite *db, char **pzErrMsg){
return rc; 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 ** The version of the library
*/ */
@@ -845,21 +863,6 @@ int sqlite3_prepare(
goto prepare_out; 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; } if( db->pVdbe==0 ){ db->nChange = 0; }
memset(&sParse, 0, sizeof(sParse)); memset(&sParse, 0, sizeof(sParse));
sParse.db = db; sParse.db = db;
@@ -974,27 +977,12 @@ int sqlite3_prepare16(
*/ */
static int openDatabase( static int openDatabase(
const char *zFilename, /* Database filename UTF-8 encoded */ const char *zFilename, /* Database filename UTF-8 encoded */
sqlite3 **ppDb, /* OUT: Returned database handle */ 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 *db; sqlite3 *db;
int rc, i; int rc, i;
char *zErrMsg = 0; 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 */ /* Allocate the sqlite data structure */
db = sqliteMalloc( sizeof(sqlite) ); db = sqliteMalloc( sizeof(sqlite) );
if( db==0 ) goto opendb_out; if( db==0 ) goto opendb_out;
@@ -1002,7 +990,7 @@ static int openDatabase(
db->magic = SQLITE_MAGIC_BUSY; db->magic = SQLITE_MAGIC_BUSY;
db->nDb = 2; db->nDb = 2;
db->aDb = db->aDbStatic; db->aDb = db->aDbStatic;
db->enc = def_enc; db->enc = TEXT_Utf8;
db->autoCommit = 1; db->autoCommit = 1;
/* db->flags |= SQLITE_ShortColNames; */ /* db->flags |= SQLITE_ShortColNames; */
sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
@@ -1030,20 +1018,18 @@ static int openDatabase(
db->aDb[0].zName = "main"; db->aDb[0].zName = "main";
db->aDb[1].zName = "temp"; 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); sqlite3RegisterBuiltinFunctions(db);
rc = sqlite3Init(db, &zErrMsg); if( rc==SQLITE_OK ){
if( sqlite3_malloc_failed ){
sqlite3_close(db);
db = 0;
goto opendb_out;
}else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
sqlite3Error(db, rc, "%s", zErrMsg, 0);
db->magic = SQLITE_MAGIC_CLOSED;
}else{
db->magic = SQLITE_MAGIC_OPEN; db->magic = SQLITE_MAGIC_OPEN;
} }else{
sqlite3Error(db, rc, "%s", zErrMsg, 0);
if( zErrMsg ) sqliteFree(zErrMsg); if( zErrMsg ) sqliteFree(zErrMsg);
db->magic = SQLITE_MAGIC_CLOSED;
}
opendb_out: opendb_out:
*ppDb = db; *ppDb = db;
@@ -1058,7 +1044,7 @@ int sqlite3_open(
sqlite3 **ppDb, sqlite3 **ppDb,
const char **options const char **options
){ ){
return openDatabase(zFilename, ppDb, options, TEXT_Utf8); return openDatabase(zFilename, ppDb);
} }
/* /*
@@ -1079,16 +1065,12 @@ int sqlite3_open16(
*ppDb = 0; *ppDb = 0;
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
rc = openDatabase(zFilename8, ppDb);
/* FIX ME: Also need to translate the option strings */ if( rc==SQLITE_OK && *ppDb ){
sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
if( SQLITE_BIGENDIAN ){
rc = openDatabase(zFilename8, ppDb, options, TEXT_Utf16be);
}else{
rc = openDatabase(zFilename8, ppDb, options, TEXT_Utf16le);
} }
sqliteFree(zFilename8); sqliteFree(zFilename8);
return rc; return rc;
} }

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** This file contains code used to implement the PRAGMA command. ** 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 "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -203,6 +203,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
{ OP_Callback, 1, 0, 0}, { OP_Callback, 1, 0, 0},
}; };
int addr; int addr;
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
if( pRight->z==pLeft->z ){ if( pRight->z==pLeft->z ){
sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC); sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
@@ -242,6 +243,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
static VdbeOpList getCacheSize[] = { static VdbeOpList getCacheSize[] = {
{ OP_Callback, 1, 0, 0}, { OP_Callback, 1, 0, 0},
}; };
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
if( pRight->z==pLeft->z ){ if( pRight->z==pLeft->z ){
int size = db->cache_size;; int size = db->cache_size;;
if( size<0 ) size = -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} { OP_Callback, 1, 0, 0}
}; };
int addr; int addr;
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
if( pRight->z==pLeft->z ){ if( pRight->z==pLeft->z ){
sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC); sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
@@ -335,6 +338,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
static VdbeOpList getSync[] = { static VdbeOpList getSync[] = {
{ OP_Callback, 1, 0, 0}, { OP_Callback, 1, 0, 0},
}; };
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
if( pRight->z==pLeft->z ){ if( pRight->z==pLeft->z ){
sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC); 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 ){ if( sqlite3StrICmp(zLeft, "table_info")==0 ){
Table *pTab; Table *pTab;
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
pTab = sqlite3FindTable(db, zRight, 0); pTab = sqlite3FindTable(db, zRight, 0);
if( pTab ){ if( pTab ){
int i; int i;
@@ -395,6 +400,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
if( sqlite3StrICmp(zLeft, "index_info")==0 ){ if( sqlite3StrICmp(zLeft, "index_info")==0 ){
Index *pIdx; Index *pIdx;
Table *pTab; Table *pTab;
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
pIdx = sqlite3FindIndex(db, zRight, 0); pIdx = sqlite3FindIndex(db, zRight, 0);
if( pIdx ){ if( pIdx ){
int i; int i;
@@ -417,6 +423,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
if( sqlite3StrICmp(zLeft, "index_list")==0 ){ if( sqlite3StrICmp(zLeft, "index_list")==0 ){
Index *pIdx; Index *pIdx;
Table *pTab; Table *pTab;
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
pTab = sqlite3FindTable(db, zRight, 0); pTab = sqlite3FindTable(db, zRight, 0);
if( pTab ){ if( pTab ){
v = sqlite3GetVdbe(pParse); v = sqlite3GetVdbe(pParse);
@@ -442,6 +449,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 ){ if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 ){
FKey *pFK; FKey *pFK;
Table *pTab; Table *pTab;
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
pTab = sqlite3FindTable(db, zRight, 0); pTab = sqlite3FindTable(db, zRight, 0);
if( pTab ){ if( pTab ){
v = sqlite3GetVdbe(pParse); v = sqlite3GetVdbe(pParse);
@@ -474,6 +482,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
if( sqlite3StrICmp(zLeft, "database_list")==0 ){ if( sqlite3StrICmp(zLeft, "database_list")==0 ){
int i; int i;
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
sqlite3VdbeSetNumCols(v, 3); sqlite3VdbeSetNumCols(v, 3);
sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC); sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
sqlite3VdbeSetColName(v, 1, "name", 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[] = { static VdbeOpList getTmpDbLoc[] = {
{ OP_Callback, 1, 0, 0}, { OP_Callback, 1, 0, 0},
}; };
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
if( pRight->z==pLeft->z ){ if( pRight->z==pLeft->z ){
sqlite3VdbeAddOp(v, OP_Integer, db->temp_store, 0); sqlite3VdbeAddOp(v, OP_Integer, db->temp_store, 0);
sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetNumCols(v, 1);
@@ -530,6 +540,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
static VdbeOpList getTmpDbLoc[] = { static VdbeOpList getTmpDbLoc[] = {
{ OP_ReadCookie, 0, 5, 0}, { OP_ReadCookie, 0, 5, 0},
{ OP_Callback, 1, 0, 0}}; { OP_Callback, 1, 0, 0}};
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
if( pRight->z==pLeft->z ){ if( pRight->z==pLeft->z ){
sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, "temp_store", P3_STATIC); sqlite3VdbeSetColName(v, 0, "temp_store", P3_STATIC);
@@ -545,6 +556,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
#ifndef NDEBUG #ifndef NDEBUG
if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
extern void sqlite3ParserTrace(FILE*, char *); extern void sqlite3ParserTrace(FILE*, char *);
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
if( getBoolean(zRight) ){ if( getBoolean(zRight) ){
sqlite3ParserTrace(stdout, "parser: "); sqlite3ParserTrace(stdout, "parser: ");
}else{ }else{
@@ -577,6 +589,7 @@ void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
}; };
/* Initialize the VDBE program */ /* Initialize the VDBE program */
if( SQLITE_OK!=sqlite3ReadSchema(pParse->db) ) return;
sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC); sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode); 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); addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode)); sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
}else }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); sqliteFree(zLeft);

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** 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 "config.h"
#include "sqlite3.h" #include "sqlite3.h"
@@ -1374,3 +1374,4 @@ void *sqlite3HexToBlob(const char *z);
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
const char *sqlite3ErrStr(int); const char *sqlite3ErrStr(int);
int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold); int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold);
int sqlite3ReadSchema(sqlite *db);

View File

@@ -421,6 +421,8 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
sqlite *db = pParse->db; sqlite *db = pParse->db;
if( sqlite3_malloc_failed ) goto drop_trigger_cleanup; if( sqlite3_malloc_failed ) goto drop_trigger_cleanup;
if( SQLITE_OK!=sqlite3ReadSchema(db) ) goto drop_trigger_cleanup;
assert( pName->nSrc==1 ); assert( pName->nSrc==1 );
zDb = pName->a[0].zDatabase; zDb = pName->a[0].zDatabase;
zName = pName->a[0].zName; 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. /* 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; int base;
static VdbeOpList dropTrigger[] = { static VdbeOpList dropTrigger[] = {
{ OP_Rewind, 0, ADDR(9), 0}, { OP_Rewind, 0, ADDR(9), 0},
@@ -488,15 +490,12 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
sqlite3OpenMasterTable(v, pTrigger->iDb); sqlite3OpenMasterTable(v, pTrigger->iDb);
base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger); base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0); 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); 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 ){ if( !pParse->explain ){
const char *zName = pTrigger->name; const char *zName = pTrigger->name;

View File

@@ -12,7 +12,7 @@
# focus of this script is testing the ATTACH and DETACH commands # focus of this script is testing the ATTACH and DETACH commands
# and schema changes to attached databases. # 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 finish_test

View File

@@ -13,7 +13,7 @@
# various suported unicode encodings (UTF-8, UTF-16, UTF-16le and # various suported unicode encodings (UTF-8, UTF-16, UTF-16le and
# UTF-16be). # 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] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -45,7 +45,7 @@ set dbcontents {
# database, and that it is possible to retreive values in # database, and that it is possible to retreive values in
# various text encodings. # various text encodings.
# #
proc run_test_script {t} { proc run_test_script {t enc} {
# Open the database and pull out a (the) row. # Open the database and pull out a (the) row.
do_test $t.1 { do_test $t.1 {
@@ -102,22 +102,23 @@ do_test $t.9 {
sqlite3_finalize $STMT sqlite3_finalize $STMT
} SQLITE_OK } SQLITE_OK
do_test $t.99 { do_test $t.10 {
db close db eval {PRAGMA encoding}
} {} } $enc
} }
# The three unicode encodings understood by SQLite. # 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 set i 1
foreach enc $encodings { foreach enc $encodings {
file delete -force test.db file delete -force test.db
sqlite db test.db $enc sqlite db test.db $enc
db eval "PRAGMA encoding = \"$enc\""
execsql $dbcontents execsql $dbcontents
db close db close
run_test_script enc2-$i run_test_script enc2-$i $enc
incr i incr i
} }