xref: /titanic_50/usr/src/lib/libsqlite/src/pragma.c (revision c5c4113dfcabb1eed3d4bdf7609de5170027a794)
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