SQLite

Check-in [4cd829107c]
Login

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

Overview
Comment:Remove misuse detection from the deprecated sqlite3_transfer_bindings() interface. The code was hard to test and was simply taking up space. (CVS 6476)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4cd829107cc9e94b092490aa821574492292b425
User & Date: drh 2009-04-09 14:02:44.000
Context
2009-04-09
14:27
Provide dummy DWORD arguments to output parameters of GetDiskFreeSpace(A|W), NULL causes access violations on Windows NT 4.0 (CVS 6477) (check-in: 5350a6586c user: chw tags: trunk)
14:02
Remove misuse detection from the deprecated sqlite3_transfer_bindings() interface. The code was hard to test and was simply taking up space. (CVS 6476) (check-in: 4cd829107c user: drh tags: trunk)
01:23
Enhance sqlite3_shutdown() so that it automatically invokes sqlite3_reset_auto_extension(). This is a harmless no-op if applications are already calling sqlite3_reset_auto_extension() prior to sqlite3_shutdown(). And it prevents possible memory corruption if they do not. So it works either way. Most of the changes are to the test cases. (CVS 6475) (check-in: 0c41f7cff4 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/vdbeapi.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
**
** $Id: vdbeapi.c,v 1.158 2009/04/08 23:05:29 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

#if 0 && defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
/*
** The following structure contains pointers to the end points of a







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
**
** $Id: vdbeapi.c,v 1.159 2009/04/09 14:02:44 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

#if 0 && defined(SQLITE_ENABLE_MEMORY_MANAGEMENT)
/*
** The following structure contains pointers to the end points of a
1160
1161
1162
1163
1164
1165
1166
1167
1168

1169
1170
1171
1172
1173
1174
1175
  rc = vdbeUnbind(p, i);
  if( rc==SQLITE_OK ){
    rc = sqlite3VdbeMemCopy(&p->aVar[i-1], pValue);
    if( rc==SQLITE_OK ){
      rc = sqlite3VdbeChangeEncoding(&p->aVar[i-1], ENC(p->db));
    }
    sqlite3_mutex_leave(p->db->mutex);
  }
  rc = sqlite3ApiExit(p->db, rc);

  return rc;
}
int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
  int rc;
  Vdbe *p = (Vdbe *)pStmt;
  rc = vdbeUnbind(p, i);
  if( rc==SQLITE_OK ){







<
|
>







1160
1161
1162
1163
1164
1165
1166

1167
1168
1169
1170
1171
1172
1173
1174
1175
  rc = vdbeUnbind(p, i);
  if( rc==SQLITE_OK ){
    rc = sqlite3VdbeMemCopy(&p->aVar[i-1], pValue);
    if( rc==SQLITE_OK ){
      rc = sqlite3VdbeChangeEncoding(&p->aVar[i-1], ENC(p->db));
    }
    sqlite3_mutex_leave(p->db->mutex);

    rc = sqlite3ApiExit(p->db, rc);
  }
  return rc;
}
int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
  int rc;
  Vdbe *p = (Vdbe *)pStmt;
  rc = vdbeUnbind(p, i);
  if( rc==SQLITE_OK ){
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201






1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
/*
** Create a mapping from variable numbers to variable names
** in the Vdbe.azVar[] array, if such a mapping does not already
** exist.
*/
static void createVarMap(Vdbe *p){
  if( !p->okVar ){
    sqlite3_mutex_enter(p->db->mutex);
    if( !p->okVar ){
      int j;
      Op *pOp;






      for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){
        if( pOp->opcode==OP_Variable ){
          assert( pOp->p1>0 && pOp->p1<=p->nVar );
          p->azVar[pOp->p1-1] = pOp->p4.z;
        }
      }
      p->okVar = 1;
    }
    sqlite3_mutex_leave(p->db->mutex);
  }
}

/*
** Return the name of a wildcard parameter.  Return NULL if the index
** is out of range or if the wildcard is unnamed.







<
<
|
|
>
>
>
>
>
>
|
|
|
|
|
|
|
<







1191
1192
1193
1194
1195
1196
1197


1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212

1213
1214
1215
1216
1217
1218
1219
/*
** Create a mapping from variable numbers to variable names
** in the Vdbe.azVar[] array, if such a mapping does not already
** exist.
*/
static void createVarMap(Vdbe *p){
  if( !p->okVar ){


    int j;
    Op *pOp;
    sqlite3_mutex_enter(p->db->mutex);
    /* The race condition here is harmless.  If two threads call this
    ** routine on the same Vdbe at the same time, they both might end
    ** up initializing the Vdbe.azVar[] array.  That is a little extra
    ** work but it results in the same answer.
    */
    for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){
      if( pOp->opcode==OP_Variable ){
        assert( pOp->p1>0 && pOp->p1<=p->nVar );
        p->azVar[pOp->p1-1] = pOp->p4.z;
      }
    }
    p->okVar = 1;

    sqlite3_mutex_leave(p->db->mutex);
  }
}

/*
** Return the name of a wildcard parameter.  Return NULL if the index
** is out of range or if the wildcard is unnamed.
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281








1282
1283





1284
1285
1286
1287
1288
1289
1290
    }
  }
  return 0;
}

/*
** Transfer all bindings from the first statement over to the second.
** If the two statements contain a different number of bindings, then
** an SQLITE_ERROR is returned.
*/
int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
  Vdbe *pFrom = (Vdbe*)pFromStmt;
  Vdbe *pTo = (Vdbe*)pToStmt;
  int i, rc = SQLITE_OK;
  if( (pFrom->magic!=VDBE_MAGIC_RUN && pFrom->magic!=VDBE_MAGIC_HALT)
    || (pTo->magic!=VDBE_MAGIC_RUN && pTo->magic!=VDBE_MAGIC_HALT)
    || pTo->db!=pFrom->db ){
    return SQLITE_MISUSE;
  }
  if( pFrom->nVar!=pTo->nVar ){
    return SQLITE_ERROR;
  }
  sqlite3_mutex_enter(pTo->db->mutex);
  for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){
    sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
  }
  sqlite3_mutex_leave(pTo->db->mutex);
  assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
  return rc;
}

#ifndef SQLITE_OMIT_DEPRECATED
/*
** Deprecated external interface.  Internal/core SQLite code
** should call sqlite3TransferBindings.








*/
int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){





  return sqlite3TransferBindings(pFromStmt, pToStmt);
}
#endif

/*
** Return the sqlite3* database handle to which the prepared statement given
** in the argument belongs.  This is the same database handle that was







<
<




|
<
<
|
<
<
|
<
<

|



<
|






>
>
>
>
>
>
>
>


>
>
>
>
>







1250
1251
1252
1253
1254
1255
1256


1257
1258
1259
1260
1261


1262


1263


1264
1265
1266
1267
1268

1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
    }
  }
  return 0;
}

/*
** Transfer all bindings from the first statement over to the second.


*/
int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
  Vdbe *pFrom = (Vdbe*)pFromStmt;
  Vdbe *pTo = (Vdbe*)pToStmt;
  int i;


  assert( pTo->db==pFrom->db );


  assert( pTo->nVar==pFrom->nVar );


  sqlite3_mutex_enter(pTo->db->mutex);
  for(i=0; i<pFrom->nVar; i++){
    sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
  }
  sqlite3_mutex_leave(pTo->db->mutex);

  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_DEPRECATED
/*
** Deprecated external interface.  Internal/core SQLite code
** should call sqlite3TransferBindings.
**
** Is is misuse to call this routine with statements from different
** database connections.  But as this is a deprecated interface, we
** will not bother to check for that condition.
**
** If the two statements contain a different number of bindings, then
** an SQLITE_ERROR is returned.  Nothing else can go wrong, so otherwise
** SQLITE_OK is returned.
*/
int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
  Vdbe *pFrom = (Vdbe*)pFromStmt;
  Vdbe *pTo = (Vdbe*)pToStmt;
  if( pFrom->nVar!=pTo->nVar ){
    return SQLITE_ERROR;
  }
  return sqlite3TransferBindings(pFromStmt, pToStmt);
}
#endif

/*
** Return the sqlite3* database handle to which the prepared statement given
** in the argument belongs.  This is the same database handle that was
Changes to test/bindxfer.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2005 April 21
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the sqlite_transfer_bindings() API.
#
# $Id: bindxfer.test,v 1.6 2008/10/12 00:27:54 shane Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc sqlite_step {stmt VALS COLS} {
  upvar #0 $VALS vals













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2005 April 21
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the sqlite_transfer_bindings() API.
#
# $Id: bindxfer.test,v 1.7 2009/04/09 14:02:44 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc sqlite_step {stmt VALS COLS} {
  upvar #0 $VALS vals
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  } {{} {} {}}
  do_test bindxfer-1.7 {
    sqlite_step $VM2 VALUES COLNAMES
  } SQLITE_ROW
  do_test bindxfer-1.8 {
    set VALUES
  } {one two {}}
  do_test bindxfer-1.9-misuse {
    catch {sqlite3_finalize $VM1}
    catch {sqlite3_finalize $VM2}
    sqlite3_transfer_bindings $VM1 $VM2
  } 21 ;# SQLITE_MISUSE
  do_test bindxfer-1.10 {
    set VM1 [sqlite3_prepare $DB {SELECT ?, ?, ?} -1 TAIL]
    set VM2 [sqlite3_prepare $DB {SELECT ?, ?, ?, ?} -1 TAIL]
    sqlite3_transfer_bindings $VM1 $VM2
  } 1  ;# SQLITE_ERROR
}
catch {sqlite3_finalize $VM1}
catch {sqlite3_finalize $VM2}


finish_test







<
|
|
<
<











64
65
66
67
68
69
70

71
72


73
74
75
76
77
78
79
80
81
82
83
  } {{} {} {}}
  do_test bindxfer-1.7 {
    sqlite_step $VM2 VALUES COLNAMES
  } SQLITE_ROW
  do_test bindxfer-1.8 {
    set VALUES
  } {one two {}}

  catch {sqlite3_finalize $VM1}
  catch {sqlite3_finalize $VM2}


  do_test bindxfer-1.10 {
    set VM1 [sqlite3_prepare $DB {SELECT ?, ?, ?} -1 TAIL]
    set VM2 [sqlite3_prepare $DB {SELECT ?, ?, ?, ?} -1 TAIL]
    sqlite3_transfer_bindings $VM1 $VM2
  } 1  ;# SQLITE_ERROR
}
catch {sqlite3_finalize $VM1}
catch {sqlite3_finalize $VM2}


finish_test