/ Check-in [999d507b]
Login

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

Overview
Comment:Change sqlite_blob_open() so that it zeros the output pBlob pointer when it fails. The other sqlite3_blob interfaces accept a NULL pointer as input. (CVS 6622)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:999d507b4432b518cfc7e02e5b0a2473cf1980f6
User & Date: drh 2009-05-09 15:17:47
Context
2009-05-09
18:59
Add the SQLITE_TESTCTRL_ASSERT and SQLITE_TESTCTRL_ALWAYS codes for the sqlite3_test_control() interface. (CVS 6623) check-in: 38df91c2 user: drh tags: trunk
15:17
Change sqlite_blob_open() so that it zeros the output pBlob pointer when it fails. The other sqlite3_blob interfaces accept a NULL pointer as input. (CVS 6622) check-in: 999d507b user: drh tags: trunk
00:18
Changes to the trigger.c module that facilitate full coverage testing. (CVS 6621) check-in: 567ccc68 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbeblob.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
81
82
83
84
85
86
87

88
89
90
91
92
93
94
...
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
...
262
263
264
265
266
267
268

269
270
271
272
273



274
275
276
277
278
279
280
...
283
284
285
286
287
288
289
290
291


292
293
294
295
296
297
298
...
340
341
342
343
344
345
346
347
348
349
350
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement incremental BLOB I/O.
**
** $Id: vdbeblob.c,v 1.31 2009/03/24 15:08:10 drh Exp $
*/

#include "sqliteInt.h"
#include "vdbeInt.h"

#ifndef SQLITE_OMIT_INCRBLOB

................................................................................
    {OP_Halt, 0, 0, 0},            /* 9 */
  };

  Vdbe *v = 0;
  int rc = SQLITE_OK;
  char zErr[128];


  zErr[0] = 0;
  sqlite3_mutex_enter(db->mutex);
  do {
    Parse sParse;
    Table *pTab;

    memset(&sParse, 0, sizeof(Parse));
................................................................................

      /* Make sure a mutex is held on the table to be accessed */
      sqlite3VdbeUsesBtree(v, iDb); 

      /* Remove either the OP_OpenWrite or OpenRead. Set the P2 
      ** parameter of the other to pTab->tnum. 
      */

      sqlite3VdbeChangeToNoop(v, (flags ? 2 : 3), 1);
      sqlite3VdbeChangeP2(v, (flags ? 3 : 2), pTab->tnum);
      sqlite3VdbeChangeP3(v, (flags ? 3 : 2), iDb);

      /* Configure the number of columns. Configure the cursor to
      ** think that the table has one more column than it really
      ** does. An OP_Column to retrieve this imaginary column will
      ** always return an SQL NULL. This is useful because it means
      ** we can invoke OP_Column to fill in the vdbe cursors type 
      ** and offset cache without causing any IO.
      */
      sqlite3VdbeChangeP4(v, flags ? 3 : 2, SQLITE_INT_TO_PTR(pTab->nCol+1), P4_INT32);
      sqlite3VdbeChangeP2(v, 6, pTab->nCol);
      if( !db->mallocFailed ){
        sqlite3VdbeMakeReady(v, 1, 1, 1, 0);
      }
    }
   
    sqlite3BtreeLeaveAll(db);
    rc = sqlite3SafetyOff(db);
    if( rc!=SQLITE_OK || db->mallocFailed ){
      goto blob_open_out;
    }

    sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow);
    rc = sqlite3_step((sqlite3_stmt *)v);
    if( rc!=SQLITE_ROW ){
      nAttempt++;
................................................................................
** sqlite3_blob_open().
*/
int sqlite3_blob_close(sqlite3_blob *pBlob){
  Incrblob *p = (Incrblob *)pBlob;
  int rc;
  sqlite3 *db;


  db = p->db;
  sqlite3_mutex_enter(db->mutex);
  rc = sqlite3_finalize(p->pStmt);
  sqlite3DbFree(db, p);
  sqlite3_mutex_leave(db->mutex);



  return rc;
}

/*
** Perform a read or write operation on a blob
*/
static int blobReadWrite(
................................................................................
  int n, 
  int iOffset, 
  int (*xCall)(BtCursor*, u32, u32, void*)
){
  int rc;
  Incrblob *p = (Incrblob *)pBlob;
  Vdbe *v;
  sqlite3 *db = p->db;  



  sqlite3_mutex_enter(db->mutex);
  v = (Vdbe*)p->pStmt;

  if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
    /* Request is out of range. Return a transient error. */
    rc = SQLITE_ERROR;
    sqlite3Error(db, SQLITE_ERROR, 0);
................................................................................
** Query a blob handle for the size of the data.
**
** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
** so no mutex is required for access.
*/
int sqlite3_blob_bytes(sqlite3_blob *pBlob){
  Incrblob *p = (Incrblob *)pBlob;
  return p->nByte;
}

#endif /* #ifndef SQLITE_OMIT_INCRBLOB */







|







 







>







 







>
|
|
|








|








|







 







>
|
|
|
|
|
>
>
>







 







|

>
>







 







|



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
...
348
349
350
351
352
353
354
355
356
357
358
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement incremental BLOB I/O.
**
** $Id: vdbeblob.c,v 1.32 2009/05/09 15:17:47 drh Exp $
*/

#include "sqliteInt.h"
#include "vdbeInt.h"

#ifndef SQLITE_OMIT_INCRBLOB

................................................................................
    {OP_Halt, 0, 0, 0},            /* 9 */
  };

  Vdbe *v = 0;
  int rc = SQLITE_OK;
  char zErr[128];

  *ppBlob = 0;
  zErr[0] = 0;
  sqlite3_mutex_enter(db->mutex);
  do {
    Parse sParse;
    Table *pTab;

    memset(&sParse, 0, sizeof(Parse));
................................................................................

      /* Make sure a mutex is held on the table to be accessed */
      sqlite3VdbeUsesBtree(v, iDb); 

      /* Remove either the OP_OpenWrite or OpenRead. Set the P2 
      ** parameter of the other to pTab->tnum. 
      */
      flags = !!flags;
      sqlite3VdbeChangeToNoop(v, 3 - flags, 1);
      sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum);
      sqlite3VdbeChangeP3(v, 2 + flags, iDb);

      /* Configure the number of columns. Configure the cursor to
      ** think that the table has one more column than it really
      ** does. An OP_Column to retrieve this imaginary column will
      ** always return an SQL NULL. This is useful because it means
      ** we can invoke OP_Column to fill in the vdbe cursors type 
      ** and offset cache without causing any IO.
      */
      sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
      sqlite3VdbeChangeP2(v, 6, pTab->nCol);
      if( !db->mallocFailed ){
        sqlite3VdbeMakeReady(v, 1, 1, 1, 0);
      }
    }
   
    sqlite3BtreeLeaveAll(db);
    rc = sqlite3SafetyOff(db);
    if( NEVER(rc!=SQLITE_OK) || db->mallocFailed ){
      goto blob_open_out;
    }

    sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow);
    rc = sqlite3_step((sqlite3_stmt *)v);
    if( rc!=SQLITE_ROW ){
      nAttempt++;
................................................................................
** sqlite3_blob_open().
*/
int sqlite3_blob_close(sqlite3_blob *pBlob){
  Incrblob *p = (Incrblob *)pBlob;
  int rc;
  sqlite3 *db;

  if( p ){
    db = p->db;
    sqlite3_mutex_enter(db->mutex);
    rc = sqlite3_finalize(p->pStmt);
    sqlite3DbFree(db, p);
    sqlite3_mutex_leave(db->mutex);
  }else{
    rc = SQLITE_OK;
  }
  return rc;
}

/*
** Perform a read or write operation on a blob
*/
static int blobReadWrite(
................................................................................
  int n, 
  int iOffset, 
  int (*xCall)(BtCursor*, u32, u32, void*)
){
  int rc;
  Incrblob *p = (Incrblob *)pBlob;
  Vdbe *v;
  sqlite3 *db;

  if( p==0 ) return SQLITE_MISUSE;
  db = p->db;
  sqlite3_mutex_enter(db->mutex);
  v = (Vdbe*)p->pStmt;

  if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
    /* Request is out of range. Return a transient error. */
    rc = SQLITE_ERROR;
    sqlite3Error(db, SQLITE_ERROR, 0);
................................................................................
** Query a blob handle for the size of the data.
**
** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
** so no mutex is required for access.
*/
int sqlite3_blob_bytes(sqlite3_blob *pBlob){
  Incrblob *p = (Incrblob *)pBlob;
  return p ? p->nByte : 0;
}

#endif /* #ifndef SQLITE_OMIT_INCRBLOB */