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