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*/
24typedef struct Incrblob Incrblob;
25struct 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*/
53static 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*/
108int 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
315blob_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*/
334int 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*/
354static 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*/
404int 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*/
411int 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*/
421int 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*/
436int 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