| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/sqlite/src/src/attach.c |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | /* | - | ||||||||||||
| 2 | ** 2003 April 6 | - | ||||||||||||
| 3 | ** | - | ||||||||||||
| 4 | ** The author disclaims copyright to this source code. In place of | - | ||||||||||||
| 5 | ** a legal notice, here is a blessing: | - | ||||||||||||
| 6 | ** | - | ||||||||||||
| 7 | ** May you do good and not evil. | - | ||||||||||||
| 8 | ** May you find forgiveness for yourself and forgive others. | - | ||||||||||||
| 9 | ** May you share freely, never taking more than you give. | - | ||||||||||||
| 10 | ** | - | ||||||||||||
| 11 | ************************************************************************* | - | ||||||||||||
| 12 | ** This file contains code used to implement the ATTACH and DETACH commands. | - | ||||||||||||
| 13 | */ | - | ||||||||||||
| 14 | #include "sqliteInt.h" | - | ||||||||||||
| 15 | - | |||||||||||||
| 16 | #ifndef SQLITE_OMIT_ATTACH | - | ||||||||||||
| 17 | /* | - | ||||||||||||
| 18 | ** Resolve an expression that was part of an ATTACH or DETACH statement. This | - | ||||||||||||
| 19 | ** is slightly different from resolving a normal SQL expression, because simple | - | ||||||||||||
| 20 | ** identifiers are treated as strings, not possible column names or aliases. | - | ||||||||||||
| 21 | ** | - | ||||||||||||
| 22 | ** i.e. if the parser sees: | - | ||||||||||||
| 23 | ** | - | ||||||||||||
| 24 | ** ATTACH DATABASE abc AS def | - | ||||||||||||
| 25 | ** | - | ||||||||||||
| 26 | ** it treats the two expressions as literal strings 'abc' and 'def' instead of | - | ||||||||||||
| 27 | ** looking for columns of the same name. | - | ||||||||||||
| 28 | ** | - | ||||||||||||
| 29 | ** This only applies to the root node of pExpr, so the statement: | - | ||||||||||||
| 30 | ** | - | ||||||||||||
| 31 | ** ATTACH DATABASE abc||def AS 'db2' | - | ||||||||||||
| 32 | ** | - | ||||||||||||
| 33 | ** will fail because neither abc or def can be resolved. | - | ||||||||||||
| 34 | */ | - | ||||||||||||
| 35 | static int resolveAttachExpr(NameContext *pName, Expr *pExpr) | - | ||||||||||||
| 36 | { | - | ||||||||||||
| 37 | int rc = SQLITE_OK; | - | ||||||||||||
| 38 | if( pExpr ){
| 1978-3458 | ||||||||||||
| 39 | if( pExpr->op!=TK_ID ){
| 1669-1789 | ||||||||||||
| 40 | rc = sqlite3ResolveExprNames(pName, pExpr); | - | ||||||||||||
| 41 | }else{ executed 1669 times by 12 tests: end of blockExecuted by:
| 1669 | ||||||||||||
| 42 | pExpr->op = TK_STRING; | - | ||||||||||||
| 43 | } executed 1789 times by 12 tests: end of blockExecuted by:
| 1789 | ||||||||||||
| 44 | } | - | ||||||||||||
| 45 | return rc; executed 5436 times by 12 tests: return rc;Executed by:
| 5436 | ||||||||||||
| 46 | } | - | ||||||||||||
| 47 | - | |||||||||||||
| 48 | /* | - | ||||||||||||
| 49 | ** An SQL user-function registered to do the work of an ATTACH statement. The | - | ||||||||||||
| 50 | ** three arguments to the function come directly from an attach statement: | - | ||||||||||||
| 51 | ** | - | ||||||||||||
| 52 | ** ATTACH DATABASE x AS y KEY z | - | ||||||||||||
| 53 | ** | - | ||||||||||||
| 54 | ** SELECT sqlite_attach(x, y, z) | - | ||||||||||||
| 55 | ** | - | ||||||||||||
| 56 | ** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the | - | ||||||||||||
| 57 | ** third argument. | - | ||||||||||||
| 58 | ** | - | ||||||||||||
| 59 | ** If the db->init.reopenMemdb flags is set, then instead of attaching a | - | ||||||||||||
| 60 | ** new database, close the database on db->init.iDb and reopen it as an | - | ||||||||||||
| 61 | ** empty MemDB. | - | ||||||||||||
| 62 | */ | - | ||||||||||||
| 63 | static void attachFunc( | - | ||||||||||||
| 64 | sqlite3_context *context, | - | ||||||||||||
| 65 | int NotUsed, | - | ||||||||||||
| 66 | sqlite3_value **argv | - | ||||||||||||
| 67 | ){ | - | ||||||||||||
| 68 | int i; | - | ||||||||||||
| 69 | int rc = 0; | - | ||||||||||||
| 70 | sqlite3 *db = sqlite3_context_db_handle(context); | - | ||||||||||||
| 71 | const char *zName; | - | ||||||||||||
| 72 | const char *zFile; | - | ||||||||||||
| 73 | char *zPath = 0; | - | ||||||||||||
| 74 | char *zErr = 0; | - | ||||||||||||
| 75 | unsigned int flags; | - | ||||||||||||
| 76 | Db *aNew; /* New array of Db pointers */ | - | ||||||||||||
| 77 | Db *pNew; /* Db object for the newly attached database */ | - | ||||||||||||
| 78 | char *zErrDyn = 0; | - | ||||||||||||
| 79 | sqlite3_vfs *pVfs; | - | ||||||||||||
| 80 | - | |||||||||||||
| 81 | UNUSED_PARAMETER(NotUsed); | - | ||||||||||||
| 82 | zFile = (const char *)sqlite3_value_text(argv[0]); | - | ||||||||||||
| 83 | zName = (const char *)sqlite3_value_text(argv[1]); | - | ||||||||||||
| 84 | if( zFile==0 ) zFile = ""; executed 2 times by 1 test: zFile = "";Executed by:
| 2-1642 | ||||||||||||
| 85 | if( zName==0 ) zName = ""; executed 4 times by 1 test: zName = "";Executed by:
| 4-1640 | ||||||||||||
| 86 | - | |||||||||||||
| 87 | #ifdef SQLITE_ENABLE_DESERIALIZE | - | ||||||||||||
| 88 | # define REOPEN_AS_MEMDB(db) (db->init.reopenMemdb) | - | ||||||||||||
| 89 | #else | - | ||||||||||||
| 90 | # define REOPEN_AS_MEMDB(db) (0) | - | ||||||||||||
| 91 | #endif | - | ||||||||||||
| 92 | - | |||||||||||||
| 93 | if( REOPEN_AS_MEMDB(db) ){
dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 94 | /* This is not a real ATTACH. Instead, this routine is being called dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 95 | ** from sqlite3_deserialize() to close database db->init.iDb and dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 96 | ** reopen it as a MemDB */ dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 97 | pVfs = sqlite3_vfs_find("memdb"); dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 98 | if( pVfs==0 ) return; dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 99 | pNew = &db->aDb[db->init.iDb]; dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 100 | if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 101 | pNew->pBt = 0; dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 102 | pNew->pSchema = 0; dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 103 | rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB); dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 104 | }else{ dead code: { pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, 0x00000100); } | - | ||||||||||||
| 105 | /* This is a real ATTACH | - | ||||||||||||
| 106 | ** | - | ||||||||||||
| 107 | ** Check for the following errors: | - | ||||||||||||
| 108 | ** | - | ||||||||||||
| 109 | ** * Too many attached databases, | - | ||||||||||||
| 110 | ** * Transaction currently open | - | ||||||||||||
| 111 | ** * Specified database name already being used. | - | ||||||||||||
| 112 | */ | - | ||||||||||||
| 113 | if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
| 3-1641 | ||||||||||||
| 114 | zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", | - | ||||||||||||
| 115 | db->aLimit[SQLITE_LIMIT_ATTACHED] | - | ||||||||||||
| 116 | ); | - | ||||||||||||
| 117 | goto attach_error; executed 3 times by 1 test: goto attach_error;Executed by:
| 3 | ||||||||||||
| 118 | } | - | ||||||||||||
| 119 | for(i=0; i<db->nDb; i++){
| 1633-3503 | ||||||||||||
| 120 | char *z = db->aDb[i].zDbSName; | - | ||||||||||||
| 121 | assert( z && zName ); | - | ||||||||||||
| 122 | if( sqlite3StrICmp(z, zName)==0 ){
| 8-3495 | ||||||||||||
| 123 | zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); | - | ||||||||||||
| 124 | goto attach_error; executed 8 times by 1 test: goto attach_error;Executed by:
| 8 | ||||||||||||
| 125 | } | - | ||||||||||||
| 126 | } executed 3495 times by 12 tests: end of blockExecuted by:
| 3495 | ||||||||||||
| 127 | - | |||||||||||||
| 128 | /* Allocate the new entry in the db->aDb[] array and initialize the schema | - | ||||||||||||
| 129 | ** hash tables. | - | ||||||||||||
| 130 | */ | - | ||||||||||||
| 131 | if( db->aDb==db->aDbStatic ){
| 96-1537 | ||||||||||||
| 132 | aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); | - | ||||||||||||
| 133 | if( aNew==0 ) return; never executed: return;
| 0-1537 | ||||||||||||
| 134 | memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); | - | ||||||||||||
| 135 | }else{ executed 1537 times by 12 tests: end of blockExecuted by:
| 1537 | ||||||||||||
| 136 | aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); | - | ||||||||||||
| 137 | if( aNew==0 ) return; never executed: return;
| 0-96 | ||||||||||||
| 138 | } executed 96 times by 1 test: end of blockExecuted by:
| 96 | ||||||||||||
| 139 | db->aDb = aNew; | - | ||||||||||||
| 140 | pNew = &db->aDb[db->nDb]; | - | ||||||||||||
| 141 | memset(pNew, 0, sizeof(*pNew)); | - | ||||||||||||
| 142 | - | |||||||||||||
| 143 | /* Open the database file. If the btree is successfully opened, use | - | ||||||||||||
| 144 | ** it to obtain the database schema. At this point the schema may | - | ||||||||||||
| 145 | ** or may not be initialized. | - | ||||||||||||
| 146 | */ | - | ||||||||||||
| 147 | flags = db->openFlags; | - | ||||||||||||
| 148 | rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); | - | ||||||||||||
| 149 | if( rc!=SQLITE_OK ){
| 0-1633 | ||||||||||||
| 150 | if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); never executed: sqlite3OomFault(db);
| 0 | ||||||||||||
| 151 | sqlite3_result_error(context, zErr, -1); | - | ||||||||||||
| 152 | sqlite3_free(zErr); | - | ||||||||||||
| 153 | return; never executed: return; | 0 | ||||||||||||
| 154 | } | - | ||||||||||||
| 155 | assert( pVfs ); | - | ||||||||||||
| 156 | flags |= SQLITE_OPEN_MAIN_DB; | - | ||||||||||||
| 157 | rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags); | - | ||||||||||||
| 158 | sqlite3_free( zPath ); | - | ||||||||||||
| 159 | db->nDb++; | - | ||||||||||||
| 160 | } executed 1633 times by 12 tests: end of blockExecuted by:
| 1633 | ||||||||||||
| 161 | db->noSharedCache = 0; | - | ||||||||||||
| 162 | if( rc==SQLITE_CONSTRAINT ){
| 3-1630 | ||||||||||||
| 163 | rc = SQLITE_ERROR; | - | ||||||||||||
| 164 | zErrDyn = sqlite3MPrintf(db, "database is already attached"); | - | ||||||||||||
| 165 | }else if( rc==SQLITE_OK ){ executed 3 times by 1 test: end of blockExecuted by:
| 2-1628 | ||||||||||||
| 166 | Pager *pPager; | - | ||||||||||||
| 167 | pNew->pSchema = sqlite3SchemaGet(db, pNew->pBt); | - | ||||||||||||
| 168 | if( !pNew->pSchema ){
| 0-1628 | ||||||||||||
| 169 | rc = SQLITE_NOMEM_BKPT; | - | ||||||||||||
| 170 | }else if( pNew->pSchema->file_format && pNew->pSchema->enc!=ENC(db) ){ never executed: end of block
| 0-1603 | ||||||||||||
| 171 | zErrDyn = sqlite3MPrintf(db, | - | ||||||||||||
| 172 | "attached databases must use the same text encoding as main database"); | - | ||||||||||||
| 173 | rc = SQLITE_ERROR; | - | ||||||||||||
| 174 | } executed 1 time by 1 test: end of blockExecuted by:
| 1 | ||||||||||||
| 175 | sqlite3BtreeEnter(pNew->pBt); | - | ||||||||||||
| 176 | pPager = sqlite3BtreePager(pNew->pBt); | - | ||||||||||||
| 177 | sqlite3PagerLockingMode(pPager, db->dfltLockMode); | - | ||||||||||||
| 178 | sqlite3BtreeSecureDelete(pNew->pBt, | - | ||||||||||||
| 179 | sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); | - | ||||||||||||
| 180 | #ifndef SQLITE_OMIT_PAGER_PRAGMAS | - | ||||||||||||
| 181 | sqlite3BtreeSetPagerFlags(pNew->pBt, | - | ||||||||||||
| 182 | PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK)); | - | ||||||||||||
| 183 | #endif | - | ||||||||||||
| 184 | sqlite3BtreeLeave(pNew->pBt); | - | ||||||||||||
| 185 | } executed 1628 times by 12 tests: end of blockExecuted by:
| 1628 | ||||||||||||
| 186 | pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; | - | ||||||||||||
| 187 | if( !REOPEN_AS_MEMDB(db) ) pNew->zDbSName = sqlite3DbStrDup(db, zName); executed 1633 times by 12 tests: pNew->zDbSName = sqlite3DbStrDup(db, zName);Executed by:
| 0-1633 | ||||||||||||
| 188 | if( rc==SQLITE_OK && pNew->zDbSName==0 ){
| 0-1627 | ||||||||||||
| 189 | rc = SQLITE_NOMEM_BKPT; | - | ||||||||||||
| 190 | } never executed: end of block | 0 | ||||||||||||
| 191 | - | |||||||||||||
| 192 | - | |||||||||||||
| 193 | #ifdef SQLITE_HAS_CODEC | - | ||||||||||||
| 194 | if( rc==SQLITE_OK ){ | - | ||||||||||||
| 195 | extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); | - | ||||||||||||
| 196 | extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); | - | ||||||||||||
| 197 | int nKey; | - | ||||||||||||
| 198 | char *zKey; | - | ||||||||||||
| 199 | int t = sqlite3_value_type(argv[2]); | - | ||||||||||||
| 200 | switch( t ){ | - | ||||||||||||
| 201 | case SQLITE_INTEGER: | - | ||||||||||||
| 202 | case SQLITE_FLOAT: | - | ||||||||||||
| 203 | zErrDyn = sqlite3DbStrDup(db, "Invalid key value"); | - | ||||||||||||
| 204 | rc = SQLITE_ERROR; | - | ||||||||||||
| 205 | break; | - | ||||||||||||
| 206 | - | |||||||||||||
| 207 | case SQLITE_TEXT: | - | ||||||||||||
| 208 | case SQLITE_BLOB: | - | ||||||||||||
| 209 | nKey = sqlite3_value_bytes(argv[2]); | - | ||||||||||||
| 210 | zKey = (char *)sqlite3_value_blob(argv[2]); | - | ||||||||||||
| 211 | rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); | - | ||||||||||||
| 212 | break; | - | ||||||||||||
| 213 | - | |||||||||||||
| 214 | case SQLITE_NULL: | - | ||||||||||||
| 215 | /* No key specified. Use the key from the main database */ | - | ||||||||||||
| 216 | sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); | - | ||||||||||||
| 217 | if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ | - | ||||||||||||
| 218 | rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); | - | ||||||||||||
| 219 | } | - | ||||||||||||
| 220 | break; | - | ||||||||||||
| 221 | } | - | ||||||||||||
| 222 | } | - | ||||||||||||
| 223 | #endif | - | ||||||||||||
| 224 | - | |||||||||||||
| 225 | /* If the file was opened successfully, read the schema for the new database. | - | ||||||||||||
| 226 | ** If this fails, or if opening the file failed, then close the file and | - | ||||||||||||
| 227 | ** remove the entry from the db->aDb[] array. i.e. put everything back the | - | ||||||||||||
| 228 | ** way we found it. | - | ||||||||||||
| 229 | */ | - | ||||||||||||
| 230 | if( rc==SQLITE_OK ){
| 6-1627 | ||||||||||||
| 231 | sqlite3BtreeEnterAll(db); | - | ||||||||||||
| 232 | db->init.iDb = 0; | - | ||||||||||||
| 233 | db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); | - | ||||||||||||
| 234 | rc = sqlite3Init(db, &zErrDyn); | - | ||||||||||||
| 235 | sqlite3BtreeLeaveAll(db); | - | ||||||||||||
| 236 | assert( zErrDyn==0 || rc!=SQLITE_OK ); | - | ||||||||||||
| 237 | } executed 1627 times by 12 tests: end of blockExecuted by:
| 1627 | ||||||||||||
| 238 | #ifdef SQLITE_USER_AUTHENTICATION | - | ||||||||||||
| 239 | if( rc==SQLITE_OK ){ | - | ||||||||||||
| 240 | u8 newAuth = 0; | - | ||||||||||||
| 241 | rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); | - | ||||||||||||
| 242 | if( newAuth<db->auth.authLevel ){ | - | ||||||||||||
| 243 | rc = SQLITE_AUTH_USER; | - | ||||||||||||
| 244 | } | - | ||||||||||||
| 245 | } | - | ||||||||||||
| 246 | #endif | - | ||||||||||||
| 247 | if( rc ){
| 9-1624 | ||||||||||||
| 248 | if( !REOPEN_AS_MEMDB(db) ){
| 0-9 | ||||||||||||
| 249 | int iDb = db->nDb - 1; | - | ||||||||||||
| 250 | assert( iDb>=2 ); | - | ||||||||||||
| 251 | if( db->aDb[iDb].pBt ){
| 4-5 | ||||||||||||
| 252 | sqlite3BtreeClose(db->aDb[iDb].pBt); | - | ||||||||||||
| 253 | db->aDb[iDb].pBt = 0; | - | ||||||||||||
| 254 | db->aDb[iDb].pSchema = 0; | - | ||||||||||||
| 255 | } executed 4 times by 1 test: end of blockExecuted by:
| 4 | ||||||||||||
| 256 | sqlite3ResetAllSchemasOfConnection(db); | - | ||||||||||||
| 257 | db->nDb = iDb; | - | ||||||||||||
| 258 | if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
| 0-9 | ||||||||||||
| 259 | sqlite3OomFault(db); | - | ||||||||||||
| 260 | sqlite3DbFree(db, zErrDyn); | - | ||||||||||||
| 261 | zErrDyn = sqlite3MPrintf(db, "out of memory"); | - | ||||||||||||
| 262 | }else if( zErrDyn==0 ){ never executed: end of block
| 0-7 | ||||||||||||
| 263 | zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); | - | ||||||||||||
| 264 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||
| 265 | } executed 9 times by 1 test: end of blockExecuted by:
| 9 | ||||||||||||
| 266 | goto attach_error; executed 9 times by 1 test: goto attach_error;Executed by:
| 9 | ||||||||||||
| 267 | } | - | ||||||||||||
| 268 | - | |||||||||||||
| 269 | return; executed 1624 times by 12 tests: return;Executed by:
| 1624 | ||||||||||||
| 270 | - | |||||||||||||
| 271 | attach_error: | - | ||||||||||||
| 272 | /* Return an error if we get here */ | - | ||||||||||||
| 273 | if( zErrDyn ){
| 0-20 | ||||||||||||
| 274 | sqlite3_result_error(context, zErrDyn, -1); | - | ||||||||||||
| 275 | sqlite3DbFree(db, zErrDyn); | - | ||||||||||||
| 276 | } executed 20 times by 1 test: end of blockExecuted by:
| 20 | ||||||||||||
| 277 | if( rc ) sqlite3_result_error_code(context, rc); executed 9 times by 1 test: sqlite3_result_error_code(context, rc);Executed by:
| 9-11 | ||||||||||||
| 278 | } executed 20 times by 1 test: end of blockExecuted by:
| 20 | ||||||||||||
| 279 | - | |||||||||||||
| 280 | /* | - | ||||||||||||
| 281 | ** An SQL user-function registered to do the work of an DETACH statement. The | - | ||||||||||||
| 282 | ** three arguments to the function come directly from a detach statement: | - | ||||||||||||
| 283 | ** | - | ||||||||||||
| 284 | ** DETACH DATABASE x | - | ||||||||||||
| 285 | ** | - | ||||||||||||
| 286 | ** SELECT sqlite_detach(x) | - | ||||||||||||
| 287 | */ | - | ||||||||||||
| 288 | static void detachFunc( | - | ||||||||||||
| 289 | sqlite3_context *context, | - | ||||||||||||
| 290 | int NotUsed, | - | ||||||||||||
| 291 | sqlite3_value **argv | - | ||||||||||||
| 292 | ){ | - | ||||||||||||
| 293 | const char *zName = (const char *)sqlite3_value_text(argv[0]); | - | ||||||||||||
| 294 | sqlite3 *db = sqlite3_context_db_handle(context); | - | ||||||||||||
| 295 | int i; | - | ||||||||||||
| 296 | Db *pDb = 0; | - | ||||||||||||
| 297 | char zErr[128]; | - | ||||||||||||
| 298 | - | |||||||||||||
| 299 | UNUSED_PARAMETER(NotUsed); | - | ||||||||||||
| 300 | - | |||||||||||||
| 301 | if( zName==0 ) zName = ""; executed 3 times by 1 test: zName = "";Executed by:
| 3-158 | ||||||||||||
| 302 | for(i=0; i<db->nDb; i++){
| 4-546 | ||||||||||||
| 303 | pDb = &db->aDb[i]; | - | ||||||||||||
| 304 | if( pDb->pBt==0 ) continue; executed 117 times by 1 test: continue;Executed by:
| 117-429 | ||||||||||||
| 305 | if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break; executed 157 times by 1 test: break;Executed by:
| 157-272 | ||||||||||||
| 306 | } executed 272 times by 1 test: end of blockExecuted by:
| 272 | ||||||||||||
| 307 | - | |||||||||||||
| 308 | if( i>=db->nDb ){
| 4-157 | ||||||||||||
| 309 | sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); | - | ||||||||||||
| 310 | goto detach_error; executed 4 times by 1 test: goto detach_error;Executed by:
| 4 | ||||||||||||
| 311 | } | - | ||||||||||||
| 312 | if( i<2 ){
| 2-155 | ||||||||||||
| 313 | sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); | - | ||||||||||||
| 314 | goto detach_error; executed 2 times by 1 test: goto detach_error;Executed by:
| 2 | ||||||||||||
| 315 | } | - | ||||||||||||
| 316 | if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
| 0-154 | ||||||||||||
| 317 | sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); | - | ||||||||||||
| 318 | goto detach_error; executed 1 time by 1 test: goto detach_error;Executed by:
| 1 | ||||||||||||
| 319 | } | - | ||||||||||||
| 320 | - | |||||||||||||
| 321 | sqlite3BtreeClose(pDb->pBt); | - | ||||||||||||
| 322 | pDb->pBt = 0; | - | ||||||||||||
| 323 | pDb->pSchema = 0; | - | ||||||||||||
| 324 | sqlite3CollapseDatabaseArray(db); | - | ||||||||||||
| 325 | return; executed 154 times by 1 test: return;Executed by:
| 154 | ||||||||||||
| 326 | - | |||||||||||||
| 327 | detach_error: | - | ||||||||||||
| 328 | sqlite3_result_error(context, zErr, -1); | - | ||||||||||||
| 329 | } executed 7 times by 1 test: end of blockExecuted by:
| 7 | ||||||||||||
| 330 | - | |||||||||||||
| 331 | /* | - | ||||||||||||
| 332 | ** This procedure generates VDBE code for a single invocation of either the | - | ||||||||||||
| 333 | ** sqlite_detach() or sqlite_attach() SQL user functions. | - | ||||||||||||
| 334 | */ | - | ||||||||||||
| 335 | static void codeAttach( | - | ||||||||||||
| 336 | Parse *pParse, /* The parser context */ | - | ||||||||||||
| 337 | int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */ | - | ||||||||||||
| 338 | FuncDef const *pFunc,/* FuncDef wrapper for detachFunc() or attachFunc() */ | - | ||||||||||||
| 339 | Expr *pAuthArg, /* Expression to pass to authorization callback */ | - | ||||||||||||
| 340 | Expr *pFilename, /* Name of database file */ | - | ||||||||||||
| 341 | Expr *pDbname, /* Name of the database to use internally */ | - | ||||||||||||
| 342 | Expr *pKey /* Database key for encryption extension */ | - | ||||||||||||
| 343 | ){ | - | ||||||||||||
| 344 | int rc; | - | ||||||||||||
| 345 | NameContext sName; | - | ||||||||||||
| 346 | Vdbe *v; | - | ||||||||||||
| 347 | sqlite3* db = pParse->db; | - | ||||||||||||
| 348 | int regArgs; | - | ||||||||||||
| 349 | - | |||||||||||||
| 350 | if( pParse->nErr ) goto attach_end; executed 1 time by 1 test: goto attach_end;Executed by:
| 1-1812 | ||||||||||||
| 351 | memset(&sName, 0, sizeof(NameContext)); | - | ||||||||||||
| 352 | sName.pParse = pParse; | - | ||||||||||||
| 353 | - | |||||||||||||
| 354 | if( | - | ||||||||||||
| 355 | SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
| 0-1812 | ||||||||||||
| 356 | SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
| 0-1812 | ||||||||||||
| 357 | SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
| 2-1810 | ||||||||||||
| 358 | ){ | - | ||||||||||||
| 359 | goto attach_end; executed 2 times by 1 test: goto attach_end;Executed by:
| 2 | ||||||||||||
| 360 | } | - | ||||||||||||
| 361 | - | |||||||||||||
| 362 | #ifndef SQLITE_OMIT_AUTHORIZATION | - | ||||||||||||
| 363 | if( pAuthArg ){
| 0-1810 | ||||||||||||
| 364 | char *zAuthArg; | - | ||||||||||||
| 365 | if( pAuthArg->op==TK_STRING ){
| 40-1770 | ||||||||||||
| 366 | zAuthArg = pAuthArg->u.zToken; | - | ||||||||||||
| 367 | }else{ executed 1770 times by 12 tests: end of blockExecuted by:
| 1770 | ||||||||||||
| 368 | zAuthArg = 0; | - | ||||||||||||
| 369 | } executed 40 times by 1 test: end of blockExecuted by:
| 40 | ||||||||||||
| 370 | rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); | - | ||||||||||||
| 371 | if(rc!=SQLITE_OK ){
| 4-1806 | ||||||||||||
| 372 | goto attach_end; executed 4 times by 1 test: goto attach_end;Executed by:
| 4 | ||||||||||||
| 373 | } | - | ||||||||||||
| 374 | } executed 1806 times by 12 tests: end of blockExecuted by:
| 1806 | ||||||||||||
| 375 | #endif /* SQLITE_OMIT_AUTHORIZATION */ | - | ||||||||||||
| 376 | - | |||||||||||||
| 377 | - | |||||||||||||
| 378 | v = sqlite3GetVdbe(pParse); | - | ||||||||||||
| 379 | regArgs = sqlite3GetTempRange(pParse, 4); | - | ||||||||||||
| 380 | sqlite3ExprCode(pParse, pFilename, regArgs); | - | ||||||||||||
| 381 | sqlite3ExprCode(pParse, pDbname, regArgs+1); | - | ||||||||||||
| 382 | sqlite3ExprCode(pParse, pKey, regArgs+2); | - | ||||||||||||
| 383 | - | |||||||||||||
| 384 | assert( v || db->mallocFailed ); | - | ||||||||||||
| 385 | if( v ){
| 0-1806 | ||||||||||||
| 386 | sqlite3VdbeAddOp4(v, OP_Function0, 0, regArgs+3-pFunc->nArg, regArgs+3, | - | ||||||||||||
| 387 | (char *)pFunc, P4_FUNCDEF); | - | ||||||||||||
| 388 | assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg ); | - | ||||||||||||
| 389 | sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); | - | ||||||||||||
| 390 | - | |||||||||||||
| 391 | /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this | - | ||||||||||||
| 392 | ** statement only). For DETACH, set it to false (expire all existing | - | ||||||||||||
| 393 | ** statements). | - | ||||||||||||
| 394 | */ | - | ||||||||||||
| 395 | sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); | - | ||||||||||||
| 396 | } executed 1806 times by 12 tests: end of blockExecuted by:
| 1806 | ||||||||||||
| 397 | - | |||||||||||||
| 398 | attach_end: code before this statement executed 1806 times by 12 tests: attach_end:Executed by:
| 1806 | ||||||||||||
| 399 | sqlite3ExprDelete(db, pFilename); | - | ||||||||||||
| 400 | sqlite3ExprDelete(db, pDbname); | - | ||||||||||||
| 401 | sqlite3ExprDelete(db, pKey); | - | ||||||||||||
| 402 | } executed 1813 times by 12 tests: end of blockExecuted by:
| 1813 | ||||||||||||
| 403 | - | |||||||||||||
| 404 | /* | - | ||||||||||||
| 405 | ** Called by the parser to compile a DETACH statement. | - | ||||||||||||
| 406 | ** | - | ||||||||||||
| 407 | ** DETACH pDbname | - | ||||||||||||
| 408 | */ | - | ||||||||||||
| 409 | void sqlite3Detach(Parse *pParse, Expr *pDbname){ | - | ||||||||||||
| 410 | static const FuncDef detach_func = { | - | ||||||||||||
| 411 | 1, /* nArg */ | - | ||||||||||||
| 412 | SQLITE_UTF8, /* funcFlags */ | - | ||||||||||||
| 413 | 0, /* pUserData */ | - | ||||||||||||
| 414 | 0, /* pNext */ | - | ||||||||||||
| 415 | detachFunc, /* xSFunc */ | - | ||||||||||||
| 416 | 0, /* xFinalize */ | - | ||||||||||||
| 417 | 0, 0, /* xValue, xInverse */ | - | ||||||||||||
| 418 | "sqlite_detach", /* zName */ | - | ||||||||||||
| 419 | {0} | - | ||||||||||||
| 420 | }; | - | ||||||||||||
| 421 | codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname); | - | ||||||||||||
| 422 | } executed 167 times by 1 test: end of blockExecuted by:
| 167 | ||||||||||||
| 423 | - | |||||||||||||
| 424 | /* | - | ||||||||||||
| 425 | ** Called by the parser to compile an ATTACH statement. | - | ||||||||||||
| 426 | ** | - | ||||||||||||
| 427 | ** ATTACH p AS pDbname KEY pKey | - | ||||||||||||
| 428 | */ | - | ||||||||||||
| 429 | void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ | - | ||||||||||||
| 430 | static const FuncDef attach_func = { | - | ||||||||||||
| 431 | 3, /* nArg */ | - | ||||||||||||
| 432 | SQLITE_UTF8, /* funcFlags */ | - | ||||||||||||
| 433 | 0, /* pUserData */ | - | ||||||||||||
| 434 | 0, /* pNext */ | - | ||||||||||||
| 435 | attachFunc, /* xSFunc */ | - | ||||||||||||
| 436 | 0, /* xFinalize */ | - | ||||||||||||
| 437 | 0, 0, /* xValue, xInverse */ | - | ||||||||||||
| 438 | "sqlite_attach", /* zName */ | - | ||||||||||||
| 439 | {0} | - | ||||||||||||
| 440 | }; | - | ||||||||||||
| 441 | codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey); | - | ||||||||||||
| 442 | } executed 1646 times by 12 tests: end of blockExecuted by:
| 1646 | ||||||||||||
| 443 | #endif /* SQLITE_OMIT_ATTACH */ | - | ||||||||||||
| 444 | - | |||||||||||||
| 445 | /* | - | ||||||||||||
| 446 | ** Initialize a DbFixer structure. This routine must be called prior | - | ||||||||||||
| 447 | ** to passing the structure to one of the sqliteFixAAAA() routines below. | - | ||||||||||||
| 448 | */ | - | ||||||||||||
| 449 | void sqlite3FixInit( | - | ||||||||||||
| 450 | DbFixer *pFix, /* The fixer to be initialized */ | - | ||||||||||||
| 451 | Parse *pParse, /* Error messages will be written here */ | - | ||||||||||||
| 452 | int iDb, /* This is the database that must be used */ | - | ||||||||||||
| 453 | const char *zType, /* "view", "trigger", or "index" */ | - | ||||||||||||
| 454 | const Token *pName /* Name of the view, trigger, or index */ | - | ||||||||||||
| 455 | ){ | - | ||||||||||||
| 456 | sqlite3 *db; | - | ||||||||||||
| 457 | - | |||||||||||||
| 458 | db = pParse->db; | - | ||||||||||||
| 459 | assert( db->nDb>iDb ); | - | ||||||||||||
| 460 | pFix->pParse = pParse; | - | ||||||||||||
| 461 | pFix->zDb = db->aDb[iDb].zDbSName; | - | ||||||||||||
| 462 | pFix->pSchema = db->aDb[iDb].pSchema; | - | ||||||||||||
| 463 | pFix->zType = zType; | - | ||||||||||||
| 464 | pFix->pName = pName; | - | ||||||||||||
| 465 | pFix->bVarOnly = (iDb==1); | - | ||||||||||||
| 466 | } executed 29911 times by 24 tests: end of blockExecuted by:
| 29911 | ||||||||||||
| 467 | - | |||||||||||||
| 468 | /* | - | ||||||||||||
| 469 | ** The following set of routines walk through the parse tree and assign | - | ||||||||||||
| 470 | ** a specific database to all table references where the database name | - | ||||||||||||
| 471 | ** was left unspecified in the original SQL statement. The pFix structure | - | ||||||||||||
| 472 | ** must have been initialized by a prior call to sqlite3FixInit(). | - | ||||||||||||
| 473 | ** | - | ||||||||||||
| 474 | ** These routines are used to make sure that an index, trigger, or | - | ||||||||||||
| 475 | ** view in one database does not refer to objects in a different database. | - | ||||||||||||
| 476 | ** (Exception: indices, triggers, and views in the TEMP database are | - | ||||||||||||
| 477 | ** allowed to refer to anything.) If a reference is explicitly made | - | ||||||||||||
| 478 | ** to an object in a different database, an error message is added to | - | ||||||||||||
| 479 | ** pParse->zErrMsg and these routines return non-zero. If everything | - | ||||||||||||
| 480 | ** checks out, these routines return 0. | - | ||||||||||||
| 481 | */ | - | ||||||||||||
| 482 | int sqlite3FixSrcList( | - | ||||||||||||
| 483 | DbFixer *pFix, /* Context of the fixation */ | - | ||||||||||||
| 484 | SrcList *pList /* The Source list to check and modify */ | - | ||||||||||||
| 485 | ){ | - | ||||||||||||
| 486 | int i; | - | ||||||||||||
| 487 | const char *zDb; | - | ||||||||||||
| 488 | struct SrcList_item *pItem; | - | ||||||||||||
| 489 | - | |||||||||||||
| 490 | if( NEVER(pList==0) ) return 0; never executed: return 0;
| 0-33186 | ||||||||||||
| 491 | zDb = pFix->zDb; | - | ||||||||||||
| 492 | for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
| 23763-33166 | ||||||||||||
| 493 | if( pFix->bVarOnly==0 ){
| 1177-22586 | ||||||||||||
| 494 | if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
| 14-22556 | ||||||||||||
| 495 | sqlite3ErrorMsg(pFix->pParse, | - | ||||||||||||
| 496 | "%s %T cannot reference objects in database %s", | - | ||||||||||||
| 497 | pFix->zType, pFix->pName, pItem->zDatabase); | - | ||||||||||||
| 498 | return 1; executed 14 times by 1 test: return 1;Executed by:
| 14 | ||||||||||||
| 499 | } | - | ||||||||||||
| 500 | sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); | - | ||||||||||||
| 501 | pItem->zDatabase = 0; | - | ||||||||||||
| 502 | pItem->pSchema = pFix->pSchema; | - | ||||||||||||
| 503 | } executed 22572 times by 24 tests: end of blockExecuted by:
| 22572 | ||||||||||||
| 504 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) | - | ||||||||||||
| 505 | if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; executed 4 times by 1 test: return 1;Executed by:
| 4-23745 | ||||||||||||
| 506 | if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; never executed: return 1;
| 0-23745 | ||||||||||||
| 507 | #endif | - | ||||||||||||
| 508 | if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){
| 2-23741 | ||||||||||||
| 509 | return 1; executed 2 times by 1 test: return 1;Executed by:
| 2 | ||||||||||||
| 510 | } | - | ||||||||||||
| 511 | } executed 23743 times by 24 tests: end of blockExecuted by:
| 23743 | ||||||||||||
| 512 | return 0; executed 33166 times by 24 tests: return 0;Executed by:
| 33166 | ||||||||||||
| 513 | } | - | ||||||||||||
| 514 | #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) | - | ||||||||||||
| 515 | int sqlite3FixSelect( | - | ||||||||||||
| 516 | DbFixer *pFix, /* Context of the fixation */ | - | ||||||||||||
| 517 | Select *pSelect /* The SELECT statement to be fixed to one database */ | - | ||||||||||||
| 518 | ){ | - | ||||||||||||
| 519 | while( pSelect ){
| 17089-39921 | ||||||||||||
| 520 | if( sqlite3FixExprList(pFix, pSelect->pEList) ){
| 8-17081 | ||||||||||||
| 521 | return 1; executed 8 times by 1 test: return 1;Executed by:
| 8 | ||||||||||||
| 522 | } | - | ||||||||||||
| 523 | if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
| 18-17063 | ||||||||||||
| 524 | return 1; executed 18 times by 1 test: return 1;Executed by:
| 18 | ||||||||||||
| 525 | } | - | ||||||||||||
| 526 | if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
| 1-17062 | ||||||||||||
| 527 | return 1; executed 1 time by 1 test: return 1;Executed by:
| 1 | ||||||||||||
| 528 | } | - | ||||||||||||
| 529 | if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){
| 2-17060 | ||||||||||||
| 530 | return 1; executed 2 times by 1 test: return 1;Executed by:
| 2 | ||||||||||||
| 531 | } | - | ||||||||||||
| 532 | if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
| 1-17059 | ||||||||||||
| 533 | return 1; executed 1 time by 1 test: return 1;Executed by:
| 1 | ||||||||||||
| 534 | } | - | ||||||||||||
| 535 | if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){
| 2-17057 | ||||||||||||
| 536 | return 1; executed 2 times by 1 test: return 1;Executed by:
| 2 | ||||||||||||
| 537 | } | - | ||||||||||||
| 538 | if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
| 2-17055 | ||||||||||||
| 539 | return 1; executed 2 times by 1 test: return 1;Executed by:
| 2 | ||||||||||||
| 540 | } | - | ||||||||||||
| 541 | if( pSelect->pWith ){
| 3-17052 | ||||||||||||
| 542 | int i; | - | ||||||||||||
| 543 | for(i=0; i<pSelect->pWith->nCte; i++){
| 0-3 | ||||||||||||
| 544 | if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){
| 0-3 | ||||||||||||
| 545 | return 1; executed 3 times by 1 test: return 1;Executed by:
| 3 | ||||||||||||
| 546 | } | - | ||||||||||||
| 547 | } never executed: end of block | 0 | ||||||||||||
| 548 | } never executed: end of block | 0 | ||||||||||||
| 549 | pSelect = pSelect->pPrior; | - | ||||||||||||
| 550 | } executed 17052 times by 7 tests: end of blockExecuted by:
| 17052 | ||||||||||||
| 551 | return 0; executed 39921 times by 24 tests: return 0;Executed by:
| 39921 | ||||||||||||
| 552 | } | - | ||||||||||||
| 553 | int sqlite3FixExpr( | - | ||||||||||||
| 554 | DbFixer *pFix, /* Context of the fixation */ | - | ||||||||||||
| 555 | Expr *pExpr /* The expression to be fixed to one database */ | - | ||||||||||||
| 556 | ){ | - | ||||||||||||
| 557 | while( pExpr ){
| 101518-113695 | ||||||||||||
| 558 | if( pExpr->op==TK_VARIABLE ){
| 23-101495 | ||||||||||||
| 559 | if( pFix->pParse->db->init.busy ){
| 4-19 | ||||||||||||
| 560 | pExpr->op = TK_NULL; | - | ||||||||||||
| 561 | }else{ executed 4 times by 1 test: end of blockExecuted by:
| 4 | ||||||||||||
| 562 | sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); | - | ||||||||||||
| 563 | return 1; executed 19 times by 1 test: return 1;Executed by:
| 19 | ||||||||||||
| 564 | } | - | ||||||||||||
| 565 | } | - | ||||||||||||
| 566 | if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break; executed 61625 times by 7 tests: break;Executed by:
| 39874-61625 | ||||||||||||
| 567 | if( ExprHasProperty(pExpr, EP_xIsSelect) ){
| 864-39010 | ||||||||||||
| 568 | if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; executed 6 times by 1 test: return 1;Executed by:
| 6-858 | ||||||||||||
| 569 | }else{ executed 858 times by 1 test: end of blockExecuted by:
| 858 | ||||||||||||
| 570 | if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; executed 1 time by 1 test: return 1;Executed by:
| 1-39009 | ||||||||||||
| 571 | } executed 39009 times by 7 tests: end of blockExecuted by:
| 39009 | ||||||||||||
| 572 | if( sqlite3FixExpr(pFix, pExpr->pRight) ){
| 8-39859 | ||||||||||||
| 573 | return 1; executed 8 times by 1 test: return 1;Executed by:
| 8 | ||||||||||||
| 574 | } | - | ||||||||||||
| 575 | pExpr = pExpr->pLeft; | - | ||||||||||||
| 576 | } executed 39859 times by 7 tests: end of blockExecuted by:
| 39859 | ||||||||||||
| 577 | return 0; executed 175320 times by 24 tests: return 0;Executed by:
| 175320 | ||||||||||||
| 578 | } | - | ||||||||||||
| 579 | int sqlite3FixExprList( | - | ||||||||||||
| 580 | DbFixer *pFix, /* Context of the fixation */ | - | ||||||||||||
| 581 | ExprList *pList /* The expression to be fixed to one database */ | - | ||||||||||||
| 582 | ){ | - | ||||||||||||
| 583 | int i; | - | ||||||||||||
| 584 | struct ExprList_item *pItem; | - | ||||||||||||
| 585 | if( pList==0 ) return 0; executed 79932 times by 7 tests: return 0;Executed by:
| 21291-79932 | ||||||||||||
| 586 | for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
| 21274-40183 | ||||||||||||
| 587 | if( sqlite3FixExpr(pFix, pItem->pExpr) ){
| 17-40166 | ||||||||||||
| 588 | return 1; executed 17 times by 1 test: return 1;Executed by:
| 17 | ||||||||||||
| 589 | } | - | ||||||||||||
| 590 | } executed 40166 times by 7 tests: end of blockExecuted by:
| 40166 | ||||||||||||
| 591 | return 0; executed 21274 times by 7 tests: return 0;Executed by:
| 21274 | ||||||||||||
| 592 | } | - | ||||||||||||
| 593 | #endif | - | ||||||||||||
| 594 | - | |||||||||||||
| 595 | #ifndef SQLITE_OMIT_TRIGGER | - | ||||||||||||
| 596 | int sqlite3FixTriggerStep( | - | ||||||||||||
| 597 | DbFixer *pFix, /* Context of the fixation */ | - | ||||||||||||
| 598 | TriggerStep *pStep /* The trigger step be fixed to one database */ | - | ||||||||||||
| 599 | ){ | - | ||||||||||||
| 600 | while( pStep ){
| 9377-10939 | ||||||||||||
| 601 | if( sqlite3FixSelect(pFix, pStep->pSelect) ){
| 21-10918 | ||||||||||||
| 602 | return 1; executed 21 times by 1 test: return 1;Executed by:
| 21 | ||||||||||||
| 603 | } | - | ||||||||||||
| 604 | if( sqlite3FixExpr(pFix, pStep->pWhere) ){
| 3-10915 | ||||||||||||
| 605 | return 1; executed 3 times by 1 test: return 1;Executed by:
| 3 | ||||||||||||
| 606 | } | - | ||||||||||||
| 607 | if( sqlite3FixExprList(pFix, pStep->pExprList) ){
| 2-10913 | ||||||||||||
| 608 | return 1; executed 2 times by 1 test: return 1;Executed by:
| 2 | ||||||||||||
| 609 | } | - | ||||||||||||
| 610 | #ifndef SQLITE_OMIT_UPSERT | - | ||||||||||||
| 611 | if( pStep->pUpsert ){
| 42-10871 | ||||||||||||
| 612 | Upsert *pUp = pStep->pUpsert; | - | ||||||||||||
| 613 | if( sqlite3FixExprList(pFix, pUp->pUpsertTarget)
| 0-42 | ||||||||||||
| 614 | || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere)
| 0-42 | ||||||||||||
| 615 | || sqlite3FixExprList(pFix, pUp->pUpsertSet)
| 0-42 | ||||||||||||
| 616 | || sqlite3FixExpr(pFix, pUp->pUpsertWhere)
| 0-42 | ||||||||||||
| 617 | ){ | - | ||||||||||||
| 618 | return 1; never executed: return 1; | 0 | ||||||||||||
| 619 | } | - | ||||||||||||
| 620 | } executed 42 times by 1 test: end of blockExecuted by:
| 42 | ||||||||||||
| 621 | #endif | - | ||||||||||||
| 622 | pStep = pStep->pNext; | - | ||||||||||||
| 623 | } executed 10913 times by 7 tests: end of blockExecuted by:
| 10913 | ||||||||||||
| 624 | return 0; executed 9377 times by 7 tests: return 0;Executed by:
| 9377 | ||||||||||||
| 625 | } | - | ||||||||||||
| 626 | #endif | - | ||||||||||||
| Source code | Switch to Preprocessed file |