Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Remove default_synchronous and temp_store pragmas. Allow the safety-level and cache-size to be set for attached databases. (CVS 1735) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
212de3ce66f746036cb2267a9f924fd5 |
User & Date: | danielk1977 2004-06-26 06:37:06.000 |
Original Comment: | Remove default_synchronous and temp_store pragmas. Allow the safety-level and cache-size to be set for attached databases. (CVS 1735) |
Original User & Date: | danielk1977 2004-06-26 06:37:07.000 |
Context
2004-06-26
| ||
06:37 | Remove default_synchronous and temp_store pragmas. Allow the safety-level and cache-size to be set for attached databases. (CVS 1736) (check-in: 76da457b8f user: danielk1977 tags: trunk) | |
06:37 | Remove default_synchronous and temp_store pragmas. Allow the safety-level and cache-size to be set for attached databases. (CVS 1735) (check-in: 212de3ce66 user: danielk1977 tags: trunk) | |
01:48 | Fix a bug in the new full-sync journal format. (CVS 1733) (check-in: 02bd3acd7e user: danielk1977 tags: trunk) | |
Changes
Changes to src/attach.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** ** $Id: attach.c,v 1.18 2004/06/26 06:37:07 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** This routine is called by the parser to process an ATTACH statement: ** ** ATTACH DATABASE filename AS dbname |
︙ | ︙ | |||
80 81 82 83 84 85 86 87 88 89 90 91 92 93 | aNew = &db->aDb[db->nDb++]; memset(aNew, 0, sizeof(*aNew)); sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1); aNew->zName = zName; rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt); if( rc ){ sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile); } #if SQLITE_HAS_CODEC { extern int sqliteCodecAttach(sqlite*, int, void*, int); | > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | aNew = &db->aDb[db->nDb++]; memset(aNew, 0, sizeof(*aNew)); sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0); 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); } #if SQLITE_HAS_CODEC { extern int sqliteCodecAttach(sqlite*, int, void*, int); |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.234 2004/06/26 06:37:07 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** A pointer to this structure is used to communicate information |
︙ | ︙ | |||
214 215 216 217 218 219 220 | /* Get the database meta information. ** ** Meta values are as follows: ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. | | | | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | /* Get the database meta information. ** ** Meta values are as follows: ** 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] ** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE ** meta[5] ** meta[6] ** meta[7] ** meta[8] ** meta[9] ** ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to ** the possible values of meta[4]. |
︙ | ︙ | |||
261 262 263 264 265 266 267 | sqlite3SetString(pzErrMsg, "attached databases must use the same" " text encoding as main database", (char*)0); return SQLITE_ERROR; } } } | < | | | < < < | < | | < | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | sqlite3SetString(pzErrMsg, "attached databases must use the same" " text encoding as main database", (char*)0); return SQLITE_ERROR; } } } 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 */ db->file_format = 1; } } /* ** file_format==1 Version 3.0.0. */ if( meta[1]>1 ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0); return SQLITE_ERROR; } sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size); /* Read the schema information out of the schema tables */ assert( db->init.busy ); if( rc==SQLITE_EMPTY ){ /* For an empty database, there is nothing to read */ rc = SQLITE_OK; |
︙ | ︙ | |||
803 804 805 806 807 808 809 | ** This routine is called to create a connection to a database BTree ** driver. If zFilename is the name of a file, then that file is ** opened and used. If zFilename is the magic name ":memory:" then ** the database is stored in memory (and is thus forgotten as soon as ** 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. | < < < < < < < < < < < < < < < < | > > > | 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 | ** This routine is called to create a connection to a database BTree ** driver. If zFilename is the name of a file, then that file is ** opened and used. If zFilename is the magic name ":memory:" then ** the database is stored in memory (and is thus forgotten as soon as ** 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. */ int sqlite3BtreeFactory( const sqlite *db, /* Main database when opening aux otherwise 0 */ const char *zFilename, /* Name of the file containing the BTree database */ int omitJournal, /* if TRUE then do not journal this file */ int nCache, /* How many pages in the page cache */ Btree **ppBtree /* Pointer to new Btree object written here */ ){ int btree_flags = 0; assert( ppBtree != 0); if( omitJournal ){ btree_flags |= BTREE_OMIT_JOURNAL; } 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; } return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags, (void *)&db->busyHandler); } |
︙ | ︙ | |||
1123 1124 1125 1126 1127 1128 1129 | goto opendb_out; } /* Also add a UTF-8 case-insensitive collation sequence. */ sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc); /* Open the backend database driver */ | < < < < < < > > > > > | 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 | goto opendb_out; } /* Also add a UTF-8 case-insensitive collation sequence. */ sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc); /* Open the backend database driver */ rc = sqlite3BtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt); if( rc!=SQLITE_OK ){ sqlite3Error(db, rc, 0); db->magic = SQLITE_MAGIC_CLOSED; goto opendb_out; } 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. */ sqlite3RegisterBuiltinFunctions(db); if( rc==SQLITE_OK ){ |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** ** @(#) $Id: parse.y,v 1.128 2004/06/26 06:37:07 danielk1977 Exp $ */ %token_prefix TK_ %token_type {Token} %default_type {Token} %extra_argument {Parse *pParse} %syntax_error { if( pParse->zErrMsg==0 ){ |
︙ | ︙ | |||
778 779 780 781 782 783 784 | ///////////////////////////// The VACUUM command ///////////////////////////// // cmd ::= VACUUM. {sqlite3Vacuum(pParse,0);} cmd ::= VACUUM nm(X). {sqlite3Vacuum(pParse,&X);} ///////////////////////////// The PRAGMA command ///////////////////////////// // | | | | > | > | | | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | ///////////////////////////// The VACUUM command ///////////////////////////// // cmd ::= VACUUM. {sqlite3Vacuum(pParse,0);} cmd ::= VACUUM nm(X). {sqlite3Vacuum(pParse,&X);} ///////////////////////////// The PRAGMA command ///////////////////////////// // 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;} number(A) ::= FLOAT(X). {A = X;} plus_opt ::= PLUS. plus_opt ::= . |
︙ | ︙ |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.53 2004/06/26 06:37:07 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) # include "pager.h" # include "btree.h" |
︙ | ︙ | |||
67 68 69 70 71 72 73 | } for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){ if( sqlite3StrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val; } return 1; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | } for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){ if( sqlite3StrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val; } return 1; } /* ** 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. ** Also, implement the pragma. */ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ static const struct { |
︙ | ︙ | |||
153 154 155 156 157 158 159 | } /* ** Process a pragma statement. ** ** Pragmas are of this form: ** | | | > > > > > > | | > > > > > > > > | | | > > | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | } /* ** Process a pragma statement. ** ** Pragmas are of this form: ** ** 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 *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; /* 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, pValue->z, pValue->n, 0); }else{ zRight = sqlite3NameFromToken(pValue); } zDb = ((iDb>0)?db->aDb[iDb].zName:0); if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ goto pragma_out; } /* ** PRAGMA default_cache_size ** PRAGMA default_cache_size=N ** |
︙ | ︙ | |||
195 196 197 198 199 200 201 | ** database file. The cache size is actually the absolute value of ** this memory location. The sign of meta-value 2 determines the ** synchronous setting. A negative value means synchronous is off ** and a positive value means synchronous is on. */ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ static VdbeOpList getCacheSize[] = { | | | > | | | | | | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | ** database file. The cache size is actually the absolute value of ** this memory location. The sign of meta-value 2 determines the ** synchronous setting. A negative value means synchronous is off ** and a positive value means synchronous is on. */ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ static VdbeOpList getCacheSize[] = { { OP_ReadCookie, 0, 2, 0}, /* 0 */ { OP_AbsValue, 0, 0, 0}, { OP_Dup, 0, 0, 0}, { OP_Integer, 0, 0, 0}, { OP_Ne, 0, 6, 0}, { OP_Integer, 0, 0, 0}, /* 5 */ { OP_Callback, 1, 0, 0}, }; int addr; if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ pParse->nErr++; goto pragma_out; } 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, iDb); sqlite3VdbeAddOp(v, OP_Integer, size, 0); 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, iDb, 2); sqlite3EndWriteOperation(pParse); db->aDb[iDb].cache_size = size; sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size); } }else /* ** PRAGMA cache_size ** PRAGMA cache_size=N ** |
︙ | ︙ | |||
251 252 253 254 255 256 257 | static VdbeOpList getCacheSize[] = { { OP_Callback, 1, 0, 0}, }; if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ pParse->nErr++; goto pragma_out; } | | | | < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | > > | < < < | > > > > > > > > > > > > > | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | static VdbeOpList getCacheSize[] = { { OP_Callback, 1, 0, 0}, }; if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ pParse->nErr++; goto pragma_out; } 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); sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); }else{ int size = atoi(zRight); if( size<0 ) size = -size; db->aDb[iDb].cache_size = size; sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size); } }else /* ** PRAGMA synchronous ** PRAGMA synchronous=OFF|ON|NORMAL|FULL ** ** Return or set the local value of the synchronous 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. */ if( sqlite3StrICmp(zLeft,"synchronous")==0 ){ static VdbeOpList getSync[] = { { OP_Callback, 1, 0, 0}, }; if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ pParse->nErr++; goto pragma_out; } if( !zRight ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC); sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].safety_level-1, 0); sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync); }else{ 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 #ifndef NDEBUG if( sqlite3StrICmp(zLeft, "trigger_overhead_test")==0 ){ if( getBoolean(zRight) ){ sqlite3_always_code_trigger_setup = 1; }else{ sqlite3_always_code_trigger_setup = 0; } }else #endif if( flagPragma(pParse, zLeft, zRight) ){ /* 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) ){ pParse->nErr++; goto pragma_out; } pTab = sqlite3FindTable(db, zRight, 0); |
︙ | ︙ | |||
524 525 526 527 528 529 530 | assert( db->aDb[i].zName!=0 ); sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); sqlite3VdbeAddOp(v, OP_Callback, 3, 0); } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | assert( db->aDb[i].zName!=0 ); sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); sqlite3VdbeAddOp(v, OP_Callback, 3, 0); } }else #ifndef NDEBUG if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ extern void sqlite3ParserTrace(FILE*, char *); if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ pParse->nErr++; |
︙ | ︙ | |||
775 776 777 778 779 780 781 | { "UTF16be", SQLITE_UTF16BE }, { "UTF-16", 0 /* Filled in at run-time */ }, { "UTF16", 0 /* Filled in at run-time */ }, { 0, 0 } }; struct EncName *pEnc; encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE; | | | 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 | { "UTF16be", SQLITE_UTF16BE }, { "UTF-16", 0 /* Filled in at run-time */ }, { "UTF16", 0 /* Filled in at run-time */ }, { 0, 0 } }; struct EncName *pEnc; encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE; if( !zRight ){ /* "PRAGMA encoding" */ if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){ pParse->nErr++; goto pragma_out; } sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC); sqlite3VdbeAddOp(v, OP_String8, 0, 0); |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.300 2004/06/26 06:37:07 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ #include "config.h" #include "sqlite3.h" #include "hash.h" |
︙ | ︙ | |||
63 64 65 66 67 68 69 | ** in order to support the main database file (0) and the file used to ** hold temporary tables (1). And it must be less than 32 because ** we use a bitmask of databases with a u32 in places (for example ** the Parse.cookieMask field). */ #define MAX_ATTACHED 10 | < < < < < < < < < < < < < | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | ** in order to support the main database file (0) and the file used to ** hold temporary tables (1). And it must be less than 32 because ** we use a bitmask of databases with a u32 in places (for example ** the Parse.cookieMask field). */ #define MAX_ATTACHED 10 /* ** When building SQLite for embedded systems where memory is scarce, ** you can define one or more of the following macros to omit extra ** features of the library and thus keep the size of the library to ** a minimum. */ /* #define SQLITE_OMIT_AUTHORIZATION 1 */ |
︙ | ︙ | |||
286 287 288 289 290 291 292 293 294 295 296 297 298 299 | int schema_cookie; /* Database schema version number for this file */ Hash tblHash; /* All tables indexed by name */ Hash idxHash; /* All (named) indices indexed by name */ Hash trigHash; /* All triggers indexed by name */ Hash aFKey; /* Foreign keys indexed by to-table */ u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */ u16 flags; /* Flags associated with this database */ void *pAux; /* Auxiliary data. Usually NULL */ void (*xFreeAux)(void*); /* Routine to free pAux */ }; /* ** These macros can be used to test, set, or clear bits in the ** Db.flags field. | > > | 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | int schema_cookie; /* Database schema version number for this file */ Hash tblHash; /* All tables indexed by name */ Hash idxHash; /* All (named) indices indexed by name */ Hash trigHash; /* All triggers indexed by name */ 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 */ }; /* ** These macros can be used to test, set, or clear bits in the ** Db.flags field. |
︙ | ︙ | |||
331 332 333 334 335 336 337 | int (*xFunc)(void *,int); /* The busy callback */ void *pArg; /* First arg to busy callback */ }; /* ** Each database is an instance of the following structure. ** | < < < < < | 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | int (*xFunc)(void *,int); /* The busy callback */ void *pArg; /* First arg to busy callback */ }; /* ** Each database is an instance of the following structure. ** ** 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 ** triggers as usual. The previous value will be restored once the trigger ** exits. Upon entering a before or instead of trigger, lastRowid is no ** longer (since after version 2.8.12) reset to -1. ** |
︙ | ︙ | |||
365 366 367 368 369 370 371 | */ struct sqlite { int nDb; /* Number of backends currently in use */ Db *aDb; /* All backends */ 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? */ | < < < | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 | */ struct sqlite { int nDb; /* Number of backends currently in use */ Db *aDb; /* All backends */ 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? */ int nTable; /* Number of tables in the database */ BusyHandler busyHandler; /* Busy callback */ void *pCommitArg; /* Argument to xCommitCallback() */ int (*xCommitCallback)(void*);/* Invoked at every commit. */ Hash aFunc; /* All functions that can be in SQL exprs */ Hash aCollSeq; /* All collating sequences */ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ |
︙ | ︙ | |||
1221 1222 1223 1224 1225 1226 1227 | Expr *sqlite3Expr(int, Expr*, Expr*, Token*); void sqlite3ExprSpan(Expr*,Token*,Token*); Expr *sqlite3ExprFunction(ExprList*, Token*); void sqlite3ExprDelete(Expr*); ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*); void sqlite3ExprListDelete(ExprList*); int sqlite3Init(sqlite*, char**); | | | 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 | Expr *sqlite3Expr(int, Expr*, Expr*, Token*); void sqlite3ExprSpan(Expr*,Token*,Token*); Expr *sqlite3ExprFunction(ExprList*, Token*); void sqlite3ExprDelete(Expr*); ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*); void sqlite3ExprListDelete(ExprList*); int sqlite3Init(sqlite*, char**); void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); void sqlite3ResetInternalSchema(sqlite*, int); void sqlite3BeginParse(Parse*,int); void sqlite3RollbackInternalChanges(sqlite*); void sqlite3CommitInternalChanges(sqlite*); Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*); void sqlite3OpenMasterTable(Vdbe *v, int); void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int); |
︙ | ︙ |
Changes to test/pragma.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for the PRAGMA command. # | | > > > > > > > > > > < | < | < | < | < | < | < | < < < < < < < < < > > > > > > > | > | > > > > > > > > > > > > > > > > < | > > | > > < < < | < | | | < < < | < | < < < < < < < < < | < | | < < | | | | | < < < < > | | | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for the PRAGMA command. # # $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. # db close file delete test.db set DB [sqlite3 db test.db] do_test pragma-1.1 { execsql { PRAGMA cache_size; PRAGMA default_cache_size; PRAGMA synchronous; } } {2000 2000 2} do_test pragma-1.2 { execsql { PRAGMA cache_size=1234; PRAGMA cache_size; PRAGMA default_cache_size; PRAGMA synchronous; } } {1234 2000 2} do_test pragma-1.3 { db close sqlite3 db test.db execsql { PRAGMA cache_size; PRAGMA default_cache_size; PRAGMA synchronous; } } {2000 2000 2} do_test pragma-1.4 { execsql { PRAGMA synchronous=OFF; PRAGMA cache_size; PRAGMA default_cache_size; PRAGMA synchronous; } } {2000 2000 0} do_test pragma-1.5 { execsql { PRAGMA cache_size=4321; PRAGMA cache_size; PRAGMA default_cache_size; PRAGMA synchronous; } } {4321 2000 0} do_test pragma-1.6 { execsql { PRAGMA synchronous=ON; PRAGMA cache_size; PRAGMA default_cache_size; PRAGMA synchronous; } } {4321 2000 1} do_test pragma-1.7 { db close sqlite3 db test.db execsql { PRAGMA cache_size; PRAGMA default_cache_size; PRAGMA synchronous; } } {2000 2000 2} do_test pragma-1.8 { execsql { PRAGMA default_cache_size=123; PRAGMA cache_size; PRAGMA default_cache_size; PRAGMA synchronous; } } {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; } } {123 123 2} do_test pragma-1.10 { execsql { PRAGMA synchronous=NORMAL; PRAGMA cache_size; PRAGMA default_cache_size; PRAGMA synchronous; } } {123 123 1} do_test pragma-1.11 { execsql { PRAGMA synchronous=FULL; PRAGMA cache_size; PRAGMA default_cache_size; PRAGMA synchronous; } } {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; } } {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 { ATTACH 'test2.db' AS aux; } } {} do_test pragma-2.2 { execsql { 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. # if {![sqlite3 -has-codec]} { do_test pragma-3.1 { execsql { |
︙ | ︙ | |||
188 189 190 191 192 193 194 | btree_delete $c btree_commit $db btree_close $db execsql {PRAGMA integrity_check} } {{rowid 1 missing from index i2} {wrong # of entries in index i2}} }; # endif has-codec | | > > > > | > > > > > > > > > | < | | < > | > | | < | > | | < > > > | | | < < | < < | < < < < | < | | | < < < < | < < < < < < < > | < < < < < | < < < | < < < | < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | | > | > | > > | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | btree_delete $c btree_commit $db btree_close $db execsql {PRAGMA integrity_check} } {{rowid 1 missing from index i2} {wrong # of entries in index i2}} }; # endif has-codec 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 aux.cache_size = 50; pragma aux.cache_size; pragma aux.default_cache_size; } } {50 2000} do_test pragma-4.3 { execsql { pragma aux.default_cache_size = 456; pragma aux.cache_size; pragma aux.default_cache_size; } } {456 456} do_test pragma-4.4 { execsql { pragma cache_size; pragma default_cache_size; } } {123 123} do_test pragma-4.5 { execsql { DETACH aux; ATTACH 'test3.db' AS aux; pragma aux.cache_size; pragma aux.default_cache_size; } } {2000 2000} do_test pragma-4.6 { execsql { DETACH aux; ATTACH 'test2.db' AS aux; pragma aux.cache_size; pragma aux.default_cache_size; } } {456 456} # Test that modifying the sync-level in the middle of a transaction is # disallowed. do_test pragma-5.0 { execsql { pragma synchronous; } } {2} do_test pragma-5.1 { catchsql { BEGIN; pragma synchronous = OFF; } } {1 {Safety level may not be changed inside a transaction}} do_test pragma-5.2 { execsql { pragma synchronous; } } {2} finish_test |