1*c5c4113dSnw141292
2*c5c4113dSnw141292 #pragma ident "%Z%%M% %I% %E% SMI"
3*c5c4113dSnw141292
4*c5c4113dSnw141292 /*
5*c5c4113dSnw141292 ** 2003 April 6
6*c5c4113dSnw141292 **
7*c5c4113dSnw141292 ** The author disclaims copyright to this source code. In place of
8*c5c4113dSnw141292 ** a legal notice, here is a blessing:
9*c5c4113dSnw141292 **
10*c5c4113dSnw141292 ** May you do good and not evil.
11*c5c4113dSnw141292 ** May you find forgiveness for yourself and forgive others.
12*c5c4113dSnw141292 ** May you share freely, never taking more than you give.
13*c5c4113dSnw141292 **
14*c5c4113dSnw141292 *************************************************************************
15*c5c4113dSnw141292 ** This file contains code used to implement the PRAGMA command.
16*c5c4113dSnw141292 **
17*c5c4113dSnw141292 ** $Id: pragma.c,v 1.19 2004/04/23 17:04:45 drh Exp $
18*c5c4113dSnw141292 */
19*c5c4113dSnw141292 #include "sqliteInt.h"
20*c5c4113dSnw141292 #include <ctype.h>
21*c5c4113dSnw141292
22*c5c4113dSnw141292 /*
23*c5c4113dSnw141292 ** Interpret the given string as a boolean value.
24*c5c4113dSnw141292 */
getBoolean(const char * z)25*c5c4113dSnw141292 static int getBoolean(const char *z){
26*c5c4113dSnw141292 static char *azTrue[] = { "yes", "on", "true" };
27*c5c4113dSnw141292 int i;
28*c5c4113dSnw141292 if( z[0]==0 ) return 0;
29*c5c4113dSnw141292 if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){
30*c5c4113dSnw141292 return atoi(z);
31*c5c4113dSnw141292 }
32*c5c4113dSnw141292 for(i=0; i<sizeof(azTrue)/sizeof(azTrue[0]); i++){
33*c5c4113dSnw141292 if( sqliteStrICmp(z,azTrue[i])==0 ) return 1;
34*c5c4113dSnw141292 }
35*c5c4113dSnw141292 return 0;
36*c5c4113dSnw141292 }
37*c5c4113dSnw141292
38*c5c4113dSnw141292 /*
39*c5c4113dSnw141292 ** Interpret the given string as a safety level. Return 0 for OFF,
40*c5c4113dSnw141292 ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
41*c5c4113dSnw141292 ** unrecognized string argument.
42*c5c4113dSnw141292 **
43*c5c4113dSnw141292 ** Note that the values returned are one less that the values that
44*c5c4113dSnw141292 ** should be passed into sqliteBtreeSetSafetyLevel(). The is done
45*c5c4113dSnw141292 ** to support legacy SQL code. The safety level used to be boolean
46*c5c4113dSnw141292 ** and older scripts may have used numbers 0 for OFF and 1 for ON.
47*c5c4113dSnw141292 */
getSafetyLevel(char * z)48*c5c4113dSnw141292 static int getSafetyLevel(char *z){
49*c5c4113dSnw141292 static const struct {
50*c5c4113dSnw141292 const char *zWord;
51*c5c4113dSnw141292 int val;
52*c5c4113dSnw141292 } aKey[] = {
53*c5c4113dSnw141292 { "no", 0 },
54*c5c4113dSnw141292 { "off", 0 },
55*c5c4113dSnw141292 { "false", 0 },
56*c5c4113dSnw141292 { "yes", 1 },
57*c5c4113dSnw141292 { "on", 1 },
58*c5c4113dSnw141292 { "true", 1 },
59*c5c4113dSnw141292 { "full", 2 },
60*c5c4113dSnw141292 };
61*c5c4113dSnw141292 int i;
62*c5c4113dSnw141292 if( z[0]==0 ) return 1;
63*c5c4113dSnw141292 if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){
64*c5c4113dSnw141292 return atoi(z);
65*c5c4113dSnw141292 }
66*c5c4113dSnw141292 for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){
67*c5c4113dSnw141292 if( sqliteStrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
68*c5c4113dSnw141292 }
69*c5c4113dSnw141292 return 1;
70*c5c4113dSnw141292 }
71*c5c4113dSnw141292
72*c5c4113dSnw141292 /*
73*c5c4113dSnw141292 ** Interpret the given string as a temp db location. Return 1 for file
74*c5c4113dSnw141292 ** backed temporary databases, 2 for the Red-Black tree in memory database
75*c5c4113dSnw141292 ** and 0 to use the compile-time default.
76*c5c4113dSnw141292 */
getTempStore(const char * z)77*c5c4113dSnw141292 static int getTempStore(const char *z){
78*c5c4113dSnw141292 if( z[0]>='0' && z[0]<='2' ){
79*c5c4113dSnw141292 return z[0] - '0';
80*c5c4113dSnw141292 }else if( sqliteStrICmp(z, "file")==0 ){
81*c5c4113dSnw141292 return 1;
82*c5c4113dSnw141292 }else if( sqliteStrICmp(z, "memory")==0 ){
83*c5c4113dSnw141292 return 2;
84*c5c4113dSnw141292 }else{
85*c5c4113dSnw141292 return 0;
86*c5c4113dSnw141292 }
87*c5c4113dSnw141292 }
88*c5c4113dSnw141292
89*c5c4113dSnw141292 /*
90*c5c4113dSnw141292 ** If the TEMP database is open, close it and mark the database schema
91*c5c4113dSnw141292 ** as needing reloading. This must be done when using the TEMP_STORE
92*c5c4113dSnw141292 ** or DEFAULT_TEMP_STORE pragmas.
93*c5c4113dSnw141292 */
changeTempStorage(Parse * pParse,const char * zStorageType)94*c5c4113dSnw141292 static int changeTempStorage(Parse *pParse, const char *zStorageType){
95*c5c4113dSnw141292 int ts = getTempStore(zStorageType);
96*c5c4113dSnw141292 sqlite *db = pParse->db;
97*c5c4113dSnw141292 if( db->temp_store==ts ) return SQLITE_OK;
98*c5c4113dSnw141292 if( db->aDb[1].pBt!=0 ){
99*c5c4113dSnw141292 if( db->flags & SQLITE_InTrans ){
100*c5c4113dSnw141292 sqliteErrorMsg(pParse, "temporary storage cannot be changed "
101*c5c4113dSnw141292 "from within a transaction");
102*c5c4113dSnw141292 return SQLITE_ERROR;
103*c5c4113dSnw141292 }
104*c5c4113dSnw141292 sqliteBtreeClose(db->aDb[1].pBt);
105*c5c4113dSnw141292 db->aDb[1].pBt = 0;
106*c5c4113dSnw141292 sqliteResetInternalSchema(db, 0);
107*c5c4113dSnw141292 }
108*c5c4113dSnw141292 db->temp_store = ts;
109*c5c4113dSnw141292 return SQLITE_OK;
110*c5c4113dSnw141292 }
111*c5c4113dSnw141292
112*c5c4113dSnw141292 /*
113*c5c4113dSnw141292 ** Check to see if zRight and zLeft refer to a pragma that queries
114*c5c4113dSnw141292 ** or changes one of the flags in db->flags. Return 1 if so and 0 if not.
115*c5c4113dSnw141292 ** Also, implement the pragma.
116*c5c4113dSnw141292 */
flagPragma(Parse * pParse,const char * zLeft,const char * zRight)117*c5c4113dSnw141292 static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
118*c5c4113dSnw141292 static const struct {
119*c5c4113dSnw141292 const char *zName; /* Name of the pragma */
120*c5c4113dSnw141292 int mask; /* Mask for the db->flags value */
121*c5c4113dSnw141292 } aPragma[] = {
122*c5c4113dSnw141292 { "vdbe_trace", SQLITE_VdbeTrace },
123*c5c4113dSnw141292 { "full_column_names", SQLITE_FullColNames },
124*c5c4113dSnw141292 { "short_column_names", SQLITE_ShortColNames },
125*c5c4113dSnw141292 { "show_datatypes", SQLITE_ReportTypes },
126*c5c4113dSnw141292 { "count_changes", SQLITE_CountRows },
127*c5c4113dSnw141292 { "empty_result_callbacks", SQLITE_NullCallback },
128*c5c4113dSnw141292 };
129*c5c4113dSnw141292 int i;
130*c5c4113dSnw141292 for(i=0; i<sizeof(aPragma)/sizeof(aPragma[0]); i++){
131*c5c4113dSnw141292 if( sqliteStrICmp(zLeft, aPragma[i].zName)==0 ){
132*c5c4113dSnw141292 sqlite *db = pParse->db;
133*c5c4113dSnw141292 Vdbe *v;
134*c5c4113dSnw141292 if( strcmp(zLeft,zRight)==0 && (v = sqliteGetVdbe(pParse))!=0 ){
135*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_ColumnName, 0, 1, aPragma[i].zName, P3_STATIC);
136*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_ColumnName, 1, 0, "boolean", P3_STATIC);
137*c5c4113dSnw141292 sqliteVdbeCode(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0,
138*c5c4113dSnw141292 OP_Callback, 1, 0,
139*c5c4113dSnw141292 0);
140*c5c4113dSnw141292 }else if( getBoolean(zRight) ){
141*c5c4113dSnw141292 db->flags |= aPragma[i].mask;
142*c5c4113dSnw141292 }else{
143*c5c4113dSnw141292 db->flags &= ~aPragma[i].mask;
144*c5c4113dSnw141292 }
145*c5c4113dSnw141292 return 1;
146*c5c4113dSnw141292 }
147*c5c4113dSnw141292 }
148*c5c4113dSnw141292 return 0;
149*c5c4113dSnw141292 }
150*c5c4113dSnw141292
151*c5c4113dSnw141292 /*
152*c5c4113dSnw141292 ** Process a pragma statement.
153*c5c4113dSnw141292 **
154*c5c4113dSnw141292 ** Pragmas are of this form:
155*c5c4113dSnw141292 **
156*c5c4113dSnw141292 ** PRAGMA id = value
157*c5c4113dSnw141292 **
158*c5c4113dSnw141292 ** The identifier might also be a string. The value is a string, and
159*c5c4113dSnw141292 ** identifier, or a number. If minusFlag is true, then the value is
160*c5c4113dSnw141292 ** a number that was preceded by a minus sign.
161*c5c4113dSnw141292 */
sqlitePragma(Parse * pParse,Token * pLeft,Token * pRight,int minusFlag)162*c5c4113dSnw141292 void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
163*c5c4113dSnw141292 char *zLeft = 0;
164*c5c4113dSnw141292 char *zRight = 0;
165*c5c4113dSnw141292 sqlite *db = pParse->db;
166*c5c4113dSnw141292 Vdbe *v = sqliteGetVdbe(pParse);
167*c5c4113dSnw141292 if( v==0 ) return;
168*c5c4113dSnw141292
169*c5c4113dSnw141292 zLeft = sqliteStrNDup(pLeft->z, pLeft->n);
170*c5c4113dSnw141292 sqliteDequote(zLeft);
171*c5c4113dSnw141292 if( minusFlag ){
172*c5c4113dSnw141292 zRight = 0;
173*c5c4113dSnw141292 sqliteSetNString(&zRight, "-", 1, pRight->z, pRight->n, 0);
174*c5c4113dSnw141292 }else{
175*c5c4113dSnw141292 zRight = sqliteStrNDup(pRight->z, pRight->n);
176*c5c4113dSnw141292 sqliteDequote(zRight);
177*c5c4113dSnw141292 }
178*c5c4113dSnw141292 if( sqliteAuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, 0) ){
179*c5c4113dSnw141292 sqliteFree(zLeft);
180*c5c4113dSnw141292 sqliteFree(zRight);
181*c5c4113dSnw141292 return;
182*c5c4113dSnw141292 }
183*c5c4113dSnw141292
184*c5c4113dSnw141292 /*
185*c5c4113dSnw141292 ** PRAGMA default_cache_size
186*c5c4113dSnw141292 ** PRAGMA default_cache_size=N
187*c5c4113dSnw141292 **
188*c5c4113dSnw141292 ** The first form reports the current persistent setting for the
189*c5c4113dSnw141292 ** page cache size. The value returned is the maximum number of
190*c5c4113dSnw141292 ** pages in the page cache. The second form sets both the current
191*c5c4113dSnw141292 ** page cache size value and the persistent page cache size value
192*c5c4113dSnw141292 ** stored in the database file.
193*c5c4113dSnw141292 **
194*c5c4113dSnw141292 ** The default cache size is stored in meta-value 2 of page 1 of the
195*c5c4113dSnw141292 ** database file. The cache size is actually the absolute value of
196*c5c4113dSnw141292 ** this memory location. The sign of meta-value 2 determines the
197*c5c4113dSnw141292 ** synchronous setting. A negative value means synchronous is off
198*c5c4113dSnw141292 ** and a positive value means synchronous is on.
199*c5c4113dSnw141292 */
200*c5c4113dSnw141292 if( sqliteStrICmp(zLeft,"default_cache_size")==0 ){
201*c5c4113dSnw141292 static VdbeOpList getCacheSize[] = {
202*c5c4113dSnw141292 { OP_ReadCookie, 0, 2, 0},
203*c5c4113dSnw141292 { OP_AbsValue, 0, 0, 0},
204*c5c4113dSnw141292 { OP_Dup, 0, 0, 0},
205*c5c4113dSnw141292 { OP_Integer, 0, 0, 0},
206*c5c4113dSnw141292 { OP_Ne, 0, 6, 0},
207*c5c4113dSnw141292 { OP_Integer, 0, 0, 0}, /* 5 */
208*c5c4113dSnw141292 { OP_ColumnName, 0, 1, "cache_size"},
209*c5c4113dSnw141292 { OP_Callback, 1, 0, 0},
210*c5c4113dSnw141292 };
211*c5c4113dSnw141292 int addr;
212*c5c4113dSnw141292 if( pRight->z==pLeft->z ){
213*c5c4113dSnw141292 addr = sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
214*c5c4113dSnw141292 sqliteVdbeChangeP1(v, addr+5, MAX_PAGES);
215*c5c4113dSnw141292 }else{
216*c5c4113dSnw141292 int size = atoi(zRight);
217*c5c4113dSnw141292 if( size<0 ) size = -size;
218*c5c4113dSnw141292 sqliteBeginWriteOperation(pParse, 0, 0);
219*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, size, 0);
220*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
221*c5c4113dSnw141292 addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
222*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Ge, 0, addr+3);
223*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Negative, 0, 0);
224*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
225*c5c4113dSnw141292 sqliteEndWriteOperation(pParse);
226*c5c4113dSnw141292 db->cache_size = db->cache_size<0 ? -size : size;
227*c5c4113dSnw141292 sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
228*c5c4113dSnw141292 }
229*c5c4113dSnw141292 }else
230*c5c4113dSnw141292
231*c5c4113dSnw141292 /*
232*c5c4113dSnw141292 ** PRAGMA cache_size
233*c5c4113dSnw141292 ** PRAGMA cache_size=N
234*c5c4113dSnw141292 **
235*c5c4113dSnw141292 ** The first form reports the current local setting for the
236*c5c4113dSnw141292 ** page cache size. The local setting can be different from
237*c5c4113dSnw141292 ** the persistent cache size value that is stored in the database
238*c5c4113dSnw141292 ** file itself. The value returned is the maximum number of
239*c5c4113dSnw141292 ** pages in the page cache. The second form sets the local
240*c5c4113dSnw141292 ** page cache size value. It does not change the persistent
241*c5c4113dSnw141292 ** cache size stored on the disk so the cache size will revert
242*c5c4113dSnw141292 ** to its default value when the database is closed and reopened.
243*c5c4113dSnw141292 ** N should be a positive integer.
244*c5c4113dSnw141292 */
245*c5c4113dSnw141292 if( sqliteStrICmp(zLeft,"cache_size")==0 ){
246*c5c4113dSnw141292 static VdbeOpList getCacheSize[] = {
247*c5c4113dSnw141292 { OP_ColumnName, 0, 1, "cache_size"},
248*c5c4113dSnw141292 { OP_Callback, 1, 0, 0},
249*c5c4113dSnw141292 };
250*c5c4113dSnw141292 if( pRight->z==pLeft->z ){
251*c5c4113dSnw141292 int size = db->cache_size;;
252*c5c4113dSnw141292 if( size<0 ) size = -size;
253*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, size, 0);
254*c5c4113dSnw141292 sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
255*c5c4113dSnw141292 }else{
256*c5c4113dSnw141292 int size = atoi(zRight);
257*c5c4113dSnw141292 if( size<0 ) size = -size;
258*c5c4113dSnw141292 if( db->cache_size<0 ) size = -size;
259*c5c4113dSnw141292 db->cache_size = size;
260*c5c4113dSnw141292 sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
261*c5c4113dSnw141292 }
262*c5c4113dSnw141292 }else
263*c5c4113dSnw141292
264*c5c4113dSnw141292 /*
265*c5c4113dSnw141292 ** PRAGMA default_synchronous
266*c5c4113dSnw141292 ** PRAGMA default_synchronous=ON|OFF|NORMAL|FULL
267*c5c4113dSnw141292 **
268*c5c4113dSnw141292 ** The first form returns the persistent value of the "synchronous" setting
269*c5c4113dSnw141292 ** that is stored in the database. This is the synchronous setting that
270*c5c4113dSnw141292 ** is used whenever the database is opened unless overridden by a separate
271*c5c4113dSnw141292 ** "synchronous" pragma. The second form changes the persistent and the
272*c5c4113dSnw141292 ** local synchronous setting to the value given.
273*c5c4113dSnw141292 **
274*c5c4113dSnw141292 ** If synchronous is OFF, SQLite does not attempt any fsync() systems calls
275*c5c4113dSnw141292 ** to make sure data is committed to disk. Write operations are very fast,
276*c5c4113dSnw141292 ** but a power failure can leave the database in an inconsistent state.
277*c5c4113dSnw141292 ** If synchronous is ON or NORMAL, SQLite will do an fsync() system call to
278*c5c4113dSnw141292 ** make sure data is being written to disk. The risk of corruption due to
279*c5c4113dSnw141292 ** a power loss in this mode is negligible but non-zero. If synchronous
280*c5c4113dSnw141292 ** is FULL, extra fsync()s occur to reduce the risk of corruption to near
281*c5c4113dSnw141292 ** zero, but with a write performance penalty. The default mode is NORMAL.
282*c5c4113dSnw141292 */
283*c5c4113dSnw141292 if( sqliteStrICmp(zLeft,"default_synchronous")==0 ){
284*c5c4113dSnw141292 static VdbeOpList getSync[] = {
285*c5c4113dSnw141292 { OP_ColumnName, 0, 1, "synchronous"},
286*c5c4113dSnw141292 { OP_ReadCookie, 0, 3, 0},
287*c5c4113dSnw141292 { OP_Dup, 0, 0, 0},
288*c5c4113dSnw141292 { OP_If, 0, 0, 0}, /* 3 */
289*c5c4113dSnw141292 { OP_ReadCookie, 0, 2, 0},
290*c5c4113dSnw141292 { OP_Integer, 0, 0, 0},
291*c5c4113dSnw141292 { OP_Lt, 0, 5, 0},
292*c5c4113dSnw141292 { OP_AddImm, 1, 0, 0},
293*c5c4113dSnw141292 { OP_Callback, 1, 0, 0},
294*c5c4113dSnw141292 { OP_Halt, 0, 0, 0},
295*c5c4113dSnw141292 { OP_AddImm, -1, 0, 0}, /* 10 */
296*c5c4113dSnw141292 { OP_Callback, 1, 0, 0}
297*c5c4113dSnw141292 };
298*c5c4113dSnw141292 if( pRight->z==pLeft->z ){
299*c5c4113dSnw141292 int addr = sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
300*c5c4113dSnw141292 sqliteVdbeChangeP2(v, addr+3, addr+10);
301*c5c4113dSnw141292 }else{
302*c5c4113dSnw141292 int addr;
303*c5c4113dSnw141292 int size = db->cache_size;
304*c5c4113dSnw141292 if( size<0 ) size = -size;
305*c5c4113dSnw141292 sqliteBeginWriteOperation(pParse, 0, 0);
306*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
307*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Dup, 0, 0);
308*c5c4113dSnw141292 addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
309*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Ne, 0, addr+3);
310*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_AddImm, MAX_PAGES, 0);
311*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_AbsValue, 0, 0);
312*c5c4113dSnw141292 db->safety_level = getSafetyLevel(zRight)+1;
313*c5c4113dSnw141292 if( db->safety_level==1 ){
314*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Negative, 0, 0);
315*c5c4113dSnw141292 size = -size;
316*c5c4113dSnw141292 }
317*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
318*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, db->safety_level, 0);
319*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_SetCookie, 0, 3);
320*c5c4113dSnw141292 sqliteEndWriteOperation(pParse);
321*c5c4113dSnw141292 db->cache_size = size;
322*c5c4113dSnw141292 sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
323*c5c4113dSnw141292 sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
324*c5c4113dSnw141292 }
325*c5c4113dSnw141292 }else
326*c5c4113dSnw141292
327*c5c4113dSnw141292 /*
328*c5c4113dSnw141292 ** PRAGMA synchronous
329*c5c4113dSnw141292 ** PRAGMA synchronous=OFF|ON|NORMAL|FULL
330*c5c4113dSnw141292 **
331*c5c4113dSnw141292 ** Return or set the local value of the synchronous flag. Changing
332*c5c4113dSnw141292 ** the local value does not make changes to the disk file and the
333*c5c4113dSnw141292 ** default value will be restored the next time the database is
334*c5c4113dSnw141292 ** opened.
335*c5c4113dSnw141292 */
336*c5c4113dSnw141292 if( sqliteStrICmp(zLeft,"synchronous")==0 ){
337*c5c4113dSnw141292 static VdbeOpList getSync[] = {
338*c5c4113dSnw141292 { OP_ColumnName, 0, 1, "synchronous"},
339*c5c4113dSnw141292 { OP_Callback, 1, 0, 0},
340*c5c4113dSnw141292 };
341*c5c4113dSnw141292 if( pRight->z==pLeft->z ){
342*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, db->safety_level-1, 0);
343*c5c4113dSnw141292 sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
344*c5c4113dSnw141292 }else{
345*c5c4113dSnw141292 int size = db->cache_size;
346*c5c4113dSnw141292 if( size<0 ) size = -size;
347*c5c4113dSnw141292 db->safety_level = getSafetyLevel(zRight)+1;
348*c5c4113dSnw141292 if( db->safety_level==1 ) size = -size;
349*c5c4113dSnw141292 db->cache_size = size;
350*c5c4113dSnw141292 sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
351*c5c4113dSnw141292 sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
352*c5c4113dSnw141292 }
353*c5c4113dSnw141292 }else
354*c5c4113dSnw141292
355*c5c4113dSnw141292 #ifndef NDEBUG
356*c5c4113dSnw141292 if( sqliteStrICmp(zLeft, "trigger_overhead_test")==0 ){
357*c5c4113dSnw141292 if( getBoolean(zRight) ){
358*c5c4113dSnw141292 always_code_trigger_setup = 1;
359*c5c4113dSnw141292 }else{
360*c5c4113dSnw141292 always_code_trigger_setup = 0;
361*c5c4113dSnw141292 }
362*c5c4113dSnw141292 }else
363*c5c4113dSnw141292 #endif
364*c5c4113dSnw141292
365*c5c4113dSnw141292 if( flagPragma(pParse, zLeft, zRight) ){
366*c5c4113dSnw141292 /* The flagPragma() call also generates any necessary code */
367*c5c4113dSnw141292 }else
368*c5c4113dSnw141292
369*c5c4113dSnw141292 if( sqliteStrICmp(zLeft, "table_info")==0 ){
370*c5c4113dSnw141292 Table *pTab;
371*c5c4113dSnw141292 pTab = sqliteFindTable(db, zRight, 0);
372*c5c4113dSnw141292 if( pTab ){
373*c5c4113dSnw141292 static VdbeOpList tableInfoPreface[] = {
374*c5c4113dSnw141292 { OP_ColumnName, 0, 0, "cid"},
375*c5c4113dSnw141292 { OP_ColumnName, 1, 0, "name"},
376*c5c4113dSnw141292 { OP_ColumnName, 2, 0, "type"},
377*c5c4113dSnw141292 { OP_ColumnName, 3, 0, "notnull"},
378*c5c4113dSnw141292 { OP_ColumnName, 4, 0, "dflt_value"},
379*c5c4113dSnw141292 { OP_ColumnName, 5, 1, "pk"},
380*c5c4113dSnw141292 };
381*c5c4113dSnw141292 int i;
382*c5c4113dSnw141292 sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
383*c5c4113dSnw141292 sqliteViewGetColumnNames(pParse, pTab);
384*c5c4113dSnw141292 for(i=0; i<pTab->nCol; i++){
385*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, i, 0);
386*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zName, 0);
387*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_String, 0, 0,
388*c5c4113dSnw141292 pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
389*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
390*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_String, 0, 0,
391*c5c4113dSnw141292 pTab->aCol[i].zDflt, P3_STATIC);
392*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
393*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Callback, 6, 0);
394*c5c4113dSnw141292 }
395*c5c4113dSnw141292 }
396*c5c4113dSnw141292 }else
397*c5c4113dSnw141292
398*c5c4113dSnw141292 if( sqliteStrICmp(zLeft, "index_info")==0 ){
399*c5c4113dSnw141292 Index *pIdx;
400*c5c4113dSnw141292 Table *pTab;
401*c5c4113dSnw141292 pIdx = sqliteFindIndex(db, zRight, 0);
402*c5c4113dSnw141292 if( pIdx ){
403*c5c4113dSnw141292 static VdbeOpList tableInfoPreface[] = {
404*c5c4113dSnw141292 { OP_ColumnName, 0, 0, "seqno"},
405*c5c4113dSnw141292 { OP_ColumnName, 1, 0, "cid"},
406*c5c4113dSnw141292 { OP_ColumnName, 2, 1, "name"},
407*c5c4113dSnw141292 };
408*c5c4113dSnw141292 int i;
409*c5c4113dSnw141292 pTab = pIdx->pTable;
410*c5c4113dSnw141292 sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
411*c5c4113dSnw141292 for(i=0; i<pIdx->nColumn; i++){
412*c5c4113dSnw141292 int cnum = pIdx->aiColumn[i];
413*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, i, 0);
414*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, cnum, 0);
415*c5c4113dSnw141292 assert( pTab->nCol>cnum );
416*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[cnum].zName, 0);
417*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Callback, 3, 0);
418*c5c4113dSnw141292 }
419*c5c4113dSnw141292 }
420*c5c4113dSnw141292 }else
421*c5c4113dSnw141292
422*c5c4113dSnw141292 if( sqliteStrICmp(zLeft, "index_list")==0 ){
423*c5c4113dSnw141292 Index *pIdx;
424*c5c4113dSnw141292 Table *pTab;
425*c5c4113dSnw141292 pTab = sqliteFindTable(db, zRight, 0);
426*c5c4113dSnw141292 if( pTab ){
427*c5c4113dSnw141292 v = sqliteGetVdbe(pParse);
428*c5c4113dSnw141292 pIdx = pTab->pIndex;
429*c5c4113dSnw141292 }
430*c5c4113dSnw141292 if( pTab && pIdx ){
431*c5c4113dSnw141292 int i = 0;
432*c5c4113dSnw141292 static VdbeOpList indexListPreface[] = {
433*c5c4113dSnw141292 { OP_ColumnName, 0, 0, "seq"},
434*c5c4113dSnw141292 { OP_ColumnName, 1, 0, "name"},
435*c5c4113dSnw141292 { OP_ColumnName, 2, 1, "unique"},
436*c5c4113dSnw141292 };
437*c5c4113dSnw141292
438*c5c4113dSnw141292 sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
439*c5c4113dSnw141292 while(pIdx){
440*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, i, 0);
441*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_String, 0, 0, pIdx->zName, 0);
442*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
443*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Callback, 3, 0);
444*c5c4113dSnw141292 ++i;
445*c5c4113dSnw141292 pIdx = pIdx->pNext;
446*c5c4113dSnw141292 }
447*c5c4113dSnw141292 }
448*c5c4113dSnw141292 }else
449*c5c4113dSnw141292
450*c5c4113dSnw141292 if( sqliteStrICmp(zLeft, "foreign_key_list")==0 ){
451*c5c4113dSnw141292 FKey *pFK;
452*c5c4113dSnw141292 Table *pTab;
453*c5c4113dSnw141292 pTab = sqliteFindTable(db, zRight, 0);
454*c5c4113dSnw141292 if( pTab ){
455*c5c4113dSnw141292 v = sqliteGetVdbe(pParse);
456*c5c4113dSnw141292 pFK = pTab->pFKey;
457*c5c4113dSnw141292 }
458*c5c4113dSnw141292 if( pTab && pFK ){
459*c5c4113dSnw141292 int i = 0;
460*c5c4113dSnw141292 static VdbeOpList indexListPreface[] = {
461*c5c4113dSnw141292 { OP_ColumnName, 0, 0, "id"},
462*c5c4113dSnw141292 { OP_ColumnName, 1, 0, "seq"},
463*c5c4113dSnw141292 { OP_ColumnName, 2, 0, "table"},
464*c5c4113dSnw141292 { OP_ColumnName, 3, 0, "from"},
465*c5c4113dSnw141292 { OP_ColumnName, 4, 1, "to"},
466*c5c4113dSnw141292 };
467*c5c4113dSnw141292
468*c5c4113dSnw141292 sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
469*c5c4113dSnw141292 while(pFK){
470*c5c4113dSnw141292 int j;
471*c5c4113dSnw141292 for(j=0; j<pFK->nCol; j++){
472*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, i, 0);
473*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, j, 0);
474*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_String, 0, 0, pFK->zTo, 0);
475*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_String, 0, 0,
476*c5c4113dSnw141292 pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
477*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_String, 0, 0, pFK->aCol[j].zCol, 0);
478*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Callback, 5, 0);
479*c5c4113dSnw141292 }
480*c5c4113dSnw141292 ++i;
481*c5c4113dSnw141292 pFK = pFK->pNextFrom;
482*c5c4113dSnw141292 }
483*c5c4113dSnw141292 }
484*c5c4113dSnw141292 }else
485*c5c4113dSnw141292
486*c5c4113dSnw141292 if( sqliteStrICmp(zLeft, "database_list")==0 ){
487*c5c4113dSnw141292 int i;
488*c5c4113dSnw141292 static VdbeOpList indexListPreface[] = {
489*c5c4113dSnw141292 { OP_ColumnName, 0, 0, "seq"},
490*c5c4113dSnw141292 { OP_ColumnName, 1, 0, "name"},
491*c5c4113dSnw141292 { OP_ColumnName, 2, 1, "file"},
492*c5c4113dSnw141292 };
493*c5c4113dSnw141292
494*c5c4113dSnw141292 sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
495*c5c4113dSnw141292 for(i=0; i<db->nDb; i++){
496*c5c4113dSnw141292 if( db->aDb[i].pBt==0 ) continue;
497*c5c4113dSnw141292 assert( db->aDb[i].zName!=0 );
498*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, i, 0);
499*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, 0);
500*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_String, 0, 0,
501*c5c4113dSnw141292 sqliteBtreeGetFilename(db->aDb[i].pBt), 0);
502*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Callback, 3, 0);
503*c5c4113dSnw141292 }
504*c5c4113dSnw141292 }else
505*c5c4113dSnw141292
506*c5c4113dSnw141292
507*c5c4113dSnw141292 /*
508*c5c4113dSnw141292 ** PRAGMA temp_store
509*c5c4113dSnw141292 ** PRAGMA temp_store = "default"|"memory"|"file"
510*c5c4113dSnw141292 **
511*c5c4113dSnw141292 ** Return or set the local value of the temp_store flag. Changing
512*c5c4113dSnw141292 ** the local value does not make changes to the disk file and the default
513*c5c4113dSnw141292 ** value will be restored the next time the database is opened.
514*c5c4113dSnw141292 **
515*c5c4113dSnw141292 ** Note that it is possible for the library compile-time options to
516*c5c4113dSnw141292 ** override this setting
517*c5c4113dSnw141292 */
518*c5c4113dSnw141292 if( sqliteStrICmp(zLeft, "temp_store")==0 ){
519*c5c4113dSnw141292 static VdbeOpList getTmpDbLoc[] = {
520*c5c4113dSnw141292 { OP_ColumnName, 0, 1, "temp_store"},
521*c5c4113dSnw141292 { OP_Callback, 1, 0, 0},
522*c5c4113dSnw141292 };
523*c5c4113dSnw141292 if( pRight->z==pLeft->z ){
524*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0);
525*c5c4113dSnw141292 sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
526*c5c4113dSnw141292 }else{
527*c5c4113dSnw141292 changeTempStorage(pParse, zRight);
528*c5c4113dSnw141292 }
529*c5c4113dSnw141292 }else
530*c5c4113dSnw141292
531*c5c4113dSnw141292 /*
532*c5c4113dSnw141292 ** PRAGMA default_temp_store
533*c5c4113dSnw141292 ** PRAGMA default_temp_store = "default"|"memory"|"file"
534*c5c4113dSnw141292 **
535*c5c4113dSnw141292 ** Return or set the value of the persistent temp_store flag. Any
536*c5c4113dSnw141292 ** change does not take effect until the next time the database is
537*c5c4113dSnw141292 ** opened.
538*c5c4113dSnw141292 **
539*c5c4113dSnw141292 ** Note that it is possible for the library compile-time options to
540*c5c4113dSnw141292 ** override this setting
541*c5c4113dSnw141292 */
542*c5c4113dSnw141292 if( sqliteStrICmp(zLeft, "default_temp_store")==0 ){
543*c5c4113dSnw141292 static VdbeOpList getTmpDbLoc[] = {
544*c5c4113dSnw141292 { OP_ColumnName, 0, 1, "temp_store"},
545*c5c4113dSnw141292 { OP_ReadCookie, 0, 5, 0},
546*c5c4113dSnw141292 { OP_Callback, 1, 0, 0}};
547*c5c4113dSnw141292 if( pRight->z==pLeft->z ){
548*c5c4113dSnw141292 sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
549*c5c4113dSnw141292 }else{
550*c5c4113dSnw141292 sqliteBeginWriteOperation(pParse, 0, 0);
551*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, getTempStore(zRight), 0);
552*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_SetCookie, 0, 5);
553*c5c4113dSnw141292 sqliteEndWriteOperation(pParse);
554*c5c4113dSnw141292 }
555*c5c4113dSnw141292 }else
556*c5c4113dSnw141292
557*c5c4113dSnw141292 #ifndef NDEBUG
558*c5c4113dSnw141292 if( sqliteStrICmp(zLeft, "parser_trace")==0 ){
559*c5c4113dSnw141292 extern void sqliteParserTrace(FILE*, char *);
560*c5c4113dSnw141292 if( getBoolean(zRight) ){
561*c5c4113dSnw141292 sqliteParserTrace(stdout, "parser: ");
562*c5c4113dSnw141292 }else{
563*c5c4113dSnw141292 sqliteParserTrace(0, 0);
564*c5c4113dSnw141292 }
565*c5c4113dSnw141292 }else
566*c5c4113dSnw141292 #endif
567*c5c4113dSnw141292
568*c5c4113dSnw141292 if( sqliteStrICmp(zLeft, "integrity_check")==0 ){
569*c5c4113dSnw141292 int i, j, addr;
570*c5c4113dSnw141292
571*c5c4113dSnw141292 /* Code that initializes the integrity check program. Set the
572*c5c4113dSnw141292 ** error count 0
573*c5c4113dSnw141292 */
574*c5c4113dSnw141292 static VdbeOpList initCode[] = {
575*c5c4113dSnw141292 { OP_Integer, 0, 0, 0},
576*c5c4113dSnw141292 { OP_MemStore, 0, 1, 0},
577*c5c4113dSnw141292 { OP_ColumnName, 0, 1, "integrity_check"},
578*c5c4113dSnw141292 };
579*c5c4113dSnw141292
580*c5c4113dSnw141292 /* Code to do an BTree integrity check on a single database file.
581*c5c4113dSnw141292 */
582*c5c4113dSnw141292 static VdbeOpList checkDb[] = {
583*c5c4113dSnw141292 { OP_SetInsert, 0, 0, "2"},
584*c5c4113dSnw141292 { OP_Integer, 0, 0, 0}, /* 1 */
585*c5c4113dSnw141292 { OP_OpenRead, 0, 2, 0},
586*c5c4113dSnw141292 { OP_Rewind, 0, 7, 0}, /* 3 */
587*c5c4113dSnw141292 { OP_Column, 0, 3, 0}, /* 4 */
588*c5c4113dSnw141292 { OP_SetInsert, 0, 0, 0},
589*c5c4113dSnw141292 { OP_Next, 0, 4, 0}, /* 6 */
590*c5c4113dSnw141292 { OP_IntegrityCk, 0, 0, 0}, /* 7 */
591*c5c4113dSnw141292 { OP_Dup, 0, 1, 0},
592*c5c4113dSnw141292 { OP_String, 0, 0, "ok"},
593*c5c4113dSnw141292 { OP_StrEq, 0, 12, 0}, /* 10 */
594*c5c4113dSnw141292 { OP_MemIncr, 0, 0, 0},
595*c5c4113dSnw141292 { OP_String, 0, 0, "*** in database "},
596*c5c4113dSnw141292 { OP_String, 0, 0, 0}, /* 13 */
597*c5c4113dSnw141292 { OP_String, 0, 0, " ***\n"},
598*c5c4113dSnw141292 { OP_Pull, 3, 0, 0},
599*c5c4113dSnw141292 { OP_Concat, 4, 1, 0},
600*c5c4113dSnw141292 { OP_Callback, 1, 0, 0},
601*c5c4113dSnw141292 };
602*c5c4113dSnw141292
603*c5c4113dSnw141292 /* Code that appears at the end of the integrity check. If no error
604*c5c4113dSnw141292 ** messages have been generated, output OK. Otherwise output the
605*c5c4113dSnw141292 ** error message
606*c5c4113dSnw141292 */
607*c5c4113dSnw141292 static VdbeOpList endCode[] = {
608*c5c4113dSnw141292 { OP_MemLoad, 0, 0, 0},
609*c5c4113dSnw141292 { OP_Integer, 0, 0, 0},
610*c5c4113dSnw141292 { OP_Ne, 0, 0, 0}, /* 2 */
611*c5c4113dSnw141292 { OP_String, 0, 0, "ok"},
612*c5c4113dSnw141292 { OP_Callback, 1, 0, 0},
613*c5c4113dSnw141292 };
614*c5c4113dSnw141292
615*c5c4113dSnw141292 /* Initialize the VDBE program */
616*c5c4113dSnw141292 sqliteVdbeAddOpList(v, ArraySize(initCode), initCode);
617*c5c4113dSnw141292
618*c5c4113dSnw141292 /* Do an integrity check on each database file */
619*c5c4113dSnw141292 for(i=0; i<db->nDb; i++){
620*c5c4113dSnw141292 HashElem *x;
621*c5c4113dSnw141292
622*c5c4113dSnw141292 /* Do an integrity check of the B-Tree
623*c5c4113dSnw141292 */
624*c5c4113dSnw141292 addr = sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb);
625*c5c4113dSnw141292 sqliteVdbeChangeP1(v, addr+1, i);
626*c5c4113dSnw141292 sqliteVdbeChangeP2(v, addr+3, addr+7);
627*c5c4113dSnw141292 sqliteVdbeChangeP2(v, addr+6, addr+4);
628*c5c4113dSnw141292 sqliteVdbeChangeP2(v, addr+7, i);
629*c5c4113dSnw141292 sqliteVdbeChangeP2(v, addr+10, addr+ArraySize(checkDb));
630*c5c4113dSnw141292 sqliteVdbeChangeP3(v, addr+13, db->aDb[i].zName, P3_STATIC);
631*c5c4113dSnw141292
632*c5c4113dSnw141292 /* Make sure all the indices are constructed correctly.
633*c5c4113dSnw141292 */
634*c5c4113dSnw141292 sqliteCodeVerifySchema(pParse, i);
635*c5c4113dSnw141292 for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
636*c5c4113dSnw141292 Table *pTab = sqliteHashData(x);
637*c5c4113dSnw141292 Index *pIdx;
638*c5c4113dSnw141292 int loopTop;
639*c5c4113dSnw141292
640*c5c4113dSnw141292 if( pTab->pIndex==0 ) continue;
641*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, i, 0);
642*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_OpenRead, 1, pTab->tnum, pTab->zName, 0);
643*c5c4113dSnw141292 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
644*c5c4113dSnw141292 if( pIdx->tnum==0 ) continue;
645*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
646*c5c4113dSnw141292 sqliteVdbeOp3(v, OP_OpenRead, j+2, pIdx->tnum, pIdx->zName, 0);
647*c5c4113dSnw141292 }
648*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Integer, 0, 0);
649*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_MemStore, 1, 1);
650*c5c4113dSnw141292 loopTop = sqliteVdbeAddOp(v, OP_Rewind, 1, 0);
651*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_MemIncr, 1, 0);
652*c5c4113dSnw141292 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
653*c5c4113dSnw141292 int k, jmp2;
654*c5c4113dSnw141292 static VdbeOpList idxErr[] = {
655*c5c4113dSnw141292 { OP_MemIncr, 0, 0, 0},
656*c5c4113dSnw141292 { OP_String, 0, 0, "rowid "},
657*c5c4113dSnw141292 { OP_Recno, 1, 0, 0},
658*c5c4113dSnw141292 { OP_String, 0, 0, " missing from index "},
659*c5c4113dSnw141292 { OP_String, 0, 0, 0}, /* 4 */
660*c5c4113dSnw141292 { OP_Concat, 4, 0, 0},
661*c5c4113dSnw141292 { OP_Callback, 1, 0, 0},
662*c5c4113dSnw141292 };
663*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Recno, 1, 0);
664*c5c4113dSnw141292 for(k=0; k<pIdx->nColumn; k++){
665*c5c4113dSnw141292 int idx = pIdx->aiColumn[k];
666*c5c4113dSnw141292 if( idx==pTab->iPKey ){
667*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Recno, 1, 0);
668*c5c4113dSnw141292 }else{
669*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Column, 1, idx);
670*c5c4113dSnw141292 }
671*c5c4113dSnw141292 }
672*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
673*c5c4113dSnw141292 if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
674*c5c4113dSnw141292 jmp2 = sqliteVdbeAddOp(v, OP_Found, j+2, 0);
675*c5c4113dSnw141292 addr = sqliteVdbeAddOpList(v, ArraySize(idxErr), idxErr);
676*c5c4113dSnw141292 sqliteVdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
677*c5c4113dSnw141292 sqliteVdbeChangeP2(v, jmp2, sqliteVdbeCurrentAddr(v));
678*c5c4113dSnw141292 }
679*c5c4113dSnw141292 sqliteVdbeAddOp(v, OP_Next, 1, loopTop+1);
680*c5c4113dSnw141292 sqliteVdbeChangeP2(v, loopTop, sqliteVdbeCurrentAddr(v));
681*c5c4113dSnw141292 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
682*c5c4113dSnw141292 static VdbeOpList cntIdx[] = {
683*c5c4113dSnw141292 { OP_Integer, 0, 0, 0},
684*c5c4113dSnw141292 { OP_MemStore, 2, 1, 0},
685*c5c4113dSnw141292 { OP_Rewind, 0, 0, 0}, /* 2 */
686*c5c4113dSnw141292 { OP_MemIncr, 2, 0, 0},
687*c5c4113dSnw141292 { OP_Next, 0, 0, 0}, /* 4 */
688*c5c4113dSnw141292 { OP_MemLoad, 1, 0, 0},
689*c5c4113dSnw141292 { OP_MemLoad, 2, 0, 0},
690*c5c4113dSnw141292 { OP_Eq, 0, 0, 0}, /* 7 */
691*c5c4113dSnw141292 { OP_MemIncr, 0, 0, 0},
692*c5c4113dSnw141292 { OP_String, 0, 0, "wrong # of entries in index "},
693*c5c4113dSnw141292 { OP_String, 0, 0, 0}, /* 10 */
694*c5c4113dSnw141292 { OP_Concat, 2, 0, 0},
695*c5c4113dSnw141292 { OP_Callback, 1, 0, 0},
696*c5c4113dSnw141292 };
697*c5c4113dSnw141292 if( pIdx->tnum==0 ) continue;
698*c5c4113dSnw141292 addr = sqliteVdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
699*c5c4113dSnw141292 sqliteVdbeChangeP1(v, addr+2, j+2);
700*c5c4113dSnw141292 sqliteVdbeChangeP2(v, addr+2, addr+5);
701*c5c4113dSnw141292 sqliteVdbeChangeP1(v, addr+4, j+2);
702*c5c4113dSnw141292 sqliteVdbeChangeP2(v, addr+4, addr+3);
703*c5c4113dSnw141292 sqliteVdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
704*c5c4113dSnw141292 sqliteVdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
705*c5c4113dSnw141292 }
706*c5c4113dSnw141292 }
707*c5c4113dSnw141292 }
708*c5c4113dSnw141292 addr = sqliteVdbeAddOpList(v, ArraySize(endCode), endCode);
709*c5c4113dSnw141292 sqliteVdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
710*c5c4113dSnw141292 }else
711*c5c4113dSnw141292
712*c5c4113dSnw141292 {}
713*c5c4113dSnw141292 sqliteFree(zLeft);
714*c5c4113dSnw141292 sqliteFree(zRight);
715*c5c4113dSnw141292 }
716