OLD | NEW |
1 /* | 1 /* |
2 ** 2007 May 1 | 2 ** 2007 May 1 |
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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 if( type<12 ){ | 69 if( type<12 ){ |
70 zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", | 70 zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", |
71 type==0?"null": type==7?"real": "integer" | 71 type==0?"null": type==7?"real": "integer" |
72 ); | 72 ); |
73 rc = SQLITE_ERROR; | 73 rc = SQLITE_ERROR; |
74 sqlite3_finalize(p->pStmt); | 74 sqlite3_finalize(p->pStmt); |
75 p->pStmt = 0; | 75 p->pStmt = 0; |
76 }else{ | 76 }else{ |
77 p->iOffset = pC->aType[p->iCol + pC->nField]; | 77 p->iOffset = pC->aType[p->iCol + pC->nField]; |
78 p->nByte = sqlite3VdbeSerialTypeLen(type); | 78 p->nByte = sqlite3VdbeSerialTypeLen(type); |
79 p->pCsr = pC->pCursor; | 79 p->pCsr = pC->uc.pCursor; |
80 sqlite3BtreeIncrblobCursor(p->pCsr); | 80 sqlite3BtreeIncrblobCursor(p->pCsr); |
81 } | 81 } |
82 } | 82 } |
83 | 83 |
84 if( rc==SQLITE_ROW ){ | 84 if( rc==SQLITE_ROW ){ |
85 rc = SQLITE_OK; | 85 rc = SQLITE_OK; |
86 }else if( p->pStmt ){ | 86 }else if( p->pStmt ){ |
87 rc = sqlite3_finalize(p->pStmt); | 87 rc = sqlite3_finalize(p->pStmt); |
88 p->pStmt = 0; | 88 p->pStmt = 0; |
89 if( rc==SQLITE_OK ){ | 89 if( rc==SQLITE_OK ){ |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 {OP_Close, 0, 0, 0}, /* 9 */ | 146 {OP_Close, 0, 0, 0}, /* 9 */ |
147 {OP_Halt, 0, 0, 0}, /* 10 */ | 147 {OP_Halt, 0, 0, 0}, /* 10 */ |
148 }; | 148 }; |
149 | 149 |
150 int rc = SQLITE_OK; | 150 int rc = SQLITE_OK; |
151 char *zErr = 0; | 151 char *zErr = 0; |
152 Table *pTab; | 152 Table *pTab; |
153 Parse *pParse = 0; | 153 Parse *pParse = 0; |
154 Incrblob *pBlob = 0; | 154 Incrblob *pBlob = 0; |
155 | 155 |
| 156 #ifdef SQLITE_ENABLE_API_ARMOR |
| 157 if( ppBlob==0 ){ |
| 158 return SQLITE_MISUSE_BKPT; |
| 159 } |
| 160 #endif |
| 161 *ppBlob = 0; |
| 162 #ifdef SQLITE_ENABLE_API_ARMOR |
| 163 if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ |
| 164 return SQLITE_MISUSE_BKPT; |
| 165 } |
| 166 #endif |
156 flags = !!flags; /* flags = (flags ? 1 : 0); */ | 167 flags = !!flags; /* flags = (flags ? 1 : 0); */ |
157 *ppBlob = 0; | |
158 | 168 |
159 sqlite3_mutex_enter(db->mutex); | 169 sqlite3_mutex_enter(db->mutex); |
160 | 170 |
161 pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); | 171 pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); |
162 if( !pBlob ) goto blob_open_out; | 172 if( !pBlob ) goto blob_open_out; |
163 pParse = sqlite3StackAllocRaw(db, sizeof(*pParse)); | 173 pParse = sqlite3StackAllocRaw(db, sizeof(*pParse)); |
164 if( !pParse ) goto blob_open_out; | 174 if( !pParse ) goto blob_open_out; |
165 | 175 |
166 do { | 176 do { |
167 memset(pParse, 0, sizeof(Parse)); | 177 memset(pParse, 0, sizeof(Parse)); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 if( pFKey->aCol[j].iFrom==iCol ){ | 240 if( pFKey->aCol[j].iFrom==iCol ){ |
231 zFault = "foreign key"; | 241 zFault = "foreign key"; |
232 } | 242 } |
233 } | 243 } |
234 } | 244 } |
235 } | 245 } |
236 #endif | 246 #endif |
237 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | 247 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
238 int j; | 248 int j; |
239 for(j=0; j<pIdx->nKeyCol; j++){ | 249 for(j=0; j<pIdx->nKeyCol; j++){ |
240 if( pIdx->aiColumn[j]==iCol ){ | 250 /* FIXME: Be smarter about indexes that use expressions */ |
| 251 if( pIdx->aiColumn[j]==iCol || pIdx->aiColumn[j]==XN_EXPR ){ |
241 zFault = "indexed"; | 252 zFault = "indexed"; |
242 } | 253 } |
243 } | 254 } |
244 } | 255 } |
245 if( zFault ){ | 256 if( zFault ){ |
246 sqlite3DbFree(db, zErr); | 257 sqlite3DbFree(db, zErr); |
247 zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault); | 258 zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault); |
248 rc = SQLITE_ERROR; | 259 rc = SQLITE_ERROR; |
249 sqlite3BtreeLeaveAll(db); | 260 sqlite3BtreeLeaveAll(db); |
250 goto blob_open_out; | 261 goto blob_open_out; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 int rc; | 372 int rc; |
362 Incrblob *p = (Incrblob *)pBlob; | 373 Incrblob *p = (Incrblob *)pBlob; |
363 Vdbe *v; | 374 Vdbe *v; |
364 sqlite3 *db; | 375 sqlite3 *db; |
365 | 376 |
366 if( p==0 ) return SQLITE_MISUSE_BKPT; | 377 if( p==0 ) return SQLITE_MISUSE_BKPT; |
367 db = p->db; | 378 db = p->db; |
368 sqlite3_mutex_enter(db->mutex); | 379 sqlite3_mutex_enter(db->mutex); |
369 v = (Vdbe*)p->pStmt; | 380 v = (Vdbe*)p->pStmt; |
370 | 381 |
371 if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){ | 382 if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){ |
372 /* Request is out of range. Return a transient error. */ | 383 /* Request is out of range. Return a transient error. */ |
373 rc = SQLITE_ERROR; | 384 rc = SQLITE_ERROR; |
374 sqlite3Error(db, SQLITE_ERROR); | |
375 }else if( v==0 ){ | 385 }else if( v==0 ){ |
376 /* If there is no statement handle, then the blob-handle has | 386 /* If there is no statement handle, then the blob-handle has |
377 ** already been invalidated. Return SQLITE_ABORT in this case. | 387 ** already been invalidated. Return SQLITE_ABORT in this case. |
378 */ | 388 */ |
379 rc = SQLITE_ABORT; | 389 rc = SQLITE_ABORT; |
380 }else{ | 390 }else{ |
381 /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is | 391 /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is |
382 ** returned, clean-up the statement handle. | 392 ** returned, clean-up the statement handle. |
383 */ | 393 */ |
384 assert( db == v->db ); | 394 assert( db == v->db ); |
385 sqlite3BtreeEnterCursor(p->pCsr); | 395 sqlite3BtreeEnterCursor(p->pCsr); |
386 rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); | 396 rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); |
387 sqlite3BtreeLeaveCursor(p->pCsr); | 397 sqlite3BtreeLeaveCursor(p->pCsr); |
388 if( rc==SQLITE_ABORT ){ | 398 if( rc==SQLITE_ABORT ){ |
389 sqlite3VdbeFinalize(v); | 399 sqlite3VdbeFinalize(v); |
390 p->pStmt = 0; | 400 p->pStmt = 0; |
391 }else{ | 401 }else{ |
392 db->errCode = rc; | |
393 v->rc = rc; | 402 v->rc = rc; |
394 } | 403 } |
395 } | 404 } |
| 405 sqlite3Error(db, rc); |
396 rc = sqlite3ApiExit(db, rc); | 406 rc = sqlite3ApiExit(db, rc); |
397 sqlite3_mutex_leave(db->mutex); | 407 sqlite3_mutex_leave(db->mutex); |
398 return rc; | 408 return rc; |
399 } | 409 } |
400 | 410 |
401 /* | 411 /* |
402 ** Read data from a blob handle. | 412 ** Read data from a blob handle. |
403 */ | 413 */ |
404 int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){ | 414 int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){ |
405 return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData); | 415 return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 assert( rc!=SQLITE_SCHEMA ); | 467 assert( rc!=SQLITE_SCHEMA ); |
458 } | 468 } |
459 | 469 |
460 rc = sqlite3ApiExit(db, rc); | 470 rc = sqlite3ApiExit(db, rc); |
461 assert( rc==SQLITE_OK || p->pStmt==0 ); | 471 assert( rc==SQLITE_OK || p->pStmt==0 ); |
462 sqlite3_mutex_leave(db->mutex); | 472 sqlite3_mutex_leave(db->mutex); |
463 return rc; | 473 return rc; |
464 } | 474 } |
465 | 475 |
466 #endif /* #ifndef SQLITE_OMIT_INCRBLOB */ | 476 #endif /* #ifndef SQLITE_OMIT_INCRBLOB */ |
OLD | NEW |