vdbeblob.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  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. ** $Id: vdbeblob.c,v 1.16 2007/08/30 01:19:59 drh Exp $
  16. */
  17. #include "sqliteInt.h"
  18. #include "vdbeInt.h"
  19. #ifndef SQLITE_OMIT_INCRBLOB
  20. /*
  21. ** Valid sqlite3_blob* handles point to Incrblob structures.
  22. */
  23. typedef struct Incrblob Incrblob;
  24. struct Incrblob {
  25. int flags; /* Copy of "flags" passed to sqlite3_blob_open() */
  26. int nByte; /* Size of open blob, in bytes */
  27. int iOffset; /* Byte offset of blob in cursor data */
  28. BtCursor *pCsr; /* Cursor pointing at blob row */
  29. sqlite3_stmt *pStmt; /* Statement holding cursor open */
  30. sqlite3 *db; /* The associated database */
  31. };
  32. /*
  33. ** Open a blob handle.
  34. */
  35. int sqlite3_blob_open(
  36. sqlite3* db, /* The database connection */
  37. const char *zDb, /* The attached database containing the blob */
  38. const char *zTable, /* The table containing the blob */
  39. const char *zColumn, /* The column containing the blob */
  40. sqlite_int64 iRow, /* The row containing the glob */
  41. int flags, /* True -> read/write access, false -> read-only */
  42. sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */
  43. ){
  44. int nAttempt = 0;
  45. int iCol; /* Index of zColumn in row-record */
  46. /* This VDBE program seeks a btree cursor to the identified
  47. ** db/table/row entry. The reason for using a vdbe program instead
  48. ** of writing code to use the b-tree layer directly is that the
  49. ** vdbe program will take advantage of the various transaction,
  50. ** locking and error handling infrastructure built into the vdbe.
  51. **
  52. ** After seeking the cursor, the vdbe executes an OP_Callback.
  53. ** Code external to the Vdbe then "borrows" the b-tree cursor and
  54. ** uses it to implement the blob_read(), blob_write() and
  55. ** blob_bytes() functions.
  56. **
  57. ** The sqlite3_blob_close() function finalizes the vdbe program,
  58. ** which closes the b-tree cursor and (possibly) commits the
  59. ** transaction.
  60. */
  61. static const VdbeOpList openBlob[] = {
  62. {OP_Transaction, 0, 0, 0}, /* 0: Start a transaction */
  63. {OP_VerifyCookie, 0, 0, 0}, /* 1: Check the schema cookie */
  64. {OP_Integer, 0, 0, 0}, /* 2: Database number */
  65. /* One of the following two instructions is replaced by an
  66. ** OP_Noop before exection.
  67. */
  68. {OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */
  69. {OP_OpenWrite, 0, 0, 0}, /* 4: Open cursor 0 for read/write */
  70. {OP_SetNumColumns, 0, 0, 0}, /* 5: Num cols for cursor */
  71. {OP_Variable, 1, 0, 0}, /* 6: Push the rowid to the stack */
  72. {OP_NotExists, 0, 10, 0}, /* 7: Seek the cursor */
  73. {OP_Column, 0, 0, 0}, /* 8 */
  74. {OP_Callback, 0, 0, 0}, /* 9 */
  75. {OP_Close, 0, 0, 0}, /* 10 */
  76. {OP_Halt, 0, 0, 0}, /* 11 */
  77. };
  78. Vdbe *v = 0;
  79. int rc = SQLITE_OK;
  80. char zErr[128];
  81. zErr[0] = 0;
  82. sqlite3_mutex_enter(db->mutex);
  83. do {
  84. Parse sParse;
  85. Table *pTab;
  86. memset(&sParse, 0, sizeof(Parse));
  87. sParse.db = db;
  88. rc = sqlite3SafetyOn(db);
  89. if( rc!=SQLITE_OK ){
  90. sqlite3_mutex_leave(db->mutex);
  91. return rc;
  92. }
  93. sqlite3BtreeEnterAll(db);
  94. pTab = sqlite3LocateTable(&sParse, zTable, zDb);
  95. if( !pTab ){
  96. if( sParse.zErrMsg ){
  97. sqlite3_snprintf(sizeof(zErr), zErr, "%s", sParse.zErrMsg);
  98. }
  99. sqlite3_free(sParse.zErrMsg);
  100. rc = SQLITE_ERROR;
  101. sqlite3SafetyOff(db);
  102. sqlite3BtreeLeaveAll(db);
  103. goto blob_open_out;
  104. }
  105. /* Now search pTab for the exact column. */
  106. for(iCol=0; iCol < pTab->nCol; iCol++) {
  107. if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){
  108. break;
  109. }
  110. }
  111. if( iCol==pTab->nCol ){
  112. sqlite3_snprintf(sizeof(zErr), zErr, "no such column: \"%s\"", zColumn);
  113. rc = SQLITE_ERROR;
  114. sqlite3SafetyOff(db);
  115. sqlite3BtreeLeaveAll(db);
  116. goto blob_open_out;
  117. }
  118. /* If the value is being opened for writing, check that the
  119. ** column is not indexed. It is against the rules to open an
  120. ** indexed column for writing.
  121. */
  122. if( flags ){
  123. Index *pIdx;
  124. for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
  125. int j;
  126. for(j=0; j<pIdx->nColumn; j++){
  127. if( pIdx->aiColumn[j]==iCol ){
  128. sqlite3_snprintf(sizeof(zErr), zErr,
  129. "cannot open indexed column for writing");
  130. rc = SQLITE_ERROR;
  131. sqlite3SafetyOff(db);
  132. sqlite3BtreeLeaveAll(db);
  133. goto blob_open_out;
  134. }
  135. }
  136. }
  137. }
  138. v = sqlite3VdbeCreate(db);
  139. if( v ){
  140. int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  141. sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob);
  142. /* Configure the OP_Transaction */
  143. sqlite3VdbeChangeP1(v, 0, iDb);
  144. sqlite3VdbeChangeP2(v, 0, (flags ? 1 : 0));
  145. /* Configure the OP_VerifyCookie */
  146. sqlite3VdbeChangeP1(v, 1, iDb);
  147. sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie);
  148. /* Make sure a mutex is held on the table to be accessed */
  149. sqlite3VdbeUsesBtree(v, iDb);
  150. /* Configure the db number pushed onto the stack */
  151. sqlite3VdbeChangeP1(v, 2, iDb);
  152. /* Remove either the OP_OpenWrite or OpenRead. Set the P2
  153. ** parameter of the other to pTab->tnum.
  154. */
  155. sqlite3VdbeChangeToNoop(v, (flags ? 3 : 4), 1);
  156. sqlite3VdbeChangeP2(v, (flags ? 4 : 3), pTab->tnum);
  157. /* Configure the OP_SetNumColumns. Configure the cursor to
  158. ** think that the table has one more column than it really
  159. ** does. An OP_Column to retrieve this imaginary column will
  160. ** always return an SQL NULL. This is useful because it means
  161. ** we can invoke OP_Column to fill in the vdbe cursors type
  162. ** and offset cache without causing any IO.
  163. */
  164. sqlite3VdbeChangeP2(v, 5, pTab->nCol+1);
  165. if( !db->mallocFailed ){
  166. sqlite3VdbeMakeReady(v, 1, 0, 1, 0);
  167. }
  168. }
  169. sqlite3BtreeLeaveAll(db);
  170. rc = sqlite3SafetyOff(db);
  171. if( rc!=SQLITE_OK || db->mallocFailed ){
  172. goto blob_open_out;
  173. }
  174. sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow);
  175. rc = sqlite3_step((sqlite3_stmt *)v);
  176. if( rc!=SQLITE_ROW ){
  177. nAttempt++;
  178. rc = sqlite3_finalize((sqlite3_stmt *)v);
  179. sqlite3_snprintf(sizeof(zErr), zErr, sqlite3_errmsg(db));
  180. v = 0;
  181. }
  182. } while( nAttempt<5 && rc==SQLITE_SCHEMA );
  183. if( rc==SQLITE_ROW ){
  184. /* The row-record has been opened successfully. Check that the
  185. ** column in question contains text or a blob. If it contains
  186. ** text, it is up to the caller to get the encoding right.
  187. */
  188. Incrblob *pBlob;
  189. u32 type = v->apCsr[0]->aType[iCol];
  190. if( type<12 ){
  191. sqlite3_snprintf(sizeof(zErr), zErr, "cannot open value of type %s",
  192. type==0?"null": type==7?"real": "integer"
  193. );
  194. rc = SQLITE_ERROR;
  195. goto blob_open_out;
  196. }
  197. pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
  198. if( db->mallocFailed ){
  199. sqlite3_free(pBlob);
  200. goto blob_open_out;
  201. }
  202. pBlob->flags = flags;
  203. pBlob->pCsr = v->apCsr[0]->pCursor;
  204. sqlite3BtreeEnterCursor(pBlob->pCsr);
  205. sqlite3BtreeCacheOverflow(pBlob->pCsr);
  206. sqlite3BtreeLeaveCursor(pBlob->pCsr);
  207. pBlob->pStmt = (sqlite3_stmt *)v;
  208. pBlob->iOffset = v->apCsr[0]->aOffset[iCol];
  209. pBlob->nByte = sqlite3VdbeSerialTypeLen(type);
  210. pBlob->db = db;
  211. *ppBlob = (sqlite3_blob *)pBlob;
  212. rc = SQLITE_OK;
  213. }else if( rc==SQLITE_OK ){
  214. sqlite3_snprintf(sizeof(zErr), zErr, "no such rowid: %lld", iRow);
  215. rc = SQLITE_ERROR;
  216. }
  217. blob_open_out:
  218. zErr[sizeof(zErr)-1] = '\0';
  219. if( rc!=SQLITE_OK || db->mallocFailed ){
  220. sqlite3_finalize((sqlite3_stmt *)v);
  221. }
  222. sqlite3Error(db, rc, (rc==SQLITE_OK?0:zErr));
  223. rc = sqlite3ApiExit(db, rc);
  224. sqlite3_mutex_leave(db->mutex);
  225. return rc;
  226. }
  227. /*
  228. ** Close a blob handle that was previously created using
  229. ** sqlite3_blob_open().
  230. */
  231. int sqlite3_blob_close(sqlite3_blob *pBlob){
  232. Incrblob *p = (Incrblob *)pBlob;
  233. int rc;
  234. rc = sqlite3_finalize(p->pStmt);
  235. sqlite3_free(p);
  236. return rc;
  237. }
  238. /*
  239. ** Perform a read or write operation on a blob
  240. */
  241. static int blobReadWrite(
  242. sqlite3_blob *pBlob,
  243. void *z,
  244. int n,
  245. int iOffset,
  246. int (*xCall)(BtCursor*, u32, u32, void*)
  247. ){
  248. int rc;
  249. Incrblob *p = (Incrblob *)pBlob;
  250. Vdbe *v;
  251. sqlite3 *db = p->db;
  252. /* Request is out of range. Return a transient error. */
  253. if( (iOffset+n)>p->nByte ){
  254. return SQLITE_ERROR;
  255. }
  256. sqlite3_mutex_enter(db->mutex);
  257. /* If there is no statement handle, then the blob-handle has
  258. ** already been invalidated. Return SQLITE_ABORT in this case.
  259. */
  260. v = (Vdbe*)p->pStmt;
  261. if( v==0 ){
  262. rc = SQLITE_ABORT;
  263. }else{
  264. /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
  265. ** returned, clean-up the statement handle.
  266. */
  267. assert( db == v->db );
  268. sqlite3BtreeEnterCursor(p->pCsr);
  269. rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
  270. sqlite3BtreeLeaveCursor(p->pCsr);
  271. if( rc==SQLITE_ABORT ){
  272. sqlite3VdbeFinalize(v);
  273. p->pStmt = 0;
  274. }else{
  275. db->errCode = rc;
  276. v->rc = rc;
  277. }
  278. }
  279. rc = sqlite3ApiExit(db, rc);
  280. sqlite3_mutex_leave(db->mutex);
  281. return rc;
  282. }
  283. /*
  284. ** Read data from a blob handle.
  285. */
  286. int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
  287. return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData);
  288. }
  289. /*
  290. ** Write data to a blob handle.
  291. */
  292. int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
  293. return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
  294. }
  295. /*
  296. ** Query a blob handle for the size of the data.
  297. **
  298. ** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
  299. ** so no mutex is required for access.
  300. */
  301. int sqlite3_blob_bytes(sqlite3_blob *pBlob){
  302. Incrblob *p = (Incrblob *)pBlob;
  303. return p->nByte;
  304. }
  305. #endif /* #ifndef SQLITE_OMIT_INCRBLOB */