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 block Executed by:
| 1669 | ||||||||||||
42 | pExpr->op = TK_STRING; | - | ||||||||||||
43 | } executed 1789 times by 12 tests: end of block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed by:
| 2 | ||||||||||||
265 | } executed 9 times by 1 test: end of block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed by:
| 1770 | ||||||||||||
368 | zAuthArg = 0; | - | ||||||||||||
369 | } executed 40 times by 1 test: end of block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed 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 block Executed by:
| 42 | ||||||||||||
621 | #endif | - | ||||||||||||
622 | pStep = pStep->pNext; | - | ||||||||||||
623 | } executed 10913 times by 7 tests: end of block Executed 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 |