| 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 |