xref: /sqlite-3.40.0/src/vdbeblob.c (revision bd5af9ea)
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(4);
253       static const VdbeOpList openBlob[] = {
254                                     /* addr/ofst */
255         /* {OP_Transaction, 0, 0, 0},  // 0/   inserted separately */
256         {OP_TableLock, 0, 0, 0},       /* 1/0: Acquire a read or write lock */
257         {OP_OpenRead, 0, 0, 0},        /* 2/1: Open a cursor */
258         {OP_Variable, 1, 1, 0},        /* 3/2: Move ?1 into reg[1] */
259         {OP_NotExists, 0, 8, 1},       /* 4/3: Seek the cursor */
260         {OP_Column, 0, 0, 1},          /* 5/4  */
261         {OP_ResultRow, 1, 0, 0},       /* 6/5  */
262         {OP_Goto, 0, 3, 0},            /* 7/6  */
263         {OP_Close, 0, 0, 0},           /* 8/7  */
264         {OP_Halt, 0, 0, 0},            /* 9/8  */
265       };
266       Vdbe *v = (Vdbe *)pBlob->pStmt;
267       int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
268       VdbeOp *aOp;
269 
270       sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags,
271                            pTab->pSchema->schema_cookie,
272                            pTab->pSchema->iGeneration);
273       sqlite3VdbeChangeP5(v, 1);
274       aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn);
275 
276       /* Make sure a mutex is held on the table to be accessed */
277       sqlite3VdbeUsesBtree(v, iDb);
278 
279       if( db->mallocFailed==0 ){
280         assert( aOp!=0 );
281         /* Configure the OP_TableLock instruction */
282 #ifdef SQLITE_OMIT_SHARED_CACHE
283         aOp[0].opcode = OP_Noop;
284 #else
285         aOp[0].p1 = iDb;
286         aOp[0].p2 = pTab->tnum;
287         aOp[0].p3 = flags;
288         sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT);
289       }
290       if( db->mallocFailed==0 ){
291 #endif
292 
293         /* Remove either the OP_OpenWrite or OpenRead. Set the P2
294         ** parameter of the other to pTab->tnum.  */
295         if( flags ) aOp[1].opcode = OP_OpenWrite;
296         aOp[1].p2 = pTab->tnum;
297         aOp[1].p3 = iDb;
298 
299         /* Configure the number of columns. Configure the cursor to
300         ** think that the table has one more column than it really
301         ** does. An OP_Column to retrieve this imaginary column will
302         ** always return an SQL NULL. This is useful because it means
303         ** we can invoke OP_Column to fill in the vdbe cursors type
304         ** and offset cache without causing any IO.
305         */
306         aOp[1].p4type = P4_INT32;
307         aOp[1].p4.i = pTab->nCol+1;
308         aOp[4].p2 = pTab->nCol;
309 
310         pParse->nVar = 1;
311         pParse->nMem = 1;
312         pParse->nTab = 1;
313         sqlite3VdbeMakeReady(v, pParse);
314       }
315     }
316 
317     pBlob->flags = flags;
318     pBlob->iCol = iCol;
319     pBlob->db = db;
320     sqlite3BtreeLeaveAll(db);
321     if( db->mallocFailed ){
322       goto blob_open_out;
323     }
324     sqlite3_bind_int64(pBlob->pStmt, 1, iRow);
325     rc = blobSeekToRow(pBlob, iRow, &zErr);
326   } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
327 
328 blob_open_out:
329   if( rc==SQLITE_OK && db->mallocFailed==0 ){
330     *ppBlob = (sqlite3_blob *)pBlob;
331   }else{
332     if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
333     sqlite3DbFree(db, pBlob);
334   }
335   sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
336   sqlite3DbFree(db, zErr);
337   sqlite3ParserReset(pParse);
338   sqlite3StackFree(db, pParse);
339   rc = sqlite3ApiExit(db, rc);
340   sqlite3_mutex_leave(db->mutex);
341   return rc;
342 }
343 
344 /*
345 ** Close a blob handle that was previously created using
346 ** sqlite3_blob_open().
347 */
348 int sqlite3_blob_close(sqlite3_blob *pBlob){
349   Incrblob *p = (Incrblob *)pBlob;
350   int rc;
351   sqlite3 *db;
352 
353   if( p ){
354     db = p->db;
355     sqlite3_mutex_enter(db->mutex);
356     rc = sqlite3_finalize(p->pStmt);
357     sqlite3DbFree(db, p);
358     sqlite3_mutex_leave(db->mutex);
359   }else{
360     rc = SQLITE_OK;
361   }
362   return rc;
363 }
364 
365 /*
366 ** Perform a read or write operation on a blob
367 */
368 static int blobReadWrite(
369   sqlite3_blob *pBlob,
370   void *z,
371   int n,
372   int iOffset,
373   int (*xCall)(BtCursor*, u32, u32, void*)
374 ){
375   int rc;
376   Incrblob *p = (Incrblob *)pBlob;
377   Vdbe *v;
378   sqlite3 *db;
379 
380   if( p==0 ) return SQLITE_MISUSE_BKPT;
381   db = p->db;
382   sqlite3_mutex_enter(db->mutex);
383   v = (Vdbe*)p->pStmt;
384 
385   if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){
386     /* Request is out of range. Return a transient error. */
387     rc = SQLITE_ERROR;
388   }else if( v==0 ){
389     /* If there is no statement handle, then the blob-handle has
390     ** already been invalidated. Return SQLITE_ABORT in this case.
391     */
392     rc = SQLITE_ABORT;
393   }else{
394     /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
395     ** returned, clean-up the statement handle.
396     */
397     assert( db == v->db );
398     sqlite3BtreeEnterCursor(p->pCsr);
399     rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
400     sqlite3BtreeLeaveCursor(p->pCsr);
401     if( rc==SQLITE_ABORT ){
402       sqlite3VdbeFinalize(v);
403       p->pStmt = 0;
404     }else{
405       v->rc = rc;
406     }
407   }
408   sqlite3Error(db, rc);
409   rc = sqlite3ApiExit(db, rc);
410   sqlite3_mutex_leave(db->mutex);
411   return rc;
412 }
413 
414 /*
415 ** Read data from a blob handle.
416 */
417 int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
418   return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData);
419 }
420 
421 /*
422 ** Write data to a blob handle.
423 */
424 int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
425   return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
426 }
427 
428 /*
429 ** Query a blob handle for the size of the data.
430 **
431 ** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
432 ** so no mutex is required for access.
433 */
434 int sqlite3_blob_bytes(sqlite3_blob *pBlob){
435   Incrblob *p = (Incrblob *)pBlob;
436   return (p && p->pStmt) ? p->nByte : 0;
437 }
438 
439 /*
440 ** Move an existing blob handle to point to a different row of the same
441 ** database table.
442 **
443 ** If an error occurs, or if the specified row does not exist or does not
444 ** contain a blob or text value, then an error code is returned and the
445 ** database handle error code and message set. If this happens, then all
446 ** subsequent calls to sqlite3_blob_xxx() functions (except blob_close())
447 ** immediately return SQLITE_ABORT.
448 */
449 int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
450   int rc;
451   Incrblob *p = (Incrblob *)pBlob;
452   sqlite3 *db;
453 
454   if( p==0 ) return SQLITE_MISUSE_BKPT;
455   db = p->db;
456   sqlite3_mutex_enter(db->mutex);
457 
458   if( p->pStmt==0 ){
459     /* If there is no statement handle, then the blob-handle has
460     ** already been invalidated. Return SQLITE_ABORT in this case.
461     */
462     rc = SQLITE_ABORT;
463   }else{
464     char *zErr;
465     rc = blobSeekToRow(p, iRow, &zErr);
466     if( rc!=SQLITE_OK ){
467       sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
468       sqlite3DbFree(db, zErr);
469     }
470     assert( rc!=SQLITE_SCHEMA );
471   }
472 
473   rc = sqlite3ApiExit(db, rc);
474   assert( rc==SQLITE_OK || p->pStmt==0 );
475   sqlite3_mutex_leave(db->mutex);
476   return rc;
477 }
478 
479 #endif /* #ifndef SQLITE_OMIT_INCRBLOB */
480