Home | History | Annotate | Download | only in src
      1 /*
      2 ** 2007 May 1
      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 **
     13 ** This file contains code used to implement incremental BLOB I/O.
     14 */
     15 
     16 #include "sqliteInt.h"
     17 #include "vdbeInt.h"
     18 
     19 #ifndef SQLITE_OMIT_INCRBLOB
     20 
     21 /*
     22 ** Valid sqlite3_blob* handles point to Incrblob structures.
     23 */
     24 typedef struct Incrblob Incrblob;
     25 struct Incrblob {
     26   int flags;              /* Copy of "flags" passed to sqlite3_blob_open() */
     27   int nByte;              /* Size of open blob, in bytes */
     28   int iOffset;            /* Byte offset of blob in cursor data */
     29   int iCol;               /* Table column this handle is open on */
     30   BtCursor *pCsr;         /* Cursor pointing at blob row */
     31   sqlite3_stmt *pStmt;    /* Statement holding cursor open */
     32   sqlite3 *db;            /* The associated database */
     33 };
     34 
     35 
     36 /*
     37 ** This function is used by both blob_open() and blob_reopen(). It seeks
     38 ** the b-tree cursor associated with blob handle p to point to row iRow.
     39 ** If successful, SQLITE_OK is returned and subsequent calls to
     40 ** sqlite3_blob_read() or sqlite3_blob_write() access the specified row.
     41 **
     42 ** If an error occurs, or if the specified row does not exist or does not
     43 ** contain a value of type TEXT or BLOB in the column nominated when the
     44 ** blob handle was opened, then an error code is returned and *pzErr may
     45 ** be set to point to a buffer containing an error message. It is the
     46 ** responsibility of the caller to free the error message buffer using
     47 ** sqlite3DbFree().
     48 **
     49 ** If an error does occur, then the b-tree cursor is closed. All subsequent
     50 ** calls to sqlite3_blob_read(), blob_write() or blob_reopen() will
     51 ** immediately return SQLITE_ABORT.
     52 */
     53 static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
     54   int rc;                         /* Error code */
     55   char *zErr = 0;                 /* Error message */
     56   Vdbe *v = (Vdbe *)p->pStmt;
     57 
     58   /* Set the value of the SQL statements only variable to integer iRow.
     59   ** This is done directly instead of using sqlite3_bind_int64() to avoid
     60   ** triggering asserts related to mutexes.
     61   */
     62   assert( v->aVar[0].flags&MEM_Int );
     63   v->aVar[0].u.i = iRow;
     64 
     65   rc = sqlite3_step(p->pStmt);
     66   if( rc==SQLITE_ROW ){
     67     u32 type = v->apCsr[0]->aType[p->iCol];
     68     if( type<12 ){
     69       zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
     70           type==0?"null": type==7?"real": "integer"
     71       );
     72       rc = SQLITE_ERROR;
     73       sqlite3_finalize(p->pStmt);
     74       p->pStmt = 0;
     75     }else{
     76       p->iOffset = v->apCsr[0]->aOffset[p->iCol];
     77       p->nByte = sqlite3VdbeSerialTypeLen(type);
     78       p->pCsr =  v->apCsr[0]->pCursor;
     79       sqlite3BtreeEnterCursor(p->pCsr);
     80       sqlite3BtreeCacheOverflow(p->pCsr);
     81       sqlite3BtreeLeaveCursor(p->pCsr);
     82     }
     83   }
     84 
     85   if( rc==SQLITE_ROW ){
     86     rc = SQLITE_OK;
     87   }else if( p->pStmt ){
     88     rc = sqlite3_finalize(p->pStmt);
     89     p->pStmt = 0;
     90     if( rc==SQLITE_OK ){
     91       zErr = sqlite3MPrintf(p->db, "no such rowid: %lld", iRow);
     92       rc = SQLITE_ERROR;
     93     }else{
     94       zErr = sqlite3MPrintf(p->db, "%s", sqlite3_errmsg(p->db));
     95     }
     96   }
     97 
     98   assert( rc!=SQLITE_OK || zErr==0 );
     99   assert( rc!=SQLITE_ROW && rc!=SQLITE_DONE );
    100 
    101   *pzErr = zErr;
    102   return rc;
    103 }
    104 
    105 /*
    106 ** Open a blob handle.
    107 */
    108 int sqlite3_blob_open(
    109   sqlite3* db,            /* The database connection */
    110   const char *zDb,        /* The attached database containing the blob */
    111   const char *zTable,     /* The table containing the blob */
    112   const char *zColumn,    /* The column containing the blob */
    113   sqlite_int64 iRow,      /* The row containing the glob */
    114   int flags,              /* True -> read/write access, false -> read-only */
    115   sqlite3_blob **ppBlob   /* Handle for accessing the blob returned here */
    116 ){
    117   int nAttempt = 0;
    118   int iCol;               /* Index of zColumn in row-record */
    119 
    120   /* This VDBE program seeks a btree cursor to the identified
    121   ** db/table/row entry. The reason for using a vdbe program instead
    122   ** of writing code to use the b-tree layer directly is that the
    123   ** vdbe program will take advantage of the various transaction,
    124   ** locking and error handling infrastructure built into the vdbe.
    125   **
    126   ** After seeking the cursor, the vdbe executes an OP_ResultRow.
    127   ** Code external to the Vdbe then "borrows" the b-tree cursor and
    128   ** uses it to implement the blob_read(), blob_write() and
    129   ** blob_bytes() functions.
    130   **
    131   ** The sqlite3_blob_close() function finalizes the vdbe program,
    132   ** which closes the b-tree cursor and (possibly) commits the
    133   ** transaction.
    134   */
    135   static const VdbeOpList openBlob[] = {
    136     {OP_Transaction, 0, 0, 0},     /* 0: Start a transaction */
    137     {OP_VerifyCookie, 0, 0, 0},    /* 1: Check the schema cookie */
    138     {OP_TableLock, 0, 0, 0},       /* 2: Acquire a read or write lock */
    139 
    140     /* One of the following two instructions is replaced by an OP_Noop. */
    141     {OP_OpenRead, 0, 0, 0},        /* 3: Open cursor 0 for reading */
    142     {OP_OpenWrite, 0, 0, 0},       /* 4: Open cursor 0 for read/write */
    143 
    144     {OP_Variable, 1, 1, 1},        /* 5: Push the rowid to the stack */
    145     {OP_NotExists, 0, 10, 1},      /* 6: Seek the cursor */
    146     {OP_Column, 0, 0, 1},          /* 7  */
    147     {OP_ResultRow, 1, 0, 0},       /* 8  */
    148     {OP_Goto, 0, 5, 0},            /* 9  */
    149     {OP_Close, 0, 0, 0},           /* 10 */
    150     {OP_Halt, 0, 0, 0},            /* 11 */
    151   };
    152 
    153   int rc = SQLITE_OK;
    154   char *zErr = 0;
    155   Table *pTab;
    156   Parse *pParse = 0;
    157   Incrblob *pBlob = 0;
    158 
    159   flags = !!flags;                /* flags = (flags ? 1 : 0); */
    160   *ppBlob = 0;
    161 
    162   sqlite3_mutex_enter(db->mutex);
    163 
    164   pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
    165   if( !pBlob ) goto blob_open_out;
    166   pParse = sqlite3StackAllocRaw(db, sizeof(*pParse));
    167   if( !pParse ) goto blob_open_out;
    168 
    169   do {
    170     memset(pParse, 0, sizeof(Parse));
    171     pParse->db = db;
    172     sqlite3DbFree(db, zErr);
    173     zErr = 0;
    174 
    175     sqlite3BtreeEnterAll(db);
    176     pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
    177     if( pTab && IsVirtual(pTab) ){
    178       pTab = 0;
    179       sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable);
    180     }
    181 #ifndef SQLITE_OMIT_VIEW
    182     if( pTab && pTab->pSelect ){
    183       pTab = 0;
    184       sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable);
    185     }
    186 #endif
    187     if( !pTab ){
    188       if( pParse->zErrMsg ){
    189         sqlite3DbFree(db, zErr);
    190         zErr = pParse->zErrMsg;
    191         pParse->zErrMsg = 0;
    192       }
    193       rc = SQLITE_ERROR;
    194       sqlite3BtreeLeaveAll(db);
    195       goto blob_open_out;
    196     }
    197 
    198     /* Now search pTab for the exact column. */
    199     for(iCol=0; iCol<pTab->nCol; iCol++) {
    200       if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){
    201         break;
    202       }
    203     }
    204     if( iCol==pTab->nCol ){
    205       sqlite3DbFree(db, zErr);
    206       zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn);
    207       rc = SQLITE_ERROR;
    208       sqlite3BtreeLeaveAll(db);
    209       goto blob_open_out;
    210     }
    211 
    212     /* If the value is being opened for writing, check that the
    213     ** column is not indexed, and that it is not part of a foreign key.
    214     ** It is against the rules to open a column to which either of these
    215     ** descriptions applies for writing.  */
    216     if( flags ){
    217       const char *zFault = 0;
    218       Index *pIdx;
    219 #ifndef SQLITE_OMIT_FOREIGN_KEY
    220       if( db->flags&SQLITE_ForeignKeys ){
    221         /* Check that the column is not part of an FK child key definition. It
    222         ** is not necessary to check if it is part of a parent key, as parent
    223         ** key columns must be indexed. The check below will pick up this
    224         ** case.  */
    225         FKey *pFKey;
    226         for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
    227           int j;
    228           for(j=0; j<pFKey->nCol; j++){
    229             if( pFKey->aCol[j].iFrom==iCol ){
    230               zFault = "foreign key";
    231             }
    232           }
    233         }
    234       }
    235 #endif
    236       for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    237         int j;
    238         for(j=0; j<pIdx->nColumn; j++){
    239           if( pIdx->aiColumn[j]==iCol ){
    240             zFault = "indexed";
    241           }
    242         }
    243       }
    244       if( zFault ){
    245         sqlite3DbFree(db, zErr);
    246         zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault);
    247         rc = SQLITE_ERROR;
    248         sqlite3BtreeLeaveAll(db);
    249         goto blob_open_out;
    250       }
    251     }
    252 
    253     pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(db);
    254     assert( pBlob->pStmt || db->mallocFailed );
    255     if( pBlob->pStmt ){
    256       Vdbe *v = (Vdbe *)pBlob->pStmt;
    257       int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
    258 
    259       sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob);
    260 
    261 
    262       /* Configure the OP_Transaction */
    263       sqlite3VdbeChangeP1(v, 0, iDb);
    264       sqlite3VdbeChangeP2(v, 0, flags);
    265 
    266       /* Configure the OP_VerifyCookie */
    267       sqlite3VdbeChangeP1(v, 1, iDb);
    268       sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie);
    269       sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration);
    270 
    271       /* Make sure a mutex is held on the table to be accessed */
    272       sqlite3VdbeUsesBtree(v, iDb);
    273 
    274       /* Configure the OP_TableLock instruction */
    275 #ifdef SQLITE_OMIT_SHARED_CACHE
    276       sqlite3VdbeChangeToNoop(v, 2, 1);
    277 #else
    278       sqlite3VdbeChangeP1(v, 2, iDb);
    279       sqlite3VdbeChangeP2(v, 2, pTab->tnum);
    280       sqlite3VdbeChangeP3(v, 2, flags);
    281       sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);
    282 #endif
    283 
    284       /* Remove either the OP_OpenWrite or OpenRead. Set the P2
    285       ** parameter of the other to pTab->tnum.  */
    286       sqlite3VdbeChangeToNoop(v, 4 - flags, 1);
    287       sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum);
    288       sqlite3VdbeChangeP3(v, 3 + flags, iDb);
    289 
    290       /* Configure the number of columns. Configure the cursor to
    291       ** think that the table has one more column than it really
    292       ** does. An OP_Column to retrieve this imaginary column will
    293       ** always return an SQL NULL. This is useful because it means
    294       ** we can invoke OP_Column to fill in the vdbe cursors type
    295       ** and offset cache without causing any IO.
    296       */
    297       sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
    298       sqlite3VdbeChangeP2(v, 7, pTab->nCol);
    299       if( !db->mallocFailed ){
    300         sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0);
    301       }
    302     }
    303 
    304     pBlob->flags = flags;
    305     pBlob->iCol = iCol;
    306     pBlob->db = db;
    307     sqlite3BtreeLeaveAll(db);
    308     if( db->mallocFailed ){
    309       goto blob_open_out;
    310     }
    311     sqlite3_bind_int64(pBlob->pStmt, 1, iRow);
    312     rc = blobSeekToRow(pBlob, iRow, &zErr);
    313   } while( (++nAttempt)<5 && rc==SQLITE_SCHEMA );
    314 
    315 blob_open_out:
    316   if( rc==SQLITE_OK && db->mallocFailed==0 ){
    317     *ppBlob = (sqlite3_blob *)pBlob;
    318   }else{
    319     if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
    320     sqlite3DbFree(db, pBlob);
    321   }
    322   sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr);
    323   sqlite3DbFree(db, zErr);
    324   sqlite3StackFree(db, pParse);
    325   rc = sqlite3ApiExit(db, rc);
    326   sqlite3_mutex_leave(db->mutex);
    327   return rc;
    328 }
    329 
    330 /*
    331 ** Close a blob handle that was previously created using
    332 ** sqlite3_blob_open().
    333 */
    334 int sqlite3_blob_close(sqlite3_blob *pBlob){
    335   Incrblob *p = (Incrblob *)pBlob;
    336   int rc;
    337   sqlite3 *db;
    338 
    339   if( p ){
    340     db = p->db;
    341     sqlite3_mutex_enter(db->mutex);
    342     rc = sqlite3_finalize(p->pStmt);
    343     sqlite3DbFree(db, p);
    344     sqlite3_mutex_leave(db->mutex);
    345   }else{
    346     rc = SQLITE_OK;
    347   }
    348   return rc;
    349 }
    350 
    351 /*
    352 ** Perform a read or write operation on a blob
    353 */
    354 static int blobReadWrite(
    355   sqlite3_blob *pBlob,
    356   void *z,
    357   int n,
    358   int iOffset,
    359   int (*xCall)(BtCursor*, u32, u32, void*)
    360 ){
    361   int rc;
    362   Incrblob *p = (Incrblob *)pBlob;
    363   Vdbe *v;
    364   sqlite3 *db;
    365 
    366   if( p==0 ) return SQLITE_MISUSE_BKPT;
    367   db = p->db;
    368   sqlite3_mutex_enter(db->mutex);
    369   v = (Vdbe*)p->pStmt;
    370 
    371   if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
    372     /* Request is out of range. Return a transient error. */
    373     rc = SQLITE_ERROR;
    374     sqlite3Error(db, SQLITE_ERROR, 0);
    375   }else if( v==0 ){
    376     /* If there is no statement handle, then the blob-handle has
    377     ** already been invalidated. Return SQLITE_ABORT in this case.
    378     */
    379     rc = SQLITE_ABORT;
    380   }else{
    381     /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
    382     ** returned, clean-up the statement handle.
    383     */
    384     assert( db == v->db );
    385     sqlite3BtreeEnterCursor(p->pCsr);
    386     rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
    387     sqlite3BtreeLeaveCursor(p->pCsr);
    388     if( rc==SQLITE_ABORT ){
    389       sqlite3VdbeFinalize(v);
    390       p->pStmt = 0;
    391     }else{
    392       db->errCode = rc;
    393       v->rc = rc;
    394     }
    395   }
    396   rc = sqlite3ApiExit(db, rc);
    397   sqlite3_mutex_leave(db->mutex);
    398   return rc;
    399 }
    400 
    401 /*
    402 ** Read data from a blob handle.
    403 */
    404 int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
    405   return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData);
    406 }
    407 
    408 /*
    409 ** Write data to a blob handle.
    410 */
    411 int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
    412   return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
    413 }
    414 
    415 /*
    416 ** Query a blob handle for the size of the data.
    417 **
    418 ** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
    419 ** so no mutex is required for access.
    420 */
    421 int sqlite3_blob_bytes(sqlite3_blob *pBlob){
    422   Incrblob *p = (Incrblob *)pBlob;
    423   return (p && p->pStmt) ? p->nByte : 0;
    424 }
    425 
    426 /*
    427 ** Move an existing blob handle to point to a different row of the same
    428 ** database table.
    429 **
    430 ** If an error occurs, or if the specified row does not exist or does not
    431 ** contain a blob or text value, then an error code is returned and the
    432 ** database handle error code and message set. If this happens, then all
    433 ** subsequent calls to sqlite3_blob_xxx() functions (except blob_close())
    434 ** immediately return SQLITE_ABORT.
    435 */
    436 int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
    437   int rc;
    438   Incrblob *p = (Incrblob *)pBlob;
    439   sqlite3 *db;
    440 
    441   if( p==0 ) return SQLITE_MISUSE_BKPT;
    442   db = p->db;
    443   sqlite3_mutex_enter(db->mutex);
    444 
    445   if( p->pStmt==0 ){
    446     /* If there is no statement handle, then the blob-handle has
    447     ** already been invalidated. Return SQLITE_ABORT in this case.
    448     */
    449     rc = SQLITE_ABORT;
    450   }else{
    451     char *zErr;
    452     rc = blobSeekToRow(p, iRow, &zErr);
    453     if( rc!=SQLITE_OK ){
    454       sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr);
    455       sqlite3DbFree(db, zErr);
    456     }
    457     assert( rc!=SQLITE_SCHEMA );
    458   }
    459 
    460   rc = sqlite3ApiExit(db, rc);
    461   assert( rc==SQLITE_OK || p->pStmt==0 );
    462   sqlite3_mutex_leave(db->mutex);
    463   return rc;
    464 }
    465 
    466 #endif /* #ifndef SQLITE_OMIT_INCRBLOB */
    467