/ Changes On Branch sqlite3_blob_reset
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch sqlite3_blob_reset Excluding Merge-Ins

This is equivalent to a diff from 97ccf3e4de to 61bd2a885d

2017-02-04
17:33
Allow sqlite3session_apply() to apply changesets to tables that have been extended using ALTER TABLE ADD COLUMN. (check-in: b20ff81ff9 user: dan tags: trunk)
15:29
Merge recent trunk enhancements. (check-in: 6c3f09028f user: drh tags: apple-osx)
14:30
Merge the latest trunk changes, especially the RTREE enhancement to use sqlite3_blob objects. (Leaf check-in: 61bd2a885d user: drh tags: sqlite3_blob_reset)
14:24
In RTREE, use an sqlite3_blob object rather than an sqlite3_stmt object for reading content out of the %_node shadow table. (check-in: 97ccf3e4de user: drh tags: trunk)
13:12
Close sqlite3_blob objects on xSync rather than waiting until xCommit. (Closed-Leaf check-in: 95ee745fce user: drh tags: rtree-blob-agressive-release)
2017-02-03
20:54
Improved performance and stack usage when processing VALUES clauses with a very large number of rows. (check-in: 5706d4708a user: drh tags: trunk)
2017-02-02
23:57
Add the sqlite3_blob_reset() interface. Enhance the behavior of sqlite3_blob objects so that they can go active again after encountering an error by rerunning sqlite3_blob_reopen(). More work needed on the documentation. (check-in: 53b77838f0 user: drh tags: sqlite3_blob_reset)

Changes to src/sqlite.h.in.

  6134   6134   **
  6135   6135   ** When the virtual-table mechanism stabilizes, we will declare the
  6136   6136   ** interface fixed, support it indefinitely, and remove this comment.
  6137   6137   */
  6138   6138   
  6139   6139   /*
  6140   6140   ** CAPI3REF: A Handle To An Open BLOB
  6141         -** KEYWORDS: {BLOB handle} {BLOB handles}
         6141  +** KEYWORDS: {BLOB handle} {BLOB handles} {sqlite3_blob object}
  6142   6142   **
  6143         -** An instance of this object represents an open BLOB on which
  6144         -** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
         6143  +** An instance of this object represents a connection to a single
         6144  +** column in a single row of a table that holds either a BLOB or string
         6145  +** and on which [sqlite3_blob_open | incremental BLOB I/O] can be performed.
         6146  +**
  6145   6147   ** ^Objects of this type are created by [sqlite3_blob_open()]
  6146   6148   ** and destroyed by [sqlite3_blob_close()].
  6147   6149   ** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces
  6148   6150   ** can be used to read or write small subsections of the BLOB.
  6149   6151   ** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes.
         6152  +**
         6153  +** An sqlite3_blob object can be in two states: ACTIVE and RESET.  When in
         6154  +** the ACTIVE state, the object is pointing to a specific entry and is
         6155  +** ready to do I/O.  When RESET, the sqlite3_blob object is in standby mode,
         6156  +** is not associated with any particular row of its table, 
         6157  +** and is not available for I/O.
         6158  +**
         6159  +** The sqlite3_blob object does not contain a mutex and so a single
         6160  +** sqlite3_blob object may not be safely used by multiple threads
         6161  +** concurrently.
  6150   6162   */
  6151   6163   typedef struct sqlite3_blob sqlite3_blob;
  6152   6164   
  6153   6165   /*
  6154   6166   ** CAPI3REF: Open A BLOB For Incremental I/O
  6155   6167   ** METHOD: sqlite3
  6156   6168   ** CONSTRUCTOR: sqlite3_blob
  6157   6169   **
  6158         -** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
  6159         -** in row iRow, column zColumn, table zTable in database zDb;
         6170  +** ^(This interfaces creates an sqlite3_blob object pointing to the string
         6171  +** or BLOB located in row iRow, column zColumn, table zTable in database zDb;
  6160   6172   ** in other words, the same BLOB that would be selected by:
  6161   6173   **
  6162   6174   ** <pre>
  6163   6175   **     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
  6164   6176   ** </pre>)^
  6165   6177   **
  6166   6178   ** ^(Parameter zDb is not the filename that contains the database, but 
................................................................................
  6169   6181   ** For the main database file, the database name is "main". For TEMP
  6170   6182   ** tables, the database name is "temp".)^
  6171   6183   **
  6172   6184   ** ^If the flags parameter is non-zero, then the BLOB is opened for read
  6173   6185   ** and write access. ^If the flags parameter is zero, the BLOB is opened for
  6174   6186   ** read-only access.
  6175   6187   **
  6176         -** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
  6177         -** in *ppBlob. Otherwise an [error code] is returned and, unless the error
  6178         -** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
  6179         -** the API is not misused, it is always safe to call [sqlite3_blob_close()] 
         6188  +** ^(On success, [SQLITE_OK] is returned and the new [sqlite3_blob object]
         6189  +** is stored in *ppBlob. Otherwise an [error code] is returned and
         6190  +** *ppBlob is set to NULL.)^ ^Because *ppBlob is always set to either a
         6191  +** valid sqlite3_blob object or NULL
         6192  +** it is always safe to call [sqlite3_blob_close()] 
  6180   6193   ** on *ppBlob after this function it returns.
  6181   6194   **
  6182   6195   ** This function fails with SQLITE_ERROR if any of the following are true:
  6183   6196   ** <ul>
  6184   6197   **   <li> ^(Database zDb does not exist)^, 
  6185   6198   **   <li> ^(Table zTable does not exist within database zDb)^, 
  6186   6199   **   <li> ^(Table zTable is a WITHOUT ROWID table)^, 
................................................................................
  6204   6217   ** [sqlite3_blob_write()].  The [BLOB handle] can be moved to a
  6205   6218   ** different row of the same table using the [sqlite3_blob_reopen()]
  6206   6219   ** interface.  However, the column, table, or database of a [BLOB handle]
  6207   6220   ** cannot be changed after the [BLOB handle] is opened.
  6208   6221   **
  6209   6222   ** ^(If the row that a BLOB handle points to is modified by an
  6210   6223   ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
  6211         -** then the BLOB handle is marked as "expired".
         6224  +** then the BLOB handle is marked as "expired" and cannot be used
         6225  +** successfully with first being [sqlite3_blob_reopen|reopened].
  6212   6226   ** This is true if any column of the row is changed, even a column
  6213   6227   ** other than the one the BLOB handle is open on.)^
  6214   6228   ** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
  6215   6229   ** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
  6216   6230   ** ^(Changes written into a BLOB prior to the BLOB expiring are not
  6217   6231   ** rolled back by the expiration of the BLOB.  Such changes will eventually
  6218   6232   ** commit if the transaction continues to completion.)^
  6219   6233   **
  6220   6234   ** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
  6221   6235   ** the opened blob.  ^The size of a blob may not be changed by this
  6222   6236   ** interface.  Use the [UPDATE] SQL command to change the size of a
  6223         -** blob.
         6237  +** blob.  The [sqlite3_blob_bytes()] interface returns an arbitrary
         6238  +** number when used on an expired sqlite3_blob object.
  6224   6239   **
  6225   6240   ** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
  6226   6241   ** and the built-in [zeroblob] SQL function may be used to create a 
  6227   6242   ** zero-filled blob to read or write using the incremental-blob interface.
  6228   6243   **
  6229   6244   ** To avoid a resource leak, every open [BLOB handle] should eventually
  6230   6245   ** be released by a call to [sqlite3_blob_close()].
  6231   6246   **
  6232   6247   ** See also: [sqlite3_blob_close()],
  6233   6248   ** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
  6234         -** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
         6249  +** [sqlite3_blob_bytes()], [sqlite3_blob_write()],
         6250  +** [sqlite3_blob_reset()].
  6235   6251   */
  6236   6252   int sqlite3_blob_open(
  6237   6253     sqlite3*,
  6238   6254     const char *zDb,
  6239   6255     const char *zTable,
  6240   6256     const char *zColumn,
  6241   6257     sqlite3_int64 iRow,
  6242   6258     int flags,
  6243   6259     sqlite3_blob **ppBlob
  6244   6260   );
  6245   6261   
  6246   6262   /*
  6247         -** CAPI3REF: Move a BLOB Handle to a New Row
         6263  +** CAPI3REF: Move an sqlite3_blob object to a New Row
  6248   6264   ** METHOD: sqlite3_blob
  6249   6265   **
  6250         -** ^This function is used to move an existing [BLOB handle] so that it points
         6266  +** ^This function updates an existing [sqlite3_blob object] so that it points
  6251   6267   ** to a different row of the same database table. ^The new row is identified
  6252   6268   ** by the rowid value passed as the second argument. Only the row can be
  6253   6269   ** changed. ^The database, table and column on which the blob handle is open
  6254         -** remain the same. Moving an existing [BLOB handle] to a new row is
         6270  +** remain the same. Moving an existing [sqlite3_blob object] to a new row is
  6255   6271   ** faster than closing the existing handle and opening a new one.
  6256   6272   **
  6257   6273   ** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
  6258   6274   ** it must exist and there must be either a blob or text value stored in
  6259   6275   ** the nominated column.)^ ^If the new row is not present in the table, or if
  6260   6276   ** it does not contain a blob or text value, or if another error occurs, an
  6261         -** SQLite error code is returned and the blob handle is considered aborted.
  6262         -** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or
  6263         -** [sqlite3_blob_reopen()] on an aborted blob handle immediately return
  6264         -** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
         6277  +** SQLite error code is returned and the [sqlite3_blob object] is changed
         6278  +** to the RESET state.
         6279  +** ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
  6265   6280   ** always returns zero.
  6266   6281   **
  6267   6282   ** ^This function sets the database handle error code and message.
  6268   6283   */
  6269   6284   int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
  6270   6285   
  6271   6286   /*
  6272         -** CAPI3REF: Close A BLOB Handle
         6287  +** CAPI3REF: Close an sqlite3_blob object
  6273   6288   ** DESTRUCTOR: sqlite3_blob
  6274   6289   **
  6275         -** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
         6290  +** ^This function is the destructor for an [sqlite3_blob object]. 
         6291  +** ^(The [sqlite3_blob object] is closed
  6276   6292   ** unconditionally.  Even if this routine returns an error code, the 
  6277         -** handle is still closed.)^
         6293  +** object is still closed.)^
  6278   6294   **
  6279         -** ^If the blob handle being closed was opened for read-write access, and if
  6280         -** the database is in auto-commit mode and there are no other open read-write
         6295  +** ^If the sqlite3_blob object being closed was opened for read-write access,
         6296  +** and is in the ACTIVE state,
         6297  +** and if the database is in auto-commit mode and there are no other open 
         6298  +** read-write
  6281   6299   ** blob handles or active write statements, the current transaction is
  6282   6300   ** committed. ^If an error occurs while committing the transaction, an error
  6283   6301   ** code is returned and the transaction rolled back.
  6284   6302   **
  6285         -** Calling this function with an argument that is not a NULL pointer or an
  6286         -** open blob handle results in undefined behaviour. ^Calling this routine 
         6303  +** Calling this function with an argument that is not a NULL pointer or a
         6304  +** valid sqlite3_blob object pointer results in undefined behaviour. 
         6305  +** ^Calling this routine 
  6287   6306   ** with a null pointer (such as would be returned by a failed call to 
  6288   6307   ** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
  6289         -** is passed a valid open blob handle, the values returned by the 
         6308  +** is passed a valid sqlite3_blob objecct pointer, the values returned by the 
  6290   6309   ** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
  6291   6310   */
  6292   6311   int sqlite3_blob_close(sqlite3_blob *);
  6293   6312   
  6294   6313   /*
  6295         -** CAPI3REF: Return The Size Of An Open BLOB
         6314  +** CAPI3REF: Reset an sqlite3_blob object
         6315  +** METHOD: sqlite3_blob
         6316  +**
         6317  +** ^This function changes an [sqlite3_blob object] to the RESET state.
         6318  +** ^If the [sqlite3_blob object] was already in the RESET state, then this
         6319  +** routine is a harmless no-op.
         6320  +*/
         6321  +int sqlite3_blob_reset(sqlite3_blob *);
         6322  +
         6323  +/*
         6324  +** CAPI3REF: Return The Size Of A BLOB
  6296   6325   ** METHOD: sqlite3_blob
  6297   6326   **
  6298         -** ^Returns the size in bytes of the BLOB accessible via the 
  6299         -** successfully opened [BLOB handle] in its only argument.  ^The
         6327  +** ^Returns the size in bytes of the BLOB or string accessible via the 
         6328  +** ACTIVE [sqlite3_blob object] in its only argument.  ^The
  6300   6329   ** incremental blob I/O routines can only read or overwriting existing
  6301         -** blob content; they cannot change the size of a blob.
         6330  +** content; they cannot change the size of a blob or string.
  6302   6331   **
  6303         -** This routine only works on a [BLOB handle] which has been created
         6332  +** This routine only works on an [sqlite3_blob object] that has been created
  6304   6333   ** by a prior successful call to [sqlite3_blob_open()] and which has not
  6305   6334   ** been closed by [sqlite3_blob_close()].  Passing any other pointer in
  6306   6335   ** to this routine results in undefined and probably undesirable behavior.
  6307   6336   */
  6308   6337   int sqlite3_blob_bytes(sqlite3_blob *);
  6309   6338   
  6310   6339   /*
  6311   6340   ** CAPI3REF: Read Data From A BLOB Incrementally
  6312   6341   ** METHOD: sqlite3_blob
  6313   6342   **
  6314         -** ^(This function is used to read data from an open [BLOB handle] into a
  6315         -** caller-supplied buffer. N bytes of data are copied into buffer Z
  6316         -** from the open BLOB, starting at offset iOffset.)^
         6343  +** ^(This function is used to read data from string or BLOB that an
         6344  +** [sqlite3_blob object] is pointing to into a caller-supplied buffer. 
         6345  +** N bytes of data are copied into buffer Z starting at offset iOffset.)^
  6317   6346   **
  6318   6347   ** ^If offset iOffset is less than N bytes from the end of the BLOB,
  6319   6348   ** [SQLITE_ERROR] is returned and no data is read.  ^If N or iOffset is
  6320   6349   ** less than zero, [SQLITE_ERROR] is returned and no data is read.
  6321   6350   ** ^The size of the blob (and hence the maximum value of N+iOffset)
  6322   6351   ** can be determined using the [sqlite3_blob_bytes()] interface.
  6323   6352   **
  6324         -** ^An attempt to read from an expired [BLOB handle] fails with an
         6353  +** ^An attempt to read from an [sqlite3_blob object] that is in the RESET
         6354  +** state, or from a database row that has changed since the most recent
         6355  +** call to [sqlite3_blob_open()] or [sqlite3_blob_reopen()] fails with an
  6325   6356   ** error code of [SQLITE_ABORT].
  6326   6357   **
  6327   6358   ** ^(On success, sqlite3_blob_read() returns SQLITE_OK.
  6328   6359   ** Otherwise, an [error code] or an [extended error code] is returned.)^
  6329   6360   **
  6330         -** This routine only works on a [BLOB handle] which has been created
  6331         -** by a prior successful call to [sqlite3_blob_open()] and which has not
  6332         -** been closed by [sqlite3_blob_close()].  Passing any other pointer in
  6333         -** to this routine results in undefined and probably undesirable behavior.
  6334         -**
  6335   6361   ** See also: [sqlite3_blob_write()].
  6336   6362   */
  6337   6363   int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
  6338   6364   
  6339   6365   /*
  6340   6366   ** CAPI3REF: Write Data Into A BLOB Incrementally
  6341   6367   ** METHOD: sqlite3_blob
  6342   6368   **
  6343         -** ^(This function is used to write data into an open [BLOB handle] from a
  6344         -** caller-supplied buffer. N bytes of data are copied from the buffer Z
  6345         -** into the open BLOB, starting at offset iOffset.)^
         6369  +** ^(This function is used to write data from a caller-supplied buffer
         6370  +** into a BLOB or string pointed to by an [sqlite3_blob object].
         6371  +** N bytes of data are copied from the buffer Z
         6372  +** into the BLOB or string, starting at offset iOffset.)^
  6346   6373   **
  6347   6374   ** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
  6348   6375   ** Otherwise, an  [error code] or an [extended error code] is returned.)^
  6349   6376   ** ^Unless SQLITE_MISUSE is returned, this function sets the 
  6350   6377   ** [database connection] error code and message accessible via 
  6351   6378   ** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 
  6352   6379   **
................................................................................
  6358   6385   ** not possible to increase the size of a BLOB using this API.
  6359   6386   ** ^If offset iOffset is less than N bytes from the end of the BLOB,
  6360   6387   ** [SQLITE_ERROR] is returned and no data is written. The size of the 
  6361   6388   ** BLOB (and hence the maximum value of N+iOffset) can be determined 
  6362   6389   ** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less 
  6363   6390   ** than zero [SQLITE_ERROR] is returned and no data is written.
  6364   6391   **
  6365         -** ^An attempt to write to an expired [BLOB handle] fails with an
  6366         -** error code of [SQLITE_ABORT].  ^Writes to the BLOB that occurred
  6367         -** before the [BLOB handle] expired are not rolled back by the
  6368         -** expiration of the handle, though of course those changes might
  6369         -** have been overwritten by the statement that expired the BLOB handle
  6370         -** or by other independent statements.
  6371         -**
  6372         -** This routine only works on a [BLOB handle] which has been created
  6373         -** by a prior successful call to [sqlite3_blob_open()] and which has not
  6374         -** been closed by [sqlite3_blob_close()].  Passing any other pointer in
  6375         -** to this routine results in undefined and probably undesirable behavior.
         6392  +** ^An attempt to write into an [sqlite3_blob object] that is in the RESET
         6393  +** state, or into a database row that has changed since the most recent
         6394  +** call to [sqlite3_blob_open()] or [sqlite3_blob_reopen()] fails with an
         6395  +** error code of [SQLITE_ABORT].
  6376   6396   **
  6377   6397   ** See also: [sqlite3_blob_read()].
  6378   6398   */
  6379   6399   int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
  6380   6400   
  6381   6401   /*
  6382   6402   ** CAPI3REF: Virtual File System Objects

Changes to src/vdbeblob.c.

    19     19   #ifndef SQLITE_OMIT_INCRBLOB
    20     20   
    21     21   /*
    22     22   ** Valid sqlite3_blob* handles point to Incrblob structures.
    23     23   */
    24     24   typedef struct Incrblob Incrblob;
    25     25   struct Incrblob {
    26         -  int nByte;              /* Size of open blob, in bytes */
           26  +  int nByte;              /* Size of open blob if ACTIVE. -1 if RESET */
    27     27     int iOffset;            /* Byte offset of blob in cursor data */
    28     28     u16 iCol;               /* Table column this handle is open on */
    29     29     BtCursor *pCsr;         /* Cursor pointing at blob row */
    30     30     sqlite3_stmt *pStmt;    /* Statement holding cursor open */
    31     31     sqlite3 *db;            /* The associated database */
    32     32     char *zDb;              /* Database name */
    33     33     Table *pTab;            /* Table object */
    34     34   };
    35         -
    36     35   
    37     36   /*
    38     37   ** This function is used by both blob_open() and blob_reopen(). It seeks
    39     38   ** the b-tree cursor associated with blob handle p to point to row iRow.
    40     39   ** If successful, SQLITE_OK is returned and subsequent calls to
    41     40   ** sqlite3_blob_read() or sqlite3_blob_write() access the specified row.
    42     41   **
................................................................................
    78     77       testcase( pC->nHdrParsed==p->iCol );
    79     78       testcase( pC->nHdrParsed==p->iCol+1 );
    80     79       if( type<12 ){
    81     80         zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
    82     81             type==0?"null": type==7?"real": "integer"
    83     82         );
    84     83         rc = SQLITE_ERROR;
    85         -      sqlite3_finalize(p->pStmt);
    86         -      p->pStmt = 0;
           84  +      sqlite3_reset(p->pStmt);
           85  +      p->nByte = -1;
    87     86       }else{
    88     87         p->iOffset = pC->aType[p->iCol + pC->nField];
    89     88         p->nByte = sqlite3VdbeSerialTypeLen(type);
    90     89         p->pCsr =  pC->uc.pCursor;
    91     90         sqlite3BtreeIncrblobCursor(p->pCsr);
    92     91       }
    93     92     }
    94     93   
    95     94     if( rc==SQLITE_ROW ){
    96     95       rc = SQLITE_OK;
    97         -  }else if( p->pStmt ){
    98         -    rc = sqlite3_finalize(p->pStmt);
    99         -    p->pStmt = 0;
           96  +  }else if( p->nByte>=0 ){
           97  +    rc = sqlite3_reset(p->pStmt);
           98  +    p->nByte = -1;
   100     99       if( rc==SQLITE_OK ){
   101    100         zErr = sqlite3MPrintf(p->db, "no such rowid: %lld", iRow);
   102    101         rc = SQLITE_ERROR;
   103    102       }else{
   104    103         zErr = sqlite3MPrintf(p->db, "%s", sqlite3_errmsg(p->db));
   105    104       }
   106    105     }
................................................................................
   153    152     if( !pParse ) goto blob_open_out;
   154    153   
   155    154     do {
   156    155       memset(pParse, 0, sizeof(Parse));
   157    156       pParse->db = db;
   158    157       sqlite3DbFree(db, zErr);
   159    158       zErr = 0;
          159  +    sqlite3_finalize(pBlob->pStmt);
   160    160   
   161    161       sqlite3BtreeEnterAll(db);
   162    162       pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
   163    163       if( pTab && IsVirtual(pTab) ){
   164    164         pTab = 0;
   165    165         sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable);
   166    166       }
................................................................................
   320    320           pParse->nTab = 1;
   321    321           sqlite3VdbeMakeReady(v, pParse);
   322    322         }
   323    323       }
   324    324      
   325    325       pBlob->iCol = iCol;
   326    326       pBlob->db = db;
          327  +    pBlob->nByte = 0;
   327    328       sqlite3BtreeLeaveAll(db);
   328    329       if( db->mallocFailed ){
   329    330         goto blob_open_out;
   330    331       }
   331    332       rc = blobSeekToRow(pBlob, iRow, &zErr);
   332    333     } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
   333    334   
................................................................................
   355    356     Incrblob *p = (Incrblob *)pBlob;
   356    357     int rc;
   357    358     sqlite3 *db;
   358    359   
   359    360     if( p ){
   360    361       db = p->db;
   361    362       sqlite3_mutex_enter(db->mutex);
   362         -    rc = sqlite3_finalize(p->pStmt);
          363  +    rc = sqlite3VdbeFinalize((Vdbe*)p->pStmt);
   363    364       sqlite3DbFree(db, p);
   364    365       sqlite3_mutex_leave(db->mutex);
   365    366     }else{
   366    367       rc = SQLITE_OK;
   367    368     }
   368    369     return rc;
   369    370   }
................................................................................
   380    381   ){
   381    382     int rc;
   382    383     Incrblob *p = (Incrblob *)pBlob;
   383    384     Vdbe *v;
   384    385     sqlite3 *db;
   385    386   
   386    387     if( p==0 ) return SQLITE_MISUSE_BKPT;
          388  +  if( p->nByte<0 ){
          389  +    /* The blob handle is in the RESET state.  Always return SQLITE_ABORT. */
          390  +    return SQLITE_ABORT;
          391  +  }
   387    392     db = p->db;
   388    393     sqlite3_mutex_enter(db->mutex);
   389    394     v = (Vdbe*)p->pStmt;
   390    395   
   391    396     if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){
   392    397       /* Request is out of range. Return a transient error. */
   393    398       rc = SQLITE_ERROR;
   394         -  }else if( v==0 ){
   395         -    /* If there is no statement handle, then the blob-handle has
   396         -    ** already been invalidated. Return SQLITE_ABORT in this case.
   397         -    */
   398         -    rc = SQLITE_ABORT;
   399    399     }else{
   400    400       /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
   401    401       ** returned, clean-up the statement handle.
   402    402       */
   403    403       assert( db == v->db );
   404    404       sqlite3BtreeEnterCursor(p->pCsr);
   405    405   
................................................................................
   425    425         );
   426    426       }
   427    427   #endif
   428    428   
   429    429       rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
   430    430       sqlite3BtreeLeaveCursor(p->pCsr);
   431    431       if( rc==SQLITE_ABORT ){
   432         -      sqlite3VdbeFinalize(v);
   433         -      p->pStmt = 0;
          432  +      sqlite3_reset(p->pStmt);
          433  +      p->nByte = -1;
   434    434       }else{
   435    435         v->rc = rc;
   436    436       }
   437    437     }
   438    438     sqlite3Error(db, rc);
   439    439     rc = sqlite3ApiExit(db, rc);
   440    440     sqlite3_mutex_leave(db->mutex);
................................................................................
   454    454   int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
   455    455     return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
   456    456   }
   457    457   
   458    458   /*
   459    459   ** Query a blob handle for the size of the data.
   460    460   **
   461         -** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
   462         -** so no mutex is required for access.
          461  +** The Incrblob.nByte field is fixed for as long as the sqlite3_blob
          462  +** object is pointing to the same row, so no mutex is required for access.
          463  +**
          464  +** When the sqlite3_blob interface was first designed in 2007, we specified
          465  +** that sqlite3_blob_bytes() returned 0 when in the RESET state.  It would
          466  +** have been better to return -1 in order to distinguish a RESET blob handle
          467  +** from an ACTIVE blob handle pointing to a zero-length string or blob.
          468  +** But, sadly, we cannot change that now without breaking compatibility.
          469  +** So 0 is returned for RESET blob handles and for ACTIVE blob handles
          470  +** pointing to zero-length blobs.
   463    471   */
   464    472   int sqlite3_blob_bytes(sqlite3_blob *pBlob){
   465    473     Incrblob *p = (Incrblob *)pBlob;
   466         -  return (p && p->pStmt) ? p->nByte : 0;
          474  +  return (p && p->pStmt && p->nByte>0) ? p->nByte : 0;
   467    475   }
   468    476   
          477  +/*
          478  +** Move the sqlite3_blob object to the RESET state.  This releases
          479  +** any locks and gets the object out of the way of commits and
          480  +** rollbacks.
          481  +*/
          482  +int sqlite3_blob_reset(sqlite3_blob *pBlob){
          483  +  Incrblob *p = (Incrblob *)pBlob;
          484  +  if( p->nByte>=0 ){
          485  +    sqlite3_reset(p->pStmt);
          486  +    p->nByte = -1;
          487  +  }
          488  +  return SQLITE_OK;
          489  +}  
          490  +
   469    491   /*
   470    492   ** Move an existing blob handle to point to a different row of the same
   471    493   ** database table.
   472    494   **
   473    495   ** If an error occurs, or if the specified row does not exist or does not
   474    496   ** contain a blob or text value, then an error code is returned and the
   475    497   ** database handle error code and message set. If this happens, then all 
................................................................................
   476    498   ** subsequent calls to sqlite3_blob_xxx() functions (except blob_close()) 
   477    499   ** immediately return SQLITE_ABORT.
   478    500   */
   479    501   int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
   480    502     int rc;
   481    503     Incrblob *p = (Incrblob *)pBlob;
   482    504     sqlite3 *db;
          505  +  char *zErr;
   483    506   
   484    507     if( p==0 ) return SQLITE_MISUSE_BKPT;
   485    508     db = p->db;
   486    509     sqlite3_mutex_enter(db->mutex);
   487    510   
   488         -  if( p->pStmt==0 ){
   489         -    /* If there is no statement handle, then the blob-handle has
   490         -    ** already been invalidated. Return SQLITE_ABORT in this case.
   491         -    */
   492         -    rc = SQLITE_ABORT;
   493         -  }else{
   494         -    char *zErr;
   495         -    rc = blobSeekToRow(p, iRow, &zErr);
   496         -    if( rc!=SQLITE_OK ){
   497         -      sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
   498         -      sqlite3DbFree(db, zErr);
   499         -    }
   500         -    assert( rc!=SQLITE_SCHEMA );
          511  +  rc = blobSeekToRow(p, iRow, &zErr);
          512  +  if( rc!=SQLITE_OK ){
          513  +    sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
          514  +    sqlite3DbFree(db, zErr);
   501    515     }
   502    516   
   503    517     rc = sqlite3ApiExit(db, rc);
   504         -  assert( rc==SQLITE_OK || p->pStmt==0 );
          518  +  assert( rc==SQLITE_OK || p->nByte<0 );
   505    519     sqlite3_mutex_leave(db->mutex);
   506    520     return rc;
   507    521   }
   508    522   
   509    523   #endif /* #ifndef SQLITE_OMIT_INCRBLOB */

Changes to test/e_blobwrite.test.

   137    137   } {}
   138    138   blob_write_error_test 2.3.1 $B 5 $blob 5 \
   139    139       SQLITE_ABORT {callback requested query abort}
   140    140   do_test 2.3.2 {
   141    141     execsql { SELECT 1, 2, 3 }
   142    142     sqlite3_errcode db
   143    143   } {SQLITE_OK}
   144         -blob_write_error_test 2.3.3 $B 5 $blob 5 \
   145         -    SQLITE_ABORT {callback requested query abort}
          144  +#blob_write_error_test 2.3.3 $B 5 $blob 5 \
          145  +#    SQLITE_OK {not an error}
   146    146   sqlite3_blob_close $B
   147    147   
   148    148   # EVIDENCE-OF: R-08382-59936 Writes to the BLOB that occurred before the
   149    149   # BLOB handle expired are not rolled back by the expiration of the
   150    150   # handle, though of course those changes might have been overwritten by
   151    151   # the statement that expired the BLOB handle or by other independent
   152    152   # statements.

Changes to test/incrblob3.test.

    58     58     list [catch {sqlite3_blob_reopen $::blob 3} msg] $msg
    59     59   } {1 SQLITE_ERROR}
    60     60   do_test incrblob3-2.1.2 {
    61     61     list [sqlite3_errcode db] [sqlite3_errmsg db]
    62     62   } {SQLITE_ERROR {no such rowid: 3}}
    63     63   do_test incrblob3-2.1.3 {
    64     64     list [catch {sqlite3_blob_reopen $::blob 1} msg] $msg
    65         -} {1 SQLITE_ABORT}
           65  +} {0 {}}
    66     66   do_test incrblob3-2.1.4 { close $::blob } {}
    67     67   
    68     68   do_execsql_test incrblob3-2.2.1 {
    69     69     INSERT INTO blobs VALUES(3, 42);
    70     70     INSERT INTO blobs VALUES(4, 54.4);
    71     71     INSERT INTO blobs VALUES(5, NULL);
    72     72   }
................................................................................
    81     81     } {1 SQLITE_ERROR}
    82     82     do_test incrblob3-2.2.$tn.2 {
    83     83       list [sqlite3_errcode db] [sqlite3_errmsg db]
    84     84     } "SQLITE_ERROR {cannot open value of type $type}"
    85     85   
    86     86     do_test incrblob3-2.2.$tn.3 {
    87     87       list [catch {sqlite3_blob_reopen $::blob 1} msg] $msg
    88         -  } {1 SQLITE_ABORT}
           88  +  } {0 {}}
    89     89     do_test incrblob3-2.2.$tn.4 {
    90     90       list [catch {sqlite3_blob_read $::blob 0 10} msg] $msg
    91         -  } {1 SQLITE_ABORT}
           91  +  } {0 {hello worl}}
    92     92     do_test incrblob3-2.2.$tn.5 {
    93     93       list [catch {sqlite3_blob_write $::blob 0 "abcd"} msg] $msg
    94         -  } {1 SQLITE_ABORT}
           94  +  } {0 {}}
    95     95     do_test incrblob3-2.2.$tn.6 {
    96     96       sqlite3_blob_bytes $::blob
    97         -  } {0}
           97  +  } {100}
           98  +  do_test incrblob3-2.2.$tn.7 {
           99  +    list [catch {sqlite3_blob_write $::blob 0 "hello"} msg] $msg
          100  +  } {0 {}}
    98    101   
    99         -  do_test incrblob3-2.2.$tn.7 { close $::blob } {}
          102  +  do_test incrblob3-2.2.$tn.8 { close $::blob } {}
   100    103   }
   101    104   
   102    105   # Test that passing NULL to sqlite3_blob_XXX() APIs returns SQLITE_MISUSE.
   103    106   #
   104    107   #   incrblob3-3.1: sqlite3_blob_reopen()
   105    108   #   incrblob3-3.2: sqlite3_blob_read()
   106    109   #   incrblob3-3.3: sqlite3_blob_write()