blob: 3d094d3854248f1d73c1df466e2ed4767b231854 [file] [log] [blame]
drhc11d4f92003-04-06 21:08:24 +00001/*
2** 2003 April 6
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11*************************************************************************
12** This file contains code used to implement the PRAGMA command.
13**
drhb6c29892004-11-22 19:12:19 +000014** $Id: pragma.c,v 1.79 2004/11/22 19:12:21 drh Exp $
drhc11d4f92003-04-06 21:08:24 +000015*/
16#include "sqliteInt.h"
drh13bff812003-04-15 01:19:47 +000017#include <ctype.h>
drhc11d4f92003-04-06 21:08:24 +000018
drh13d70422004-11-13 15:59:14 +000019/* Ignore this whole file if pragmas are disabled
20*/
21#ifndef SQLITE_OMIT_PRAGMA
22
dougcurrie81c95ef2004-06-18 23:21:47 +000023#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
drh89ac8c12004-06-09 14:17:20 +000024# include "pager.h"
25# include "btree.h"
26#endif
27
drhc11d4f92003-04-06 21:08:24 +000028/*
drhc11d4f92003-04-06 21:08:24 +000029** Interpret the given string as a safety level. Return 0 for OFF,
jplyonb1639ff2004-01-19 04:52:29 +000030** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
31** unrecognized string argument.
drhc11d4f92003-04-06 21:08:24 +000032**
33** Note that the values returned are one less that the values that
danielk19774adee202004-05-08 08:23:19 +000034** should be passed into sqlite3BtreeSetSafetyLevel(). The is done
drhc11d4f92003-04-06 21:08:24 +000035** to support legacy SQL code. The safety level used to be boolean
36** and older scripts may have used numbers 0 for OFF and 1 for ON.
37*/
drh722e95a2004-10-25 20:33:44 +000038static int getSafetyLevel(const u8 *z){
39 /* 123456789 123456789 */
40 static const char zText[] = "onoffalseyestruefull";
41 static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
42 static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
43 static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2};
44 int i, n;
45 if( isdigit(*z) ){
drhc11d4f92003-04-06 21:08:24 +000046 return atoi(z);
47 }
drh722e95a2004-10-25 20:33:44 +000048 n = strlen(z);
49 for(i=0; i<sizeof(iLength); i++){
50 if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
51 return iValue[i];
52 }
drhc11d4f92003-04-06 21:08:24 +000053 }
54 return 1;
55}
56
57/*
drh722e95a2004-10-25 20:33:44 +000058** Interpret the given string as a boolean value.
59*/
60static int getBoolean(const u8 *z){
61 return getSafetyLevel(z)&1;
62}
63
64/*
drh90f5ecb2004-07-22 01:19:35 +000065** Interpret the given string as a temp db location. Return 1 for file
66** backed temporary databases, 2 for the Red-Black tree in memory database
67** and 0 to use the compile-time default.
68*/
69static int getTempStore(const char *z){
70 if( z[0]>='0' && z[0]<='2' ){
71 return z[0] - '0';
72 }else if( sqlite3StrICmp(z, "file")==0 ){
73 return 1;
74 }else if( sqlite3StrICmp(z, "memory")==0 ){
75 return 2;
76 }else{
77 return 0;
78 }
79}
80
81/*
82** If the TEMP database is open, close it and mark the database schema
83** as needing reloading. This must be done when using the TEMP_STORE
84** or DEFAULT_TEMP_STORE pragmas.
85*/
86static int changeTempStorage(Parse *pParse, const char *zStorageType){
87 int ts = getTempStore(zStorageType);
drh9bb575f2004-09-06 17:24:11 +000088 sqlite3 *db = pParse->db;
drh90f5ecb2004-07-22 01:19:35 +000089 if( db->temp_store==ts ) return SQLITE_OK;
90 if( db->aDb[1].pBt!=0 ){
91 if( db->flags & SQLITE_InTrans ){
92 sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
93 "from within a transaction");
94 return SQLITE_ERROR;
95 }
96 sqlite3BtreeClose(db->aDb[1].pBt);
97 db->aDb[1].pBt = 0;
98 sqlite3ResetInternalSchema(db, 0);
99 }
100 db->temp_store = ts;
101 return SQLITE_OK;
102}
103
104/*
105** Generate code to return a single integer value.
106*/
drh5bb7ffe2004-09-02 15:14:00 +0000107static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
108 Vdbe *v = sqlite3GetVdbe(pParse);
drh90f5ecb2004-07-22 01:19:35 +0000109 sqlite3VdbeAddOp(v, OP_Integer, value, 0);
drh5bb7ffe2004-09-02 15:14:00 +0000110 if( pParse->explain==0 ){
111 sqlite3VdbeSetNumCols(v, 1);
112 sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
113 }
drh90f5ecb2004-07-22 01:19:35 +0000114 sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
115}
116
117/*
drh87223182004-02-21 14:00:29 +0000118** Check to see if zRight and zLeft refer to a pragma that queries
119** or changes one of the flags in db->flags. Return 1 if so and 0 if not.
120** Also, implement the pragma.
121*/
122static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
drh722e95a2004-10-25 20:33:44 +0000123 static const struct sPragmaType {
drh87223182004-02-21 14:00:29 +0000124 const char *zName; /* Name of the pragma */
125 int mask; /* Mask for the db->flags value */
126 } aPragma[] = {
127 { "vdbe_trace", SQLITE_VdbeTrace },
drh35d4c2f2004-06-10 01:30:59 +0000128 { "sql_trace", SQLITE_SqlTrace },
129 { "vdbe_listing", SQLITE_VdbeListing },
drh87223182004-02-21 14:00:29 +0000130 { "full_column_names", SQLITE_FullColNames },
131 { "short_column_names", SQLITE_ShortColNames },
drh87223182004-02-21 14:00:29 +0000132 { "count_changes", SQLITE_CountRows },
133 { "empty_result_callbacks", SQLITE_NullCallback },
drh722e95a2004-10-25 20:33:44 +0000134 /* The following is VERY experimental */
drhf4040832004-10-22 20:29:21 +0000135 { "writable_schema", SQLITE_WriteSchema },
drh87223182004-02-21 14:00:29 +0000136 };
137 int i;
drh722e95a2004-10-25 20:33:44 +0000138 const struct sPragmaType *p;
139 for(i=0, p=aPragma; i<sizeof(aPragma)/sizeof(aPragma[0]); i++, p++){
140 if( sqlite3StrICmp(zLeft, p->zName)==0 ){
drh9bb575f2004-09-06 17:24:11 +0000141 sqlite3 *db = pParse->db;
drh87223182004-02-21 14:00:29 +0000142 Vdbe *v;
drh5260f7e2004-06-26 19:35:29 +0000143 if( zRight==0 ){
144 v = sqlite3GetVdbe(pParse);
145 if( v ){
drh722e95a2004-10-25 20:33:44 +0000146 returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
drh5260f7e2004-06-26 19:35:29 +0000147 }
drh87223182004-02-21 14:00:29 +0000148 }else if( getBoolean(zRight) ){
drh722e95a2004-10-25 20:33:44 +0000149 db->flags |= p->mask;
drh87223182004-02-21 14:00:29 +0000150 }else{
drh722e95a2004-10-25 20:33:44 +0000151 db->flags &= ~p->mask;
drh87223182004-02-21 14:00:29 +0000152 }
153 return 1;
154 }
155 }
156 return 0;
157}
158
159/*
drhc11d4f92003-04-06 21:08:24 +0000160** Process a pragma statement.
161**
162** Pragmas are of this form:
163**
danielk197791cf71b2004-06-26 06:37:06 +0000164** PRAGMA [database.]id [= value]
drhc11d4f92003-04-06 21:08:24 +0000165**
166** The identifier might also be a string. The value is a string, and
167** identifier, or a number. If minusFlag is true, then the value is
168** a number that was preceded by a minus sign.
drh90f5ecb2004-07-22 01:19:35 +0000169**
170** If the left side is "database.id" then pId1 is the database name
171** and pId2 is the id. If the left side is just "id" then pId1 is the
172** id and pId2 is any empty string.
drhc11d4f92003-04-06 21:08:24 +0000173*/
danielk197791cf71b2004-06-26 06:37:06 +0000174void sqlite3Pragma(
175 Parse *pParse,
176 Token *pId1, /* First part of [database.]id field */
177 Token *pId2, /* Second part of [database.]id field, or NULL */
178 Token *pValue, /* Token for <value>, or NULL */
179 int minusFlag /* True if a '-' sign preceded <value> */
180){
181 char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */
182 char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */
183 const char *zDb = 0; /* The database name */
184 Token *pId; /* Pointer to <id> token */
185 int iDb; /* Database index for <database> */
drh9bb575f2004-09-06 17:24:11 +0000186 sqlite3 *db = pParse->db;
drh90f5ecb2004-07-22 01:19:35 +0000187 Db *pDb;
danielk19774adee202004-05-08 08:23:19 +0000188 Vdbe *v = sqlite3GetVdbe(pParse);
drhc11d4f92003-04-06 21:08:24 +0000189 if( v==0 ) return;
190
danielk197791cf71b2004-06-26 06:37:06 +0000191 /* Interpret the [database.] part of the pragma statement. iDb is the
192 ** index of the database this pragma is being applied to in db.aDb[]. */
193 iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
194 if( iDb<0 ) return;
drh90f5ecb2004-07-22 01:19:35 +0000195 pDb = &db->aDb[iDb];
danielk197791cf71b2004-06-26 06:37:06 +0000196
197 zLeft = sqlite3NameFromToken(pId);
danielk197796fb0dd2004-06-30 09:49:22 +0000198 if( !zLeft ) return;
drhc11d4f92003-04-06 21:08:24 +0000199 if( minusFlag ){
drhae29ffb2004-09-25 14:39:18 +0000200 zRight = sqlite3MPrintf("-%T", pValue);
drhc11d4f92003-04-06 21:08:24 +0000201 }else{
danielk197791cf71b2004-06-26 06:37:06 +0000202 zRight = sqlite3NameFromToken(pValue);
drhc11d4f92003-04-06 21:08:24 +0000203 }
danielk197791cf71b2004-06-26 06:37:06 +0000204
drh90f5ecb2004-07-22 01:19:35 +0000205 zDb = ((iDb>0)?pDb->zName:0);
danielk197791cf71b2004-06-26 06:37:06 +0000206 if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
danielk1977e0048402004-06-15 16:51:01 +0000207 goto pragma_out;
drhc11d4f92003-04-06 21:08:24 +0000208 }
209
drh13d70422004-11-13 15:59:14 +0000210#ifndef SQLITE_OMIT_PAGER_PRAGMAS
drhc11d4f92003-04-06 21:08:24 +0000211 /*
drh90f5ecb2004-07-22 01:19:35 +0000212 ** PRAGMA [database.]default_cache_size
213 ** PRAGMA [database.]default_cache_size=N
drhc11d4f92003-04-06 21:08:24 +0000214 **
215 ** The first form reports the current persistent setting for the
216 ** page cache size. The value returned is the maximum number of
217 ** pages in the page cache. The second form sets both the current
218 ** page cache size value and the persistent page cache size value
219 ** stored in the database file.
220 **
221 ** The default cache size is stored in meta-value 2 of page 1 of the
222 ** database file. The cache size is actually the absolute value of
223 ** this memory location. The sign of meta-value 2 determines the
224 ** synchronous setting. A negative value means synchronous is off
225 ** and a positive value means synchronous is on.
226 */
danielk19774adee202004-05-08 08:23:19 +0000227 if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
drh57196282004-10-06 15:41:16 +0000228 static const VdbeOpList getCacheSize[] = {
danielk197791cf71b2004-06-26 06:37:06 +0000229 { OP_ReadCookie, 0, 2, 0}, /* 0 */
drhc11d4f92003-04-06 21:08:24 +0000230 { OP_AbsValue, 0, 0, 0},
231 { OP_Dup, 0, 0, 0},
232 { OP_Integer, 0, 0, 0},
233 { OP_Ne, 0, 6, 0},
drh905793e2004-02-21 13:31:09 +0000234 { OP_Integer, 0, 0, 0}, /* 5 */
drhc11d4f92003-04-06 21:08:24 +0000235 { OP_Callback, 1, 0, 0},
236 };
drh905793e2004-02-21 13:31:09 +0000237 int addr;
danielk19778a414492004-06-29 08:59:35 +0000238 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
danielk197791cf71b2004-06-26 06:37:06 +0000239 if( !zRight ){
danielk197722322fd2004-05-25 23:35:17 +0000240 sqlite3VdbeSetNumCols(v, 1);
danielk19773cf86062004-05-26 10:11:05 +0000241 sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
danielk19774adee202004-05-08 08:23:19 +0000242 addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
danielk197791cf71b2004-06-26 06:37:06 +0000243 sqlite3VdbeChangeP1(v, addr, iDb);
danielk19774adee202004-05-08 08:23:19 +0000244 sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
drhc11d4f92003-04-06 21:08:24 +0000245 }else{
drhc11d4f92003-04-06 21:08:24 +0000246 int size = atoi(zRight);
247 if( size<0 ) size = -size;
danielk197791cf71b2004-06-26 06:37:06 +0000248 sqlite3BeginWriteOperation(pParse, 0, iDb);
danielk19774adee202004-05-08 08:23:19 +0000249 sqlite3VdbeAddOp(v, OP_Integer, size, 0);
danielk197791cf71b2004-06-26 06:37:06 +0000250 sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2);
danielk19774adee202004-05-08 08:23:19 +0000251 addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
252 sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
253 sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
danielk197791cf71b2004-06-26 06:37:06 +0000254 sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
drh90f5ecb2004-07-22 01:19:35 +0000255 pDb->cache_size = size;
256 sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
drhc11d4f92003-04-06 21:08:24 +0000257 }
258 }else
259
260 /*
drh90f5ecb2004-07-22 01:19:35 +0000261 ** PRAGMA [database.]page_size
262 ** PRAGMA [database.]page_size=N
263 **
264 ** The first form reports the current setting for the
265 ** database page size in bytes. The second form sets the
266 ** database page size value. The value can only be set if
267 ** the database has not yet been created.
268 */
269 if( sqlite3StrICmp(zLeft,"page_size")==0 ){
270 Btree *pBt = pDb->pBt;
271 if( !zRight ){
272 int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0;
drh5bb7ffe2004-09-02 15:14:00 +0000273 returnSingleInt(pParse, "page_size", size);
drh90f5ecb2004-07-22 01:19:35 +0000274 }else{
drhd900a462004-09-17 20:25:24 +0000275 sqlite3BtreeSetPageSize(pBt, atoi(zRight), sqlite3BtreeGetReserve(pBt));
drh90f5ecb2004-07-22 01:19:35 +0000276 }
277 }else
drh13d70422004-11-13 15:59:14 +0000278#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
drh90f5ecb2004-07-22 01:19:35 +0000279
280 /*
danielk1977951af802004-11-05 15:45:09 +0000281 ** PRAGMA [database.]auto_vacuum
282 ** PRAGMA [database.]auto_vacuum=N
283 **
284 ** Get or set the (boolean) value of the database 'auto-vacuum' parameter.
285 */
286#ifndef SQLITE_OMIT_AUTOVACUUM
287 if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){
288 Btree *pBt = pDb->pBt;
289 if( !zRight ){
290 int auto_vacuum =
291 pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM;
292 returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
293 }else{
294 sqlite3BtreeSetAutoVacuum(pBt, getBoolean(zRight));
295 }
296 }else
297#endif
298
drh13d70422004-11-13 15:59:14 +0000299#ifndef SQLITE_OMIT_PAGER_PRAGMAS
danielk1977951af802004-11-05 15:45:09 +0000300 /*
drh90f5ecb2004-07-22 01:19:35 +0000301 ** PRAGMA [database.]cache_size
302 ** PRAGMA [database.]cache_size=N
drhc11d4f92003-04-06 21:08:24 +0000303 **
304 ** The first form reports the current local setting for the
305 ** page cache size. The local setting can be different from
306 ** the persistent cache size value that is stored in the database
307 ** file itself. The value returned is the maximum number of
308 ** pages in the page cache. The second form sets the local
309 ** page cache size value. It does not change the persistent
310 ** cache size stored on the disk so the cache size will revert
311 ** to its default value when the database is closed and reopened.
312 ** N should be a positive integer.
313 */
danielk19774adee202004-05-08 08:23:19 +0000314 if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
danielk19778a414492004-06-29 08:59:35 +0000315 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
danielk197791cf71b2004-06-26 06:37:06 +0000316 if( !zRight ){
drh5bb7ffe2004-09-02 15:14:00 +0000317 returnSingleInt(pParse, "cache_size", pDb->cache_size);
drhc11d4f92003-04-06 21:08:24 +0000318 }else{
319 int size = atoi(zRight);
320 if( size<0 ) size = -size;
drh90f5ecb2004-07-22 01:19:35 +0000321 pDb->cache_size = size;
322 sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
drhc11d4f92003-04-06 21:08:24 +0000323 }
324 }else
325
326 /*
drh90f5ecb2004-07-22 01:19:35 +0000327 ** PRAGMA temp_store
328 ** PRAGMA temp_store = "default"|"memory"|"file"
329 **
330 ** Return or set the local value of the temp_store flag. Changing
331 ** the local value does not make changes to the disk file and the default
332 ** value will be restored the next time the database is opened.
333 **
334 ** Note that it is possible for the library compile-time options to
335 ** override this setting
336 */
337 if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
338 if( !zRight ){
drh5bb7ffe2004-09-02 15:14:00 +0000339 returnSingleInt(pParse, "temp_store", db->temp_store);
drh90f5ecb2004-07-22 01:19:35 +0000340 }else{
341 changeTempStorage(pParse, zRight);
342 }
343 }else
344
345 /*
346 ** PRAGMA [database.]synchronous
347 ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
drhc11d4f92003-04-06 21:08:24 +0000348 **
349 ** Return or set the local value of the synchronous flag. Changing
350 ** the local value does not make changes to the disk file and the
351 ** default value will be restored the next time the database is
352 ** opened.
353 */
danielk19774adee202004-05-08 08:23:19 +0000354 if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
danielk19778a414492004-06-29 08:59:35 +0000355 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
danielk197791cf71b2004-06-26 06:37:06 +0000356 if( !zRight ){
drh5bb7ffe2004-09-02 15:14:00 +0000357 returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
drhc11d4f92003-04-06 21:08:24 +0000358 }else{
danielk197791cf71b2004-06-26 06:37:06 +0000359 if( !db->autoCommit ){
360 sqlite3ErrorMsg(pParse,
361 "Safety level may not be changed inside a transaction");
362 }else{
drh90f5ecb2004-07-22 01:19:35 +0000363 pDb->safety_level = getSafetyLevel(zRight)+1;
364 sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level);
danielk197791cf71b2004-06-26 06:37:06 +0000365 }
drhc11d4f92003-04-06 21:08:24 +0000366 }
367 }else
drh13d70422004-11-13 15:59:14 +0000368#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
drhc11d4f92003-04-06 21:08:24 +0000369
drh87223182004-02-21 14:00:29 +0000370 if( flagPragma(pParse, zLeft, zRight) ){
drh90f5ecb2004-07-22 01:19:35 +0000371 /* The flagPragma() subroutine also generates any necessary code
372 ** there is nothing more to do here */
drhc11d4f92003-04-06 21:08:24 +0000373 }else
374
drh13d70422004-11-13 15:59:14 +0000375#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
danielk197791cf71b2004-06-26 06:37:06 +0000376 /*
377 ** PRAGMA table_info(<table>)
378 **
379 ** Return a single row for each column of the named table. The columns of
380 ** the returned data set are:
381 **
382 ** cid: Column id (numbered from left to right, starting at 0)
383 ** name: Column name
384 ** type: Column declaration type.
385 ** notnull: True if 'NOT NULL' is part of column declaration
386 ** dflt_value: The default value for the column, if any.
387 */
drh5260f7e2004-06-26 19:35:29 +0000388 if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
drhc11d4f92003-04-06 21:08:24 +0000389 Table *pTab;
danielk19778a414492004-06-29 08:59:35 +0000390 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
drh2783e4b2004-10-05 15:42:53 +0000391 pTab = sqlite3FindTable(db, zRight, zDb);
drhc11d4f92003-04-06 21:08:24 +0000392 if( pTab ){
drhc11d4f92003-04-06 21:08:24 +0000393 int i;
danielk197722322fd2004-05-25 23:35:17 +0000394 sqlite3VdbeSetNumCols(v, 6);
danielk19773cf86062004-05-26 10:11:05 +0000395 sqlite3VdbeSetColName(v, 0, "cid", P3_STATIC);
396 sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
397 sqlite3VdbeSetColName(v, 2, "type", P3_STATIC);
398 sqlite3VdbeSetColName(v, 3, "notnull", P3_STATIC);
399 sqlite3VdbeSetColName(v, 4, "dflt_value", P3_STATIC);
400 sqlite3VdbeSetColName(v, 5, "pk", P3_STATIC);
danielk19774adee202004-05-08 08:23:19 +0000401 sqlite3ViewGetColumnNames(pParse, pTab);
drhc11d4f92003-04-06 21:08:24 +0000402 for(i=0; i<pTab->nCol; i++){
danielk19774adee202004-05-08 08:23:19 +0000403 sqlite3VdbeAddOp(v, OP_Integer, i, 0);
danielk19770f69c1e2004-05-29 11:24:50 +0000404 sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zName, 0);
405 sqlite3VdbeOp3(v, OP_String8, 0, 0,
drh701a0ae2004-02-22 20:05:00 +0000406 pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
danielk19774adee202004-05-08 08:23:19 +0000407 sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
danielk19777977a172004-11-09 12:44:37 +0000408 sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
danielk19774adee202004-05-08 08:23:19 +0000409 sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
410 sqlite3VdbeAddOp(v, OP_Callback, 6, 0);
drhc11d4f92003-04-06 21:08:24 +0000411 }
412 }
413 }else
414
drh5260f7e2004-06-26 19:35:29 +0000415 if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){
drhc11d4f92003-04-06 21:08:24 +0000416 Index *pIdx;
417 Table *pTab;
danielk19778a414492004-06-29 08:59:35 +0000418 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
drh2783e4b2004-10-05 15:42:53 +0000419 pIdx = sqlite3FindIndex(db, zRight, zDb);
drhc11d4f92003-04-06 21:08:24 +0000420 if( pIdx ){
drhc11d4f92003-04-06 21:08:24 +0000421 int i;
422 pTab = pIdx->pTable;
danielk197722322fd2004-05-25 23:35:17 +0000423 sqlite3VdbeSetNumCols(v, 3);
danielk19773cf86062004-05-26 10:11:05 +0000424 sqlite3VdbeSetColName(v, 0, "seqno", P3_STATIC);
425 sqlite3VdbeSetColName(v, 1, "cid", P3_STATIC);
426 sqlite3VdbeSetColName(v, 2, "name", P3_STATIC);
drhc11d4f92003-04-06 21:08:24 +0000427 for(i=0; i<pIdx->nColumn; i++){
428 int cnum = pIdx->aiColumn[i];
danielk19774adee202004-05-08 08:23:19 +0000429 sqlite3VdbeAddOp(v, OP_Integer, i, 0);
430 sqlite3VdbeAddOp(v, OP_Integer, cnum, 0);
drhc11d4f92003-04-06 21:08:24 +0000431 assert( pTab->nCol>cnum );
danielk19770f69c1e2004-05-29 11:24:50 +0000432 sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[cnum].zName, 0);
danielk19774adee202004-05-08 08:23:19 +0000433 sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
drhc11d4f92003-04-06 21:08:24 +0000434 }
435 }
436 }else
437
drh5260f7e2004-06-26 19:35:29 +0000438 if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){
drhc11d4f92003-04-06 21:08:24 +0000439 Index *pIdx;
440 Table *pTab;
danielk19778a414492004-06-29 08:59:35 +0000441 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
drh2783e4b2004-10-05 15:42:53 +0000442 pTab = sqlite3FindTable(db, zRight, zDb);
drhc11d4f92003-04-06 21:08:24 +0000443 if( pTab ){
danielk19774adee202004-05-08 08:23:19 +0000444 v = sqlite3GetVdbe(pParse);
drhc11d4f92003-04-06 21:08:24 +0000445 pIdx = pTab->pIndex;
danielk1977742f9472004-06-16 12:02:43 +0000446 if( pIdx ){
447 int i = 0;
448 sqlite3VdbeSetNumCols(v, 3);
449 sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
450 sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
451 sqlite3VdbeSetColName(v, 2, "unique", P3_STATIC);
452 while(pIdx){
453 sqlite3VdbeAddOp(v, OP_Integer, i, 0);
454 sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
455 sqlite3VdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
456 sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
457 ++i;
458 pIdx = pIdx->pNext;
459 }
drhc11d4f92003-04-06 21:08:24 +0000460 }
461 }
462 }else
463
drh13d70422004-11-13 15:59:14 +0000464 if( sqlite3StrICmp(zLeft, "database_list")==0 ){
465 int i;
466 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
467 sqlite3VdbeSetNumCols(v, 3);
468 sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
469 sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
470 sqlite3VdbeSetColName(v, 2, "file", P3_STATIC);
471 for(i=0; i<db->nDb; i++){
472 if( db->aDb[i].pBt==0 ) continue;
473 assert( db->aDb[i].zName!=0 );
474 sqlite3VdbeAddOp(v, OP_Integer, i, 0);
475 sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0);
476 sqlite3VdbeOp3(v, OP_String8, 0, 0,
477 sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
478 sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
479 }
480 }else
drhb6c29892004-11-22 19:12:19 +0000481
482#ifndef SQLITE_OMIT_CURSOR
483 if( sqlite3StrICmp(zLeft, "cursor_list")==0 ){
484 int i;
485 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
486 sqlite3VdbeSetNumCols(v, 2);
487 sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
488 sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
489 for(i=0; i<db->nSqlCursor; i++){
490 SqlCursor *p = db->apSqlCursor[i];
491 if( p==0 ) continue;
492 assert( p->zName!=0 );
493 sqlite3VdbeAddOp(v, OP_Integer, i, 0);
494 sqlite3VdbeOp3(v, OP_String8, 0, 0, p->zName, 0);
495 sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
496 }
497 }else
498#endif /* SQLITE_OMIT_CURSOR */
drh13d70422004-11-13 15:59:14 +0000499#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
500
drhb7f91642004-10-31 02:22:47 +0000501#ifndef SQLITE_OMIT_FOREIGN_KEY
drh5260f7e2004-06-26 19:35:29 +0000502 if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
drh78100cc2003-08-23 22:40:53 +0000503 FKey *pFK;
504 Table *pTab;
danielk19778a414492004-06-29 08:59:35 +0000505 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
drh2783e4b2004-10-05 15:42:53 +0000506 pTab = sqlite3FindTable(db, zRight, zDb);
drh78100cc2003-08-23 22:40:53 +0000507 if( pTab ){
danielk19774adee202004-05-08 08:23:19 +0000508 v = sqlite3GetVdbe(pParse);
drh78100cc2003-08-23 22:40:53 +0000509 pFK = pTab->pFKey;
danielk1977742f9472004-06-16 12:02:43 +0000510 if( pFK ){
511 int i = 0;
512 sqlite3VdbeSetNumCols(v, 5);
513 sqlite3VdbeSetColName(v, 0, "id", P3_STATIC);
514 sqlite3VdbeSetColName(v, 1, "seq", P3_STATIC);
515 sqlite3VdbeSetColName(v, 2, "table", P3_STATIC);
516 sqlite3VdbeSetColName(v, 3, "from", P3_STATIC);
517 sqlite3VdbeSetColName(v, 4, "to", P3_STATIC);
518 while(pFK){
519 int j;
520 for(j=0; j<pFK->nCol; j++){
521 sqlite3VdbeAddOp(v, OP_Integer, i, 0);
522 sqlite3VdbeAddOp(v, OP_Integer, j, 0);
523 sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->zTo, 0);
524 sqlite3VdbeOp3(v, OP_String8, 0, 0,
525 pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
526 sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->aCol[j].zCol, 0);
527 sqlite3VdbeAddOp(v, OP_Callback, 5, 0);
528 }
529 ++i;
530 pFK = pFK->pNextFrom;
drh78100cc2003-08-23 22:40:53 +0000531 }
drh78100cc2003-08-23 22:40:53 +0000532 }
533 }
534 }else
drhb7f91642004-10-31 02:22:47 +0000535#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
drh78100cc2003-08-23 22:40:53 +0000536
drhc11d4f92003-04-06 21:08:24 +0000537#ifndef NDEBUG
danielk19774adee202004-05-08 08:23:19 +0000538 if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
539 extern void sqlite3ParserTrace(FILE*, char *);
drhc11d4f92003-04-06 21:08:24 +0000540 if( getBoolean(zRight) ){
danielk19774adee202004-05-08 08:23:19 +0000541 sqlite3ParserTrace(stdout, "parser: ");
drhc11d4f92003-04-06 21:08:24 +0000542 }else{
danielk19774adee202004-05-08 08:23:19 +0000543 sqlite3ParserTrace(0, 0);
drhc11d4f92003-04-06 21:08:24 +0000544 }
545 }else
546#endif
547
drhb7f91642004-10-31 02:22:47 +0000548#ifndef SQLITE_OMIT_INTEGRITY_CHECK
danielk19774adee202004-05-08 08:23:19 +0000549 if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){
drhed717fe2003-06-15 23:42:24 +0000550 int i, j, addr;
551
552 /* Code that initializes the integrity check program. Set the
drh4be295b2003-12-16 03:44:47 +0000553 ** error count 0
drhed717fe2003-06-15 23:42:24 +0000554 */
drh57196282004-10-06 15:41:16 +0000555 static const VdbeOpList initCode[] = {
drh4be295b2003-12-16 03:44:47 +0000556 { OP_Integer, 0, 0, 0},
drhed717fe2003-06-15 23:42:24 +0000557 { OP_MemStore, 0, 1, 0},
drhed717fe2003-06-15 23:42:24 +0000558 };
559
drhed717fe2003-06-15 23:42:24 +0000560 /* Code that appears at the end of the integrity check. If no error
561 ** messages have been generated, output OK. Otherwise output the
562 ** error message
563 */
drh57196282004-10-06 15:41:16 +0000564 static const VdbeOpList endCode[] = {
drhed717fe2003-06-15 23:42:24 +0000565 { OP_MemLoad, 0, 0, 0},
drh4be295b2003-12-16 03:44:47 +0000566 { OP_Integer, 0, 0, 0},
567 { OP_Ne, 0, 0, 0}, /* 2 */
drh290c1942004-08-21 17:54:45 +0000568 { OP_String8, 0, 0, "ok"},
drhc11d4f92003-04-06 21:08:24 +0000569 { OP_Callback, 1, 0, 0},
570 };
drhed717fe2003-06-15 23:42:24 +0000571
572 /* Initialize the VDBE program */
danielk19778a414492004-06-29 08:59:35 +0000573 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
danielk197722322fd2004-05-25 23:35:17 +0000574 sqlite3VdbeSetNumCols(v, 1);
danielk19773cf86062004-05-26 10:11:05 +0000575 sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
danielk19774adee202004-05-08 08:23:19 +0000576 sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode);
drhed717fe2003-06-15 23:42:24 +0000577
578 /* Do an integrity check on each database file */
579 for(i=0; i<db->nDb; i++){
580 HashElem *x;
drh79069752004-05-22 21:30:40 +0000581 int cnt = 0;
drhed717fe2003-06-15 23:42:24 +0000582
drh80242052004-06-09 00:48:12 +0000583 sqlite3CodeVerifySchema(pParse, i);
584
drhed717fe2003-06-15 23:42:24 +0000585 /* Do an integrity check of the B-Tree
586 */
drh79069752004-05-22 21:30:40 +0000587 for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
588 Table *pTab = sqliteHashData(x);
589 Index *pIdx;
590 sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0);
591 cnt++;
592 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
danielk1977e0048402004-06-15 16:51:01 +0000593 if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto pragma_out;
drh79069752004-05-22 21:30:40 +0000594 sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
595 cnt++;
596 }
597 }
danielk19772b444852004-06-29 07:45:33 +0000598 assert( cnt>0 );
drh79069752004-05-22 21:30:40 +0000599 sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);
600 sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
danielk19770f69c1e2004-05-29 11:24:50 +0000601 addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
drh79069752004-05-22 21:30:40 +0000602 sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
danielk19770f69c1e2004-05-29 11:24:50 +0000603 sqlite3VdbeOp3(v, OP_String8, 0, 0,
drh79069752004-05-22 21:30:40 +0000604 sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
605 P3_DYNAMIC);
606 sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
drh855eb1c2004-08-31 13:45:11 +0000607 sqlite3VdbeAddOp(v, OP_Concat, 0, 1);
drh79069752004-05-22 21:30:40 +0000608 sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
drhed717fe2003-06-15 23:42:24 +0000609
610 /* Make sure all the indices are constructed correctly.
611 */
danielk19774adee202004-05-08 08:23:19 +0000612 sqlite3CodeVerifySchema(pParse, i);
drhed717fe2003-06-15 23:42:24 +0000613 for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
614 Table *pTab = sqliteHashData(x);
615 Index *pIdx;
616 int loopTop;
617
618 if( pTab->pIndex==0 ) continue;
drh290c1942004-08-21 17:54:45 +0000619 sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
danielk19774adee202004-05-08 08:23:19 +0000620 sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
621 sqlite3VdbeAddOp(v, OP_MemStore, 1, 1);
622 loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);
623 sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);
drhed717fe2003-06-15 23:42:24 +0000624 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
danielk197713adf8a2004-06-03 16:08:41 +0000625 int jmp2;
drh57196282004-10-06 15:41:16 +0000626 static const VdbeOpList idxErr[] = {
drh4be295b2003-12-16 03:44:47 +0000627 { OP_MemIncr, 0, 0, 0},
drh290c1942004-08-21 17:54:45 +0000628 { OP_String8, 0, 0, "rowid "},
drhed717fe2003-06-15 23:42:24 +0000629 { OP_Recno, 1, 0, 0},
drh290c1942004-08-21 17:54:45 +0000630 { OP_String8, 0, 0, " missing from index "},
631 { OP_String8, 0, 0, 0}, /* 4 */
drh855eb1c2004-08-31 13:45:11 +0000632 { OP_Concat, 2, 0, 0},
drh4be295b2003-12-16 03:44:47 +0000633 { OP_Callback, 1, 0, 0},
drhed717fe2003-06-15 23:42:24 +0000634 };
drh51846b52004-05-28 16:00:21 +0000635 sqlite3GenerateIndexKey(v, pIdx, 1);
danielk19774adee202004-05-08 08:23:19 +0000636 jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
637 addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
638 sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
639 sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));
drhed717fe2003-06-15 23:42:24 +0000640 }
danielk19774adee202004-05-08 08:23:19 +0000641 sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
642 sqlite3VdbeChangeP2(v, loopTop, sqlite3VdbeCurrentAddr(v));
drhed717fe2003-06-15 23:42:24 +0000643 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
drh57196282004-10-06 15:41:16 +0000644 static const VdbeOpList cntIdx[] = {
drhed717fe2003-06-15 23:42:24 +0000645 { OP_Integer, 0, 0, 0},
646 { OP_MemStore, 2, 1, 0},
647 { OP_Rewind, 0, 0, 0}, /* 2 */
648 { OP_MemIncr, 2, 0, 0},
649 { OP_Next, 0, 0, 0}, /* 4 */
650 { OP_MemLoad, 1, 0, 0},
651 { OP_MemLoad, 2, 0, 0},
652 { OP_Eq, 0, 0, 0}, /* 7 */
drh4be295b2003-12-16 03:44:47 +0000653 { OP_MemIncr, 0, 0, 0},
drh290c1942004-08-21 17:54:45 +0000654 { OP_String8, 0, 0, "wrong # of entries in index "},
655 { OP_String8, 0, 0, 0}, /* 10 */
drh855eb1c2004-08-31 13:45:11 +0000656 { OP_Concat, 0, 0, 0},
drh4be295b2003-12-16 03:44:47 +0000657 { OP_Callback, 1, 0, 0},
drhed717fe2003-06-15 23:42:24 +0000658 };
659 if( pIdx->tnum==0 ) continue;
danielk19774adee202004-05-08 08:23:19 +0000660 addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
661 sqlite3VdbeChangeP1(v, addr+2, j+2);
662 sqlite3VdbeChangeP2(v, addr+2, addr+5);
663 sqlite3VdbeChangeP1(v, addr+4, j+2);
664 sqlite3VdbeChangeP2(v, addr+4, addr+3);
665 sqlite3VdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
666 sqlite3VdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
drhed717fe2003-06-15 23:42:24 +0000667 }
668 }
669 }
danielk19774adee202004-05-08 08:23:19 +0000670 addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
671 sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
drhc11d4f92003-04-06 21:08:24 +0000672 }else
drhb7f91642004-10-31 02:22:47 +0000673#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
674
drh13d70422004-11-13 15:59:14 +0000675#ifndef SQLITE_OMIT_UTF16
danielk19778e227872004-06-07 07:52:17 +0000676 /*
677 ** PRAGMA encoding
678 ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
679 **
680 ** In it's first form, this pragma returns the encoding of the main
681 ** database. If the database is not initialized, it is initialized now.
682 **
683 ** The second form of this pragma is a no-op if the main database file
684 ** has not already been initialized. In this case it sets the default
685 ** encoding that will be used for the main database file if a new file
686 ** is created. If an existing main database file is opened, then the
687 ** default text encoding for the existing database is used.
688 **
689 ** In all cases new databases created using the ATTACH command are
690 ** created to use the same default text encoding as the main database. If
691 ** the main database has not been initialized and/or created when ATTACH
692 ** is executed, this is done before the ATTACH operation.
693 **
694 ** In the second form this pragma sets the text encoding to be used in
695 ** new database files created using this database handle. It is only
696 ** useful if invoked immediately after the main database i
697 */
698 if( sqlite3StrICmp(zLeft, "encoding")==0 ){
drh57196282004-10-06 15:41:16 +0000699 static struct EncName {
danielk19778e227872004-06-07 07:52:17 +0000700 char *zName;
701 u8 enc;
702 } encnames[] = {
drh998da3a2004-06-19 15:22:56 +0000703 { "UTF-8", SQLITE_UTF8 },
704 { "UTF8", SQLITE_UTF8 },
705 { "UTF-16le", SQLITE_UTF16LE },
706 { "UTF16le", SQLITE_UTF16LE },
707 { "UTF-16be", SQLITE_UTF16BE },
708 { "UTF16be", SQLITE_UTF16BE },
709 { "UTF-16", 0 /* Filled in at run-time */ },
710 { "UTF16", 0 /* Filled in at run-time */ },
danielk19778e227872004-06-07 07:52:17 +0000711 { 0, 0 }
712 };
713 struct EncName *pEnc;
drh998da3a2004-06-19 15:22:56 +0000714 encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;
danielk197791cf71b2004-06-26 06:37:06 +0000715 if( !zRight ){ /* "PRAGMA encoding" */
danielk19778a414492004-06-29 08:59:35 +0000716 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
danielk19778e227872004-06-07 07:52:17 +0000717 sqlite3VdbeSetNumCols(v, 1);
718 sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
719 sqlite3VdbeAddOp(v, OP_String8, 0, 0);
720 for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
721 if( pEnc->enc==pParse->db->enc ){
722 sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);
723 break;
724 }
725 }
726 sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
727 }else{ /* "PRAGMA encoding = XXX" */
728 /* Only change the value of sqlite.enc if the database handle is not
729 ** initialized. If the main database exists, the new sqlite.enc value
730 ** will be overwritten when the schema is next loaded. If it does not
731 ** already exists, it will be created to use the new encoding value.
732 */
733 if( !(pParse->db->flags&SQLITE_Initialized) ){
734 for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
735 if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
736 pParse->db->enc = pEnc->enc;
737 break;
738 }
739 }
740 if( !pEnc->zName ){
drh5260f7e2004-06-26 19:35:29 +0000741 sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
danielk19778e227872004-06-07 07:52:17 +0000742 }
743 }
744 }
745 }else
drh13d70422004-11-13 15:59:14 +0000746#endif /* SQLITE_OMIT_UTF16 */
747
748#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
danielk1977dae24952004-11-11 05:10:43 +0000749 /*
danielk1977b92b70b2004-11-12 16:11:59 +0000750 ** PRAGMA [database.]schema_version
751 ** PRAGMA [database.]schema_version = <integer>
danielk1977dae24952004-11-11 05:10:43 +0000752 **
danielk1977b92b70b2004-11-12 16:11:59 +0000753 ** PRAGMA [database.]user_version
754 ** PRAGMA [database.]user_version = <integer>
danielk1977dae24952004-11-11 05:10:43 +0000755 **
danielk1977b92b70b2004-11-12 16:11:59 +0000756 ** The pragma's schema_version and user_version are used to set or get
757 ** the value of the schema-version and user-version, respectively. Both
758 ** the schema-version and the user-version are 32-bit signed integers
danielk1977dae24952004-11-11 05:10:43 +0000759 ** stored in the database header.
760 **
761 ** The schema-cookie is usually only manipulated internally by SQLite. It
762 ** is incremented by SQLite whenever the database schema is modified (by
danielk1977b92b70b2004-11-12 16:11:59 +0000763 ** creating or dropping a table or index). The schema version is used by
danielk1977dae24952004-11-11 05:10:43 +0000764 ** SQLite each time a query is executed to ensure that the internal cache
765 ** of the schema used when compiling the SQL query matches the schema of
766 ** the database against which the compiled query is actually executed.
danielk1977b92b70b2004-11-12 16:11:59 +0000767 ** Subverting this mechanism by using "PRAGMA schema_version" to modify
768 ** the schema-version is potentially dangerous and may lead to program
danielk1977dae24952004-11-11 05:10:43 +0000769 ** crashes or database corruption. Use with caution!
770 **
danielk1977b92b70b2004-11-12 16:11:59 +0000771 ** The user-version is not used internally by SQLite. It may be used by
danielk1977dae24952004-11-11 05:10:43 +0000772 ** applications for any purpose.
773 */
danielk1977b92b70b2004-11-12 16:11:59 +0000774 if( sqlite3StrICmp(zLeft, "schema_version")==0 ||
775 sqlite3StrICmp(zLeft, "user_version")==0 ){
danielk1977dae24952004-11-11 05:10:43 +0000776
777 int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */
778 if( zLeft[0]=='s' || zLeft[0]=='S' ){
779 iCookie = 0;
780 }else{
781 iCookie = 5;
782 }
783
784 if( zRight ){
785 /* Write the specified cookie value */
786 static const VdbeOpList setCookie[] = {
787 { OP_Transaction, 0, 1, 0}, /* 0 */
788 { OP_Integer, 0, 0, 0}, /* 1 */
789 { OP_SetCookie, 0, 0, 0}, /* 2 */
790 };
791 int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);
792 sqlite3VdbeChangeP1(v, addr, iDb);
793 sqlite3VdbeChangeP1(v, addr+1, atoi(zRight));
794 sqlite3VdbeChangeP1(v, addr+2, iDb);
795 sqlite3VdbeChangeP2(v, addr+2, iCookie);
796 }else{
797 /* Read the specified cookie value */
798 static const VdbeOpList readCookie[] = {
799 { OP_ReadCookie, 0, 0, 0}, /* 0 */
800 { OP_Callback, 1, 0, 0}
801 };
802 int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
803 sqlite3VdbeChangeP1(v, addr, iDb);
804 sqlite3VdbeChangeP2(v, addr, iCookie);
805 sqlite3VdbeSetNumCols(v, 1);
806 }
807 }
drh13d70422004-11-13 15:59:14 +0000808#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
drhc11d4f92003-04-06 21:08:24 +0000809
dougcurrie81c95ef2004-06-18 23:21:47 +0000810#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
drh89ac8c12004-06-09 14:17:20 +0000811 /*
812 ** Report the current state of file logs for all databases
813 */
814 if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
drh57196282004-10-06 15:41:16 +0000815 static const char *const azLockName[] = {
drh89ac8c12004-06-09 14:17:20 +0000816 "unlocked", "shared", "reserved", "pending", "exclusive"
817 };
818 int i;
819 Vdbe *v = sqlite3GetVdbe(pParse);
820 sqlite3VdbeSetNumCols(v, 2);
821 sqlite3VdbeSetColName(v, 0, "database", P3_STATIC);
822 sqlite3VdbeSetColName(v, 1, "status", P3_STATIC);
823 for(i=0; i<db->nDb; i++){
824 Btree *pBt;
825 Pager *pPager;
826 if( db->aDb[i].zName==0 ) continue;
827 sqlite3VdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, P3_STATIC);
828 pBt = db->aDb[i].pBt;
829 if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
830 sqlite3VdbeOp3(v, OP_String, 0, 0, "closed", P3_STATIC);
831 }else{
832 int j = sqlite3pager_lockstate(pPager);
833 sqlite3VdbeOp3(v, OP_String, 0, 0,
834 (j>=0 && j<=4) ? azLockName[j] : "unknown", P3_STATIC);
835 }
836 sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
837 }
838 }else
839#endif
840
drhc11d4f92003-04-06 21:08:24 +0000841 {}
danielk1977e0048402004-06-15 16:51:01 +0000842pragma_out:
drhc11d4f92003-04-06 21:08:24 +0000843 sqliteFree(zLeft);
844 sqliteFree(zRight);
845}
drh13d70422004-11-13 15:59:14 +0000846
847#endif /* SQLITE_OMIT_PRAGMA */