| OLD | NEW |
| 1 /* | 1 /* |
| 2 ** 2003 April 6 | 2 ** 2003 April 6 |
| 3 ** | 3 ** |
| 4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
| 5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
| 6 ** | 6 ** |
| 7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
| 8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
| 9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
| 10 ** | 10 ** |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", | 90 zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", |
| 91 db->aLimit[SQLITE_LIMIT_ATTACHED] | 91 db->aLimit[SQLITE_LIMIT_ATTACHED] |
| 92 ); | 92 ); |
| 93 goto attach_error; | 93 goto attach_error; |
| 94 } | 94 } |
| 95 if( !db->autoCommit ){ | 95 if( !db->autoCommit ){ |
| 96 zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction"); | 96 zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction"); |
| 97 goto attach_error; | 97 goto attach_error; |
| 98 } | 98 } |
| 99 for(i=0; i<db->nDb; i++){ | 99 for(i=0; i<db->nDb; i++){ |
| 100 char *z = db->aDb[i].zName; | 100 char *z = db->aDb[i].zDbSName; |
| 101 assert( z && zName ); | 101 assert( z && zName ); |
| 102 if( sqlite3StrICmp(z, zName)==0 ){ | 102 if( sqlite3StrICmp(z, zName)==0 ){ |
| 103 zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); | 103 zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); |
| 104 goto attach_error; | 104 goto attach_error; |
| 105 } | 105 } |
| 106 } | 106 } |
| 107 | 107 |
| 108 /* Allocate the new entry in the db->aDb[] array and initialize the schema | 108 /* Allocate the new entry in the db->aDb[] array and initialize the schema |
| 109 ** hash tables. | 109 ** hash tables. |
| 110 */ | 110 */ |
| 111 if( db->aDb==db->aDbStatic ){ | 111 if( db->aDb==db->aDbStatic ){ |
| 112 aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 ); | 112 aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); |
| 113 if( aNew==0 ) return; | 113 if( aNew==0 ) return; |
| 114 memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); | 114 memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); |
| 115 }else{ | 115 }else{ |
| 116 aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); | 116 aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); |
| 117 if( aNew==0 ) return; | 117 if( aNew==0 ) return; |
| 118 } | 118 } |
| 119 db->aDb = aNew; | 119 db->aDb = aNew; |
| 120 aNew = &db->aDb[db->nDb]; | 120 aNew = &db->aDb[db->nDb]; |
| 121 memset(aNew, 0, sizeof(*aNew)); | 121 memset(aNew, 0, sizeof(*aNew)); |
| 122 | 122 |
| 123 /* Open the database file. If the btree is successfully opened, use | 123 /* Open the database file. If the btree is successfully opened, use |
| 124 ** it to obtain the database schema. At this point the schema may | 124 ** it to obtain the database schema. At this point the schema may |
| 125 ** or may not be initialized. | 125 ** or may not be initialized. |
| 126 */ | 126 */ |
| 127 flags = db->openFlags; | 127 flags = db->openFlags; |
| 128 rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); | 128 rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); |
| 129 if( rc!=SQLITE_OK ){ | 129 if( rc!=SQLITE_OK ){ |
| 130 if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; | 130 if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); |
| 131 sqlite3_result_error(context, zErr, -1); | 131 sqlite3_result_error(context, zErr, -1); |
| 132 sqlite3_free(zErr); | 132 sqlite3_free(zErr); |
| 133 return; | 133 return; |
| 134 } | 134 } |
| 135 assert( pVfs ); | 135 assert( pVfs ); |
| 136 flags |= SQLITE_OPEN_MAIN_DB; | 136 flags |= SQLITE_OPEN_MAIN_DB; |
| 137 rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags); | 137 rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags); |
| 138 sqlite3_free( zPath ); | 138 sqlite3_free( zPath ); |
| 139 db->nDb++; | 139 db->nDb++; |
| 140 db->skipBtreeMutex = 0; |
| 140 if( rc==SQLITE_CONSTRAINT ){ | 141 if( rc==SQLITE_CONSTRAINT ){ |
| 141 rc = SQLITE_ERROR; | 142 rc = SQLITE_ERROR; |
| 142 zErrDyn = sqlite3MPrintf(db, "database is already attached"); | 143 zErrDyn = sqlite3MPrintf(db, "database is already attached"); |
| 143 }else if( rc==SQLITE_OK ){ | 144 }else if( rc==SQLITE_OK ){ |
| 144 Pager *pPager; | 145 Pager *pPager; |
| 145 aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt); | 146 aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt); |
| 146 if( !aNew->pSchema ){ | 147 if( !aNew->pSchema ){ |
| 147 rc = SQLITE_NOMEM; | 148 rc = SQLITE_NOMEM_BKPT; |
| 148 }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ | 149 }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ |
| 149 zErrDyn = sqlite3MPrintf(db, | 150 zErrDyn = sqlite3MPrintf(db, |
| 150 "attached databases must use the same text encoding as main database"); | 151 "attached databases must use the same text encoding as main database"); |
| 151 rc = SQLITE_ERROR; | 152 rc = SQLITE_ERROR; |
| 152 } | 153 } |
| 153 sqlite3BtreeEnter(aNew->pBt); | 154 sqlite3BtreeEnter(aNew->pBt); |
| 154 pPager = sqlite3BtreePager(aNew->pBt); | 155 pPager = sqlite3BtreePager(aNew->pBt); |
| 155 sqlite3PagerLockingMode(pPager, db->dfltLockMode); | 156 sqlite3PagerLockingMode(pPager, db->dfltLockMode); |
| 156 sqlite3BtreeSecureDelete(aNew->pBt, | 157 sqlite3BtreeSecureDelete(aNew->pBt, |
| 157 sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); | 158 sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); |
| 158 #ifndef SQLITE_OMIT_PAGER_PRAGMAS | 159 #ifndef SQLITE_OMIT_PAGER_PRAGMAS |
| 159 sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK)); | 160 sqlite3BtreeSetPagerFlags(aNew->pBt, |
| 161 PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK)); |
| 160 #endif | 162 #endif |
| 161 sqlite3BtreeLeave(aNew->pBt); | 163 sqlite3BtreeLeave(aNew->pBt); |
| 162 } | 164 } |
| 163 aNew->safety_level = 3; | 165 aNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; |
| 164 aNew->zName = sqlite3DbStrDup(db, zName); | 166 aNew->zDbSName = sqlite3DbStrDup(db, zName); |
| 165 if( rc==SQLITE_OK && aNew->zName==0 ){ | 167 if( rc==SQLITE_OK && aNew->zDbSName==0 ){ |
| 166 rc = SQLITE_NOMEM; | 168 rc = SQLITE_NOMEM_BKPT; |
| 167 } | 169 } |
| 168 | 170 |
| 169 | 171 |
| 170 #ifdef SQLITE_HAS_CODEC | 172 #ifdef SQLITE_HAS_CODEC |
| 171 if( rc==SQLITE_OK ){ | 173 if( rc==SQLITE_OK ){ |
| 172 extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); | 174 extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); |
| 173 extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); | 175 extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); |
| 174 int nKey; | 176 int nKey; |
| 175 char *zKey; | 177 char *zKey; |
| 176 int t = sqlite3_value_type(argv[2]); | 178 int t = sqlite3_value_type(argv[2]); |
| 177 switch( t ){ | 179 switch( t ){ |
| 178 case SQLITE_INTEGER: | 180 case SQLITE_INTEGER: |
| 179 case SQLITE_FLOAT: | 181 case SQLITE_FLOAT: |
| 180 zErrDyn = sqlite3DbStrDup(db, "Invalid key value"); | 182 zErrDyn = sqlite3DbStrDup(db, "Invalid key value"); |
| 181 rc = SQLITE_ERROR; | 183 rc = SQLITE_ERROR; |
| 182 break; | 184 break; |
| 183 | 185 |
| 184 case SQLITE_TEXT: | 186 case SQLITE_TEXT: |
| 185 case SQLITE_BLOB: | 187 case SQLITE_BLOB: |
| 186 nKey = sqlite3_value_bytes(argv[2]); | 188 nKey = sqlite3_value_bytes(argv[2]); |
| 187 zKey = (char *)sqlite3_value_blob(argv[2]); | 189 zKey = (char *)sqlite3_value_blob(argv[2]); |
| 188 rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); | 190 rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); |
| 189 break; | 191 break; |
| 190 | 192 |
| 191 case SQLITE_NULL: | 193 case SQLITE_NULL: |
| 192 /* No key specified. Use the key from the main database */ | 194 /* No key specified. Use the key from the main database */ |
| 193 sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); | 195 sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); |
| 194 if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ | 196 if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ |
| 195 rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); | 197 rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); |
| 196 } | 198 } |
| 197 break; | 199 break; |
| 198 } | 200 } |
| 199 } | 201 } |
| 200 #endif | 202 #endif |
| 201 | 203 |
| 202 /* If the file was opened successfully, read the schema for the new database. | 204 /* If the file was opened successfully, read the schema for the new database. |
| 203 ** If this fails, or if opening the file failed, then close the file and | 205 ** If this fails, or if opening the file failed, then close the file and |
| 204 ** remove the entry from the db->aDb[] array. i.e. put everything back the way | 206 ** remove the entry from the db->aDb[] array. i.e. put everything back the way |
| (...skipping 17 matching lines...) Expand all Loading... |
| 222 int iDb = db->nDb - 1; | 224 int iDb = db->nDb - 1; |
| 223 assert( iDb>=2 ); | 225 assert( iDb>=2 ); |
| 224 if( db->aDb[iDb].pBt ){ | 226 if( db->aDb[iDb].pBt ){ |
| 225 sqlite3BtreeClose(db->aDb[iDb].pBt); | 227 sqlite3BtreeClose(db->aDb[iDb].pBt); |
| 226 db->aDb[iDb].pBt = 0; | 228 db->aDb[iDb].pBt = 0; |
| 227 db->aDb[iDb].pSchema = 0; | 229 db->aDb[iDb].pSchema = 0; |
| 228 } | 230 } |
| 229 sqlite3ResetAllSchemasOfConnection(db); | 231 sqlite3ResetAllSchemasOfConnection(db); |
| 230 db->nDb = iDb; | 232 db->nDb = iDb; |
| 231 if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ | 233 if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ |
| 232 db->mallocFailed = 1; | 234 sqlite3OomFault(db); |
| 233 sqlite3DbFree(db, zErrDyn); | 235 sqlite3DbFree(db, zErrDyn); |
| 234 zErrDyn = sqlite3MPrintf(db, "out of memory"); | 236 zErrDyn = sqlite3MPrintf(db, "out of memory"); |
| 235 }else if( zErrDyn==0 ){ | 237 }else if( zErrDyn==0 ){ |
| 236 zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); | 238 zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); |
| 237 } | 239 } |
| 238 goto attach_error; | 240 goto attach_error; |
| 239 } | 241 } |
| 240 | 242 |
| 241 return; | 243 return; |
| 242 | 244 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 267 int i; | 269 int i; |
| 268 Db *pDb = 0; | 270 Db *pDb = 0; |
| 269 char zErr[128]; | 271 char zErr[128]; |
| 270 | 272 |
| 271 UNUSED_PARAMETER(NotUsed); | 273 UNUSED_PARAMETER(NotUsed); |
| 272 | 274 |
| 273 if( zName==0 ) zName = ""; | 275 if( zName==0 ) zName = ""; |
| 274 for(i=0; i<db->nDb; i++){ | 276 for(i=0; i<db->nDb; i++){ |
| 275 pDb = &db->aDb[i]; | 277 pDb = &db->aDb[i]; |
| 276 if( pDb->pBt==0 ) continue; | 278 if( pDb->pBt==0 ) continue; |
| 277 if( sqlite3StrICmp(pDb->zName, zName)==0 ) break; | 279 if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break; |
| 278 } | 280 } |
| 279 | 281 |
| 280 if( i>=db->nDb ){ | 282 if( i>=db->nDb ){ |
| 281 sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); | 283 sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); |
| 282 goto detach_error; | 284 goto detach_error; |
| 283 } | 285 } |
| 284 if( i<2 ){ | 286 if( i<2 ){ |
| 285 sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); | 287 sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); |
| 286 goto detach_error; | 288 goto detach_error; |
| 287 } | 289 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 317 Expr *pFilename, /* Name of database file */ | 319 Expr *pFilename, /* Name of database file */ |
| 318 Expr *pDbname, /* Name of the database to use internally */ | 320 Expr *pDbname, /* Name of the database to use internally */ |
| 319 Expr *pKey /* Database key for encryption extension */ | 321 Expr *pKey /* Database key for encryption extension */ |
| 320 ){ | 322 ){ |
| 321 int rc; | 323 int rc; |
| 322 NameContext sName; | 324 NameContext sName; |
| 323 Vdbe *v; | 325 Vdbe *v; |
| 324 sqlite3* db = pParse->db; | 326 sqlite3* db = pParse->db; |
| 325 int regArgs; | 327 int regArgs; |
| 326 | 328 |
| 329 if( pParse->nErr ) goto attach_end; |
| 327 memset(&sName, 0, sizeof(NameContext)); | 330 memset(&sName, 0, sizeof(NameContext)); |
| 328 sName.pParse = pParse; | 331 sName.pParse = pParse; |
| 329 | 332 |
| 330 if( | 333 if( |
| 331 SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) || | 334 SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) || |
| 332 SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) || | 335 SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) || |
| 333 SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) | 336 SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) |
| 334 ){ | 337 ){ |
| 335 goto attach_end; | 338 goto attach_end; |
| 336 } | 339 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 352 | 355 |
| 353 | 356 |
| 354 v = sqlite3GetVdbe(pParse); | 357 v = sqlite3GetVdbe(pParse); |
| 355 regArgs = sqlite3GetTempRange(pParse, 4); | 358 regArgs = sqlite3GetTempRange(pParse, 4); |
| 356 sqlite3ExprCode(pParse, pFilename, regArgs); | 359 sqlite3ExprCode(pParse, pFilename, regArgs); |
| 357 sqlite3ExprCode(pParse, pDbname, regArgs+1); | 360 sqlite3ExprCode(pParse, pDbname, regArgs+1); |
| 358 sqlite3ExprCode(pParse, pKey, regArgs+2); | 361 sqlite3ExprCode(pParse, pKey, regArgs+2); |
| 359 | 362 |
| 360 assert( v || db->mallocFailed ); | 363 assert( v || db->mallocFailed ); |
| 361 if( v ){ | 364 if( v ){ |
| 362 sqlite3VdbeAddOp3(v, OP_Function0, 0, regArgs+3-pFunc->nArg, regArgs+3); | 365 sqlite3VdbeAddOp4(v, OP_Function0, 0, regArgs+3-pFunc->nArg, regArgs+3, |
| 366 (char *)pFunc, P4_FUNCDEF); |
| 363 assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg ); | 367 assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg ); |
| 364 sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); | 368 sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); |
| 365 sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF); | 369 |
| 366 | |
| 367 /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this | 370 /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this |
| 368 ** statement only). For DETACH, set it to false (expire all existing | 371 ** statement only). For DETACH, set it to false (expire all existing |
| 369 ** statements). | 372 ** statements). |
| 370 */ | 373 */ |
| 371 sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); | 374 sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); |
| 372 } | 375 } |
| 373 | 376 |
| 374 attach_end: | 377 attach_end: |
| 375 sqlite3ExprDelete(db, pFilename); | 378 sqlite3ExprDelete(db, pFilename); |
| 376 sqlite3ExprDelete(db, pDbname); | 379 sqlite3ExprDelete(db, pDbname); |
| 377 sqlite3ExprDelete(db, pKey); | 380 sqlite3ExprDelete(db, pKey); |
| 378 } | 381 } |
| 379 | 382 |
| 380 /* | 383 /* |
| 381 ** Called by the parser to compile a DETACH statement. | 384 ** Called by the parser to compile a DETACH statement. |
| 382 ** | 385 ** |
| 383 ** DETACH pDbname | 386 ** DETACH pDbname |
| 384 */ | 387 */ |
| 385 void sqlite3Detach(Parse *pParse, Expr *pDbname){ | 388 void sqlite3Detach(Parse *pParse, Expr *pDbname){ |
| 386 static const FuncDef detach_func = { | 389 static const FuncDef detach_func = { |
| 387 1, /* nArg */ | 390 1, /* nArg */ |
| 388 SQLITE_UTF8, /* funcFlags */ | 391 SQLITE_UTF8, /* funcFlags */ |
| 389 0, /* pUserData */ | 392 0, /* pUserData */ |
| 390 0, /* pNext */ | 393 0, /* pNext */ |
| 391 detachFunc, /* xFunc */ | 394 detachFunc, /* xSFunc */ |
| 392 0, /* xStep */ | |
| 393 0, /* xFinalize */ | 395 0, /* xFinalize */ |
| 394 "sqlite_detach", /* zName */ | 396 "sqlite_detach", /* zName */ |
| 395 0, /* pHash */ | 397 {0} |
| 396 0 /* pDestructor */ | |
| 397 }; | 398 }; |
| 398 codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname); | 399 codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname); |
| 399 } | 400 } |
| 400 | 401 |
| 401 /* | 402 /* |
| 402 ** Called by the parser to compile an ATTACH statement. | 403 ** Called by the parser to compile an ATTACH statement. |
| 403 ** | 404 ** |
| 404 ** ATTACH p AS pDbname KEY pKey | 405 ** ATTACH p AS pDbname KEY pKey |
| 405 */ | 406 */ |
| 406 void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ | 407 void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ |
| 407 static const FuncDef attach_func = { | 408 static const FuncDef attach_func = { |
| 408 3, /* nArg */ | 409 3, /* nArg */ |
| 409 SQLITE_UTF8, /* funcFlags */ | 410 SQLITE_UTF8, /* funcFlags */ |
| 410 0, /* pUserData */ | 411 0, /* pUserData */ |
| 411 0, /* pNext */ | 412 0, /* pNext */ |
| 412 attachFunc, /* xFunc */ | 413 attachFunc, /* xSFunc */ |
| 413 0, /* xStep */ | |
| 414 0, /* xFinalize */ | 414 0, /* xFinalize */ |
| 415 "sqlite_attach", /* zName */ | 415 "sqlite_attach", /* zName */ |
| 416 0, /* pHash */ | 416 {0} |
| 417 0 /* pDestructor */ | |
| 418 }; | 417 }; |
| 419 codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey); | 418 codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey); |
| 420 } | 419 } |
| 421 #endif /* SQLITE_OMIT_ATTACH */ | 420 #endif /* SQLITE_OMIT_ATTACH */ |
| 422 | 421 |
| 423 /* | 422 /* |
| 424 ** Initialize a DbFixer structure. This routine must be called prior | 423 ** Initialize a DbFixer structure. This routine must be called prior |
| 425 ** to passing the structure to one of the sqliteFixAAAA() routines below. | 424 ** to passing the structure to one of the sqliteFixAAAA() routines below. |
| 426 */ | 425 */ |
| 427 void sqlite3FixInit( | 426 void sqlite3FixInit( |
| 428 DbFixer *pFix, /* The fixer to be initialized */ | 427 DbFixer *pFix, /* The fixer to be initialized */ |
| 429 Parse *pParse, /* Error messages will be written here */ | 428 Parse *pParse, /* Error messages will be written here */ |
| 430 int iDb, /* This is the database that must be used */ | 429 int iDb, /* This is the database that must be used */ |
| 431 const char *zType, /* "view", "trigger", or "index" */ | 430 const char *zType, /* "view", "trigger", or "index" */ |
| 432 const Token *pName /* Name of the view, trigger, or index */ | 431 const Token *pName /* Name of the view, trigger, or index */ |
| 433 ){ | 432 ){ |
| 434 sqlite3 *db; | 433 sqlite3 *db; |
| 435 | 434 |
| 436 db = pParse->db; | 435 db = pParse->db; |
| 437 assert( db->nDb>iDb ); | 436 assert( db->nDb>iDb ); |
| 438 pFix->pParse = pParse; | 437 pFix->pParse = pParse; |
| 439 pFix->zDb = db->aDb[iDb].zName; | 438 pFix->zDb = db->aDb[iDb].zDbSName; |
| 440 pFix->pSchema = db->aDb[iDb].pSchema; | 439 pFix->pSchema = db->aDb[iDb].pSchema; |
| 441 pFix->zType = zType; | 440 pFix->zType = zType; |
| 442 pFix->pName = pName; | 441 pFix->pName = pName; |
| 443 pFix->bVarOnly = (iDb==1); | 442 pFix->bVarOnly = (iDb==1); |
| 444 } | 443 } |
| 445 | 444 |
| 446 /* | 445 /* |
| 447 ** The following set of routines walk through the parse tree and assign | 446 ** The following set of routines walk through the parse tree and assign |
| 448 ** a specific database to all table references where the database name | 447 ** a specific database to all table references where the database name |
| 449 ** was left unspecified in the original SQL statement. The pFix structure | 448 ** was left unspecified in the original SQL statement. The pFix structure |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 ){ | 525 ){ |
| 527 while( pExpr ){ | 526 while( pExpr ){ |
| 528 if( pExpr->op==TK_VARIABLE ){ | 527 if( pExpr->op==TK_VARIABLE ){ |
| 529 if( pFix->pParse->db->init.busy ){ | 528 if( pFix->pParse->db->init.busy ){ |
| 530 pExpr->op = TK_NULL; | 529 pExpr->op = TK_NULL; |
| 531 }else{ | 530 }else{ |
| 532 sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); | 531 sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); |
| 533 return 1; | 532 return 1; |
| 534 } | 533 } |
| 535 } | 534 } |
| 536 if( ExprHasProperty(pExpr, EP_TokenOnly) ) break; | 535 if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break; |
| 537 if( ExprHasProperty(pExpr, EP_xIsSelect) ){ | 536 if( ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 538 if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; | 537 if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; |
| 539 }else{ | 538 }else{ |
| 540 if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; | 539 if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; |
| 541 } | 540 } |
| 542 if( sqlite3FixExpr(pFix, pExpr->pRight) ){ | 541 if( sqlite3FixExpr(pFix, pExpr->pRight) ){ |
| 543 return 1; | 542 return 1; |
| 544 } | 543 } |
| 545 pExpr = pExpr->pLeft; | 544 pExpr = pExpr->pLeft; |
| 546 } | 545 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 575 return 1; | 574 return 1; |
| 576 } | 575 } |
| 577 if( sqlite3FixExprList(pFix, pStep->pExprList) ){ | 576 if( sqlite3FixExprList(pFix, pStep->pExprList) ){ |
| 578 return 1; | 577 return 1; |
| 579 } | 578 } |
| 580 pStep = pStep->pNext; | 579 pStep = pStep->pNext; |
| 581 } | 580 } |
| 582 return 0; | 581 return 0; |
| 583 } | 582 } |
| 584 #endif | 583 #endif |
| OLD | NEW |