/ Check-in [1637f379]
Login

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

Overview
Comment:Fix minor malloc() related problems and add sqlite3_soft_heap_limit() stubs. (CVS 2814)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:1637f3796015d1582ed8c6bc8bdf8c067b4bade9
User & Date: danielk1977 2005-12-12 06:53:04
Context
2005-12-14
20:11
Properly zero-terminate UTF-16 collation names on an sqlite3_collation_needed16 callback. (CVS 2815) check-in: 71a49d05 user: drh tags: trunk
2005-12-12
06:53
Fix minor malloc() related problems and add sqlite3_soft_heap_limit() stubs. (CVS 2814) check-in: 1637f379 user: danielk1977 tags: trunk
2005-12-10
21:19
Add the "exists" method to the TCL interface. (CVS 2813) check-in: 8a355d7a user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/complete.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
251
252
253
254
255
256
257



258
259
260
261
262
263
** An tokenizer for SQL
**
** This file contains C code that implements the sqlite3_complete() API.
** This code used to be part of the tokenizer.c source file.  But by
** separating it out, the code will be automatically omitted from
** static links that do not use it.
**
** $Id: complete.c,v 1.1 2005/08/14 17:53:21 drh Exp $
*/
#include "sqliteInt.h"
#ifndef SQLITE_OMIT_COMPLETE

/*
** This is defined in tokenize.c.  We just have to import the definition.
*/
................................................................................
  int rc = 0;

  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zSql8 ){
    rc = sqlite3_complete(zSql8);



  }
  sqlite3ValueFree(pVal);
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_OMIT_COMPLETE */







|







 







>
>
>






12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
** An tokenizer for SQL
**
** This file contains C code that implements the sqlite3_complete() API.
** This code used to be part of the tokenizer.c source file.  But by
** separating it out, the code will be automatically omitted from
** static links that do not use it.
**
** $Id: complete.c,v 1.2 2005/12/12 06:53:04 danielk1977 Exp $
*/
#include "sqliteInt.h"
#ifndef SQLITE_OMIT_COMPLETE

/*
** This is defined in tokenize.c.  We just have to import the definition.
*/
................................................................................
  int rc = 0;

  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zSql8 ){
    rc = sqlite3_complete(zSql8);
  }else if( zSql ){
    rc = SQLITE_NOMEM;
    sqlite3MallocClearFailed();
  }
  sqlite3ValueFree(pVal);
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_OMIT_COMPLETE */

Changes to src/legacy.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
...
120
121
122
123
124
125
126

127

128
129
130
131
132
133
134
135
136
137
138
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: legacy.c,v 1.8 2005/12/06 12:52:59 danielk1977 Exp $
*/

#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
................................................................................

    db->nChange += nChange;
    nCallback = 0;

    nCol = sqlite3_column_count(pStmt);
    azCols = sqliteMalloc(2*nCol*sizeof(const char *));
    if( nCol && !azCols ){
      rc = SQLITE_NOMEM;
      goto exec_out;
    }

    while( 1 ){
      int i;
      rc = sqlite3_step(pStmt);

................................................................................

exec_out:
  if( pStmt ) sqlite3_finalize(pStmt);
  if( azCols ) sqliteFree(azCols);

  if( sqlite3Tsd()->mallocFailed ){
    rc = SQLITE_NOMEM;

  }

  if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
    *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
    if( *pzErrMsg ){
      strcpy(*pzErrMsg, sqlite3_errmsg(db));
    }
  }else if( pzErrMsg ){
    *pzErrMsg = 0;
  }

  return rc;
}







|







 







<







 







>

>











10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
66
67
68
69
70
71
72

73
74
75
76
77
78
79
...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: legacy.c,v 1.9 2005/12/12 06:53:04 danielk1977 Exp $
*/

#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
................................................................................

    db->nChange += nChange;
    nCallback = 0;

    nCol = sqlite3_column_count(pStmt);
    azCols = sqliteMalloc(2*nCol*sizeof(const char *));
    if( nCol && !azCols ){

      goto exec_out;
    }

    while( 1 ){
      int i;
      rc = sqlite3_step(pStmt);

................................................................................

exec_out:
  if( pStmt ) sqlite3_finalize(pStmt);
  if( azCols ) sqliteFree(azCols);

  if( sqlite3Tsd()->mallocFailed ){
    rc = SQLITE_NOMEM;
    sqlite3MallocClearFailed();
  }

  if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
    *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
    if( *pzErrMsg ){
      strcpy(*pzErrMsg, sqlite3_errmsg(db));
    }
  }else if( pzErrMsg ){
    *pzErrMsg = 0;
  }

  return rc;
}

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
148
149
150
151
152
153
154



155
156
157
158
159
160
161
...
182
183
184
185
186
187
188

189
190
191
192
193
194
195
...
199
200
201
202
203
204
205

206
207
208

209
210
211
212
213
214
215
...
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701
702
703
704
...
711
712
713
714
715
716
717


718
719
720
721
722
723
724
...
737
738
739
740
741
742
743
744




745
746
747
748
749
750
751
752
...
781
782
783
784
785
786
787
788
789

790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
...
818
819
820
821
822
823
824

825
826
827
828
829
830
831
832
833
834



835
836
837
838
839
840
841
842
843
844
845
...
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.307 2005/12/09 20:02:05 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
................................................................................
  ** that case. But maybe there should be an extra magic value for the
  ** "failed to open" state.
  */
  if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){
    /* printf("DID NOT CLOSE\n"); fflush(stdout); */
    return SQLITE_ERROR;
  }




  for(j=0; j<db->nDb; j++){
    struct Db *pDb = &db->aDb[j];
    if( pDb->pBt ){
      sqlite3BtreeClose(pDb->pBt);
      pDb->pBt = 0;
    }
................................................................................
  if( db->pValue ){
    sqlite3ValueFree(db->pValue);
  }
  if( db->pErr ){
    sqlite3ValueFree(db->pErr);
  }


#ifndef SQLITE_OMIT_GLOBALRECOVER
  {
    sqlite3 *pPrev;
    sqlite3Os.xEnterMutex();
    pPrev = pDbList;
    while( pPrev && pPrev->pNext!=db ){
      pPrev = pPrev->pNext;
................................................................................
    }else{
      assert( pDbList==db );
      pDbList = db->pNext;
    }
    sqlite3Os.xLeaveMutex();
  }
#endif


  db->magic = SQLITE_MAGIC_ERROR;
  sqliteFree(db);

  return SQLITE_OK;
}

/*
** Rollback all database files.
*/
void sqlite3RollbackAll(sqlite3 *db){
................................................................................
    z = sqlite3_value_text16(db->pErr);
  }
  return z;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** Return the most recent error code generated by an SQLite routine.

*/
int sqlite3_errcode(sqlite3 *db){
  if( sqlite3Tsd()->mallocFailed ){
    return SQLITE_NOMEM;
  }
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  return db->errCode;
}
................................................................................
static int openDatabase(
  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb         /* OUT: Returned database handle */
){
  sqlite3 *db;
  int rc, i;
  CollSeq *pColl;



  /* Allocate the sqlite data structure */
  db = sqliteMalloc( sizeof(sqlite3) );
  if( db==0 ) goto opendb_out;
  db->priorNewRowid = 0;
  db->magic = SQLITE_MAGIC_BUSY;
  db->nDb = 2;
................................................................................
  
  /* Add the default collation sequence BINARY. BINARY works for both UTF-8
  ** and UTF-16, so add a version for each to avoid any unnecessary
  ** conversions. The only error that can occur here is a malloc() failure.
  */
  if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
      sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
      (db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0))==0 ){




    assert(rc!=SQLITE_OK || sqlite3Tsd()->mallocFailed);
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }

  /* Also add a UTF-8 case-insensitive collation sequence. */
  sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);

................................................................................
  ** is accessed.
  */
  sqlite3RegisterBuiltinFunctions(db);
  sqlite3Error(db, SQLITE_OK, 0);
  db->magic = SQLITE_MAGIC_OPEN;

opendb_out:
  if( sqlite3_errcode(db)==SQLITE_OK && sqlite3Tsd()->mallocFailed ){
    sqlite3Error(db, SQLITE_NOMEM, 0);

  }
  *ppDb = db;
#ifndef SQLITE_OMIT_GLOBALRECOVER
  if( db ){
    sqlite3Os.xEnterMutex();
    db->pNext = pDbList;
    pDbList = db;
    sqlite3Os.xLeaveMutex();
  }
#endif
  return sqlite3_errcode(db);
}

/*
** Open a new database handle.
*/
int sqlite3_open(
  const char *zFilename, 
................................................................................
  const void *zFilename, 
  sqlite3 **ppDb
){
  char const *zFilename8;   /* zFilename encoded in UTF-8 instead of UTF-16 */
  int rc = SQLITE_NOMEM;
  sqlite3_value *pVal;


  assert( ppDb );
  *ppDb = 0;
  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zFilename8 ){
    rc = openDatabase(zFilename8, ppDb);
    if( rc==SQLITE_OK && *ppDb ){
      rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
    }



  }
  if( pVal ){
    sqlite3ValueFree(pVal);
  }

  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** The following routine destroys a virtual machine that is created by
................................................................................
  db->pCollNeededArg = pCollNeededArg;
  return SQLITE_OK;
}
#endif /* SQLITE_OMIT_UTF16 */

#ifndef SQLITE_OMIT_GLOBALRECOVER
/*
** This function is called to recover from a malloc failure that occured
** within SQLite. 
**
** This function is *not* threadsafe. Calling this from within a threaded
** application when threads other than the caller have used SQLite is 
** dangerous and will almost certainly result in malfunctions.
*/
int sqlite3_global_recover(){
#if 0
  int rc = SQLITE_OK;

  if( sqlite3Tsd()->mallocFailed ){
    sqlite3 *db;
    int i;
    sqlite3Tsd()->mallocFailed = 0;
    for(db=pDbList; db; db=db->pNext ){
      sqlite3ExpirePreparedStatements(db);
      for(i=0; i<db->nDb; i++){
        Btree *pBt = db->aDb[i].pBt;
        if( pBt && (rc=sqlite3BtreeReset(pBt))!=0 ){
          goto recover_out;
        }
      } 
      db->autoCommit = 1;
    }
  }

recover_out:
  if( rc!=SQLITE_OK ){
    sqlite3Tsd()->mallocFailed = 1;
  }
  return rc;
#endif
  return SQLITE_OK;
}
#endif

/*
** Test to see whether or not the database connection is in autocommit
** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on







|







 







>
>
>







 







>







 







>



>







 







|
>


|







 







>
>







 







|
>
>
>
>
|







 







|
|
>


<
|
<
<
<
<
<
<
|







 







>










>
>
>

<
|
<







 







|
|
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
...
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
...
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
...
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
...
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
...
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
...
794
795
796
797
798
799
800
801
802
803
804
805

806






807
808
809
810
811
812
813
814
...
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846

847

848
849
850
851
852
853
854
....
1006
1007
1008
1009
1010
1011
1012
1013
1014




1015
1016

























1017
1018
1019
1020
1021
1022
1023
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.308 2005/12/12 06:53:04 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
................................................................................
  ** that case. But maybe there should be an extra magic value for the
  ** "failed to open" state.
  */
  if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){
    /* printf("DID NOT CLOSE\n"); fflush(stdout); */
    return SQLITE_ERROR;
  }

  /* sqlite3_close() may not invoke sqliteMalloc(). */
  sqlite3MallocDisallow();

  for(j=0; j<db->nDb; j++){
    struct Db *pDb = &db->aDb[j];
    if( pDb->pBt ){
      sqlite3BtreeClose(pDb->pBt);
      pDb->pBt = 0;
    }
................................................................................
  if( db->pValue ){
    sqlite3ValueFree(db->pValue);
  }
  if( db->pErr ){
    sqlite3ValueFree(db->pErr);
  }

#if 0 
#ifndef SQLITE_OMIT_GLOBALRECOVER
  {
    sqlite3 *pPrev;
    sqlite3Os.xEnterMutex();
    pPrev = pDbList;
    while( pPrev && pPrev->pNext!=db ){
      pPrev = pPrev->pNext;
................................................................................
    }else{
      assert( pDbList==db );
      pDbList = db->pNext;
    }
    sqlite3Os.xLeaveMutex();
  }
#endif
#endif

  db->magic = SQLITE_MAGIC_ERROR;
  sqliteFree(db);
  sqlite3MallocAllow();
  return SQLITE_OK;
}

/*
** Rollback all database files.
*/
void sqlite3RollbackAll(sqlite3 *db){
................................................................................
    z = sqlite3_value_text16(db->pErr);
  }
  return z;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** Return the most recent error code generated by an SQLite routine. If NULL is
** passed to this function, we assume a malloc() failed during sqlite3_open().
*/
int sqlite3_errcode(sqlite3 *db){
  if( !db || sqlite3Tsd()->mallocFailed ){
    return SQLITE_NOMEM;
  }
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  return db->errCode;
}
................................................................................
static int openDatabase(
  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb         /* OUT: Returned database handle */
){
  sqlite3 *db;
  int rc, i;
  CollSeq *pColl;

  assert( !sqlite3Tsd()->mallocFailed );

  /* Allocate the sqlite data structure */
  db = sqliteMalloc( sizeof(sqlite3) );
  if( db==0 ) goto opendb_out;
  db->priorNewRowid = 0;
  db->magic = SQLITE_MAGIC_BUSY;
  db->nDb = 2;
................................................................................
  
  /* Add the default collation sequence BINARY. BINARY works for both UTF-8
  ** and UTF-16, so add a version for each to avoid any unnecessary
  ** conversions. The only error that can occur here is a malloc() failure.
  */
  if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
      sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
      (db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0))==0 
  ){
    /* sqlite3_create_collation() is an external API. So the mallocFailed flag
    ** will have been cleared before returning. So set it explicitly here.
    */
    sqlite3Tsd()->mallocFailed = 1;
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }

  /* Also add a UTF-8 case-insensitive collation sequence. */
  sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);

................................................................................
  ** is accessed.
  */
  sqlite3RegisterBuiltinFunctions(db);
  sqlite3Error(db, SQLITE_OK, 0);
  db->magic = SQLITE_MAGIC_OPEN;

opendb_out:
  if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
    sqlite3_close(db);
    db = 0;
  }
  *ppDb = db;

  sqlite3MallocClearFailed();






  return rc;
}

/*
** Open a new database handle.
*/
int sqlite3_open(
  const char *zFilename, 
................................................................................
  const void *zFilename, 
  sqlite3 **ppDb
){
  char const *zFilename8;   /* zFilename encoded in UTF-8 instead of UTF-16 */
  int rc = SQLITE_NOMEM;
  sqlite3_value *pVal;

  assert( zFilename );
  assert( ppDb );
  *ppDb = 0;
  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zFilename8 ){
    rc = openDatabase(zFilename8, ppDb);
    if( rc==SQLITE_OK && *ppDb ){
      rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
    }
  }else{
    assert( sqlite3Tsd()->mallocFailed );
    sqlite3MallocClearFailed();
  }

  sqlite3ValueFree(pVal);


  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** The following routine destroys a virtual machine that is created by
................................................................................
  db->pCollNeededArg = pCollNeededArg;
  return SQLITE_OK;
}
#endif /* SQLITE_OMIT_UTF16 */

#ifndef SQLITE_OMIT_GLOBALRECOVER
/*
** This function is now an anachronism. It used to be used to recover from a
** malloc() failure, but SQLite now does this automatically.




*/
int sqlite3_global_recover(){

























  return SQLITE_OK;
}
#endif

/*
** Test to see whether or not the database connection is in autocommit
** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on

Changes to src/prepare.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.7 2005/12/09 20:02:05 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
................................................................................

  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sqlite3RunParser(&sParse, zSql, &zErrMsg);

  if( sqlite3Tsd()->mallocFailed ){
    sParse.rc = SQLITE_NOMEM;
#if 0
    sqlite3RollbackInternalChanges(db);
    sqlite3RollbackAll(db);
    db->flags &= ~SQLITE_InTrans;
    db->autoCommit = 1;
#endif
  }
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){
    sParse.rc = SQLITE_SCHEMA;
  }
  if( sParse.rc==SQLITE_SCHEMA ){
    sqlite3ResetInternalSchema(db, 0);







|







 







<
<
<
<
<
<







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
439
440
441
442
443
444
445






446
447
448
449
450
451
452
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.8 2005/12/12 06:53:04 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
................................................................................

  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sqlite3RunParser(&sParse, zSql, &zErrMsg);

  if( sqlite3Tsd()->mallocFailed ){
    sParse.rc = SQLITE_NOMEM;






  }
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){
    sParse.rc = SQLITE_SCHEMA;
  }
  if( sParse.rc==SQLITE_SCHEMA ){
    sqlite3ResetInternalSchema(db, 0);

Changes to src/sqlite.h.in.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1272
1273
1274
1275
1276
1277
1278















1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.143 2005/10/20 07:28:19 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** Return the sqlite3* database handle to which the prepared statement given
** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
















/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
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
1298
1299
1300
1301
1302
1303
1304
1305
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.144 2005/12/12 06:53:05 danielk1977 Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** Return the sqlite3* database handle to which the prepared statement given
** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt*);

/*
** Place a "soft" limit on the amount of heap memory that may be allocated by
** SQLite within the current thread. If an internal allocation is requested 
** that would exceed the specified limit, sqlite3_release_memory() is invoked
** one or more times to free up some space before the allocation is made.
**
** The limit is called "soft", because if sqlite3_release_memory() cannot free
** sufficient memory to prevent the limit from being exceeded, the memory is
** allocated anyway and the current operation proceeds.
**
** This function is only available if the library was compiled without the 
** SQLITE_OMIT_SOFTHEAPLIMIT option set.
*/
void sqlite3_soft_heap_limit(int);

/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
265
266
267
268
269
270
271





272
273
274
275
276
277
278
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.433 2005/12/09 20:02:06 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Many people are failing to set -DNDEBUG=1 when compiling SQLite.
** Setting NDEBUG makes the code smaller and run faster.  So the following
................................................................................

/*
** An instance of this structure is allocated for each thread that uses SQLite.
*/
typedef struct SqliteTsd SqliteTsd;
struct SqliteTsd {
  int mallocFailed;               /* True after a malloc() has failed */





#ifndef NDEBUG
  int mallocAllowed;              /* assert() in sqlite3Malloc() if not set */
#endif
#ifdef SQLITE_MEMDEBUG
  int isFail;              /* True if all malloc() calls should fail */
  const char *zFile;       /* Filename to associate debugging info with */
  int iLine;               /* Line number to associate debugging info with */







|







 







>
>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.434 2005/12/12 06:53:05 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Many people are failing to set -DNDEBUG=1 when compiling SQLite.
** Setting NDEBUG makes the code smaller and run faster.  So the following
................................................................................

/*
** An instance of this structure is allocated for each thread that uses SQLite.
*/
typedef struct SqliteTsd SqliteTsd;
struct SqliteTsd {
  int mallocFailed;               /* True after a malloc() has failed */
#ifndef SQLITE_OMIT_SOFTHEAPLIMIT
  unsigned int nSoftHeapLimit;    /* (uint)-1 for unlimited */
  unsigned int nAlloc;            /* Number of bytes currently allocated */
#endif

#ifndef NDEBUG
  int mallocAllowed;              /* assert() in sqlite3Malloc() if not set */
#endif
#ifdef SQLITE_MEMDEBUG
  int isFail;              /* True if all malloc() calls should fail */
  const char *zFile;       /* Filename to associate debugging info with */
  int iLine;               /* Line number to associate debugging info with */

Changes to src/tclsqlite.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
....
1701
1702
1703
1704
1705
1706
1707




















1708
1709
1710
1711
1712
1713
1714
....
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
**    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.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.136 2005/12/10 21:19:05 drh Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
................................................................................
  static const char *DB_strs[] = {
    "authorizer",         "busy",              "cache",
    "changes",            "close",             "collate",
    "collation_needed",   "commit_hook",       "complete",
    "copy",               "errorcode",         "eval",
    "exists",             "function",          "last_insert_rowid",
    "nullvalue",          "onecolumn",         "profile",
    "progress",           "rekey",             "timeout",
    "total_changes",      "trace",             "transaction",
    "version",            0                    
  };
  enum DB_enum {
    DB_AUTHORIZER,        DB_BUSY,             DB_CACHE,
    DB_CHANGES,           DB_CLOSE,            DB_COLLATE,
    DB_COLLATION_NEEDED,  DB_COMMIT_HOOK,      DB_COMPLETE,
    DB_COPY,              DB_ERRORCODE,        DB_EVAL,
    DB_EXISTS,            DB_FUNCTION,         DB_LAST_INSERT_ROWID,
    DB_NULLVALUE,         DB_ONECOLUMN,        DB_PROFILE,
    DB_PROGRESS,          DB_REKEY,            DB_TIMEOUT,
    DB_TOTAL_CHANGES,     DB_TRACE,            DB_TRANSACTION,
    DB_VERSION
  };
  /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
    return TCL_ERROR;
  }
................................................................................
      Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
      return TCL_ERROR;
    }
    if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
    sqlite3_busy_timeout(pDb->db, ms);
    break;
  }




















  
  /*
  **     $db total_changes
  **
  ** Return the number of rows that were modified, inserted, or deleted 
  ** since the database handle was created.
  */
................................................................................
    int mallocfail = sqlite3_iMallocFail;
    sqlite3_iMallocFail = 0;
#endif
    Md5_Register(p->db);
#ifdef SQLITE_MEMDEBUG
    sqlite3_iMallocFail = mallocfail;
#endif
   }
#endif  
  p->interp = interp;
  return TCL_OK;
}

/*
** Provide a dummy Tcl_InitStubs if we are using this as a static







|







 







|
|
|








|
|
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
....
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
....
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
**    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.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.137 2005/12/12 06:53:05 danielk1977 Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
................................................................................
  static const char *DB_strs[] = {
    "authorizer",         "busy",              "cache",
    "changes",            "close",             "collate",
    "collation_needed",   "commit_hook",       "complete",
    "copy",               "errorcode",         "eval",
    "exists",             "function",          "last_insert_rowid",
    "nullvalue",          "onecolumn",         "profile",
    "progress",           "rekey",             "soft_heap_limit",
    "timeout",            "total_changes",     "trace",
    "transaction",        "version",            0                    
  };
  enum DB_enum {
    DB_AUTHORIZER,        DB_BUSY,             DB_CACHE,
    DB_CHANGES,           DB_CLOSE,            DB_COLLATE,
    DB_COLLATION_NEEDED,  DB_COMMIT_HOOK,      DB_COMPLETE,
    DB_COPY,              DB_ERRORCODE,        DB_EVAL,
    DB_EXISTS,            DB_FUNCTION,         DB_LAST_INSERT_ROWID,
    DB_NULLVALUE,         DB_ONECOLUMN,        DB_PROFILE,
    DB_PROGRESS,          DB_REKEY,            DB_SOFT_HEAP_LIMIT,
    DB_TIMEOUT,           DB_TOTAL_CHANGES,    DB_TRACE,
    DB_TRANSACTION,       DB_VERSION
  };
  /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
    return TCL_ERROR;
  }
................................................................................
      Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
      return TCL_ERROR;
    }
    if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
    sqlite3_busy_timeout(pDb->db, ms);
    break;
  }

  /*
  **     $db soft_heap_limit N
  **
  ** Set the soft-heap-limit for this thread. Note that the limit is 
  ** per-thread, not per-database.
  */
  case DB_SOFT_HEAP_LIMIT: {
    int n;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "BYTES");
      return TCL_ERROR;
    }
    if( Tcl_GetIntFromObj(interp, objv[2], &n) ){
      return TCL_ERROR;
    }
    sqlite3_soft_heap_limit(n);
    Tcl_ResetResult(interp);
    break;
  }
  
  /*
  **     $db total_changes
  **
  ** Return the number of rows that were modified, inserted, or deleted 
  ** since the database handle was created.
  */
................................................................................
    int mallocfail = sqlite3_iMallocFail;
    sqlite3_iMallocFail = 0;
#endif
    Md5_Register(p->db);
#ifdef SQLITE_MEMDEBUG
    sqlite3_iMallocFail = mallocfail;
#endif
  }
#endif  
  p->interp = interp;
  return TCL_OK;
}

/*
** Provide a dummy Tcl_InitStubs if we are using this as a static

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.174 2005/12/09 20:21:59 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  if( argc==3 ){
    if( Tcl_GetInt(interp, argv[2], &rep) ) return TCL_ERROR;
  }else{
    rep = 0;
  }
  sqlite3_iMallocFail = n;
  sqlite3_iMallocReset = rep;
  sqlite3Tsd()->mallocFailed = 0;
  return TCL_OK;
}
#endif

/*
** Usage: sqlite_malloc_stat
**







|







 







<







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
806
807
808
809
810
811
812

813
814
815
816
817
818
819
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.175 2005/12/12 06:53:05 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  if( argc==3 ){
    if( Tcl_GetInt(interp, argv[2], &rep) ) return TCL_ERROR;
  }else{
    rep = 0;
  }
  sqlite3_iMallocFail = n;
  sqlite3_iMallocReset = rep;

  return TCL_OK;
}
#endif

/*
** Usage: sqlite_malloc_stat
**

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
...
133
134
135
136
137
138
139
140


141
142
143
144
145
146
147
...
360
361
362
363
364
365
366
367
368







369
370
371
372
373
374
375
...
459
460
461
462
463
464
465







466
467
468
469
470

471
472
473
474
475
476






















477
478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
...
504
505
506
507
508
509
510

511
512
513
514
515
516
517
...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
....
1204
1205
1206
1207
1208
1209
1210

1211

1212
1213




1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227




1228
1229
1230
















1231
1232
1233
1234
1235
1236
1237
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.151 2005/12/09 14:39:04 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** MALLOC WRAPPER ARCHITECTURE
................................................................................
** define it as an empty macro and set the amount of space reserved to 0.
*/
#if defined(__GLIBC__) && SQLITE_MEMDEBUG>1
  extern int backtrace(void **, int);
  #define TESTALLOC_STACKSIZE 128
  #define TESTALLOC_STACKFRAMES ((TESTALLOC_STACKSIZE-8)/sizeof(void*))
#else
  #define backtrace(x, y) 0
  #define TESTALLOC_STACKSIZE 0
  #define TESTALLOC_STACKFRAMES 0
#endif

/*
** Number of 32-bit guard words.  This should probably be a multiple of
** 2 since on 64-bit machines we want the value returned by sqliteMalloc()
................................................................................

/*
** Size reserved for storing file-name along with each malloc()ed blob.
*/
#define TESTALLOC_FILESIZE 64

/*
** Size reserved for storing the user string.


*/
#define TESTALLOC_USERSIZE 64
const char *sqlite3_malloc_id = 0;

/*
** Blocks used by the test layer have the following format:
**
................................................................................
  if( pp[1] ){
    ((void **)(pp[1]))[0] = p;
  }
}

/*
** This function sets the result of the Tcl interpreter passed as an argument
** to a list containing an entry for each currently outstanding call made to
** sqliteMalloc and friends by the current thread.







**
** Todo: We could have a version of this function that outputs to stdout, 
** to debug memory leaks when Tcl is not available.
*/
#ifdef TCLSH
#include <tcl.h>
int sqlite3OutstandingMallocs(Tcl_Interp *interp){
................................................................................
  }
  return 0;
}

void OSMALLOC_FAILED(){
  sqlite3Tsd()->isFail = 0;
}








#else
#define OSMALLOC(x) sqlite3OsMalloc(x)
#define OSREALLOC(x,y) sqlite3OsRealloc(x,y)
#define OSFREE(x) sqlite3OsFree(x)

#define OSMALLOC_FAILED()
#endif
/*
** End code for memory allocation system test layer.
**--------------------------------------------------------------------------*/























/*
** Allocate and return N bytes of uninitialised memory by calling
** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory 
** by calling sqlite3_release_memory().
*/
void *sqlite3MallocRaw(int n){
  SqliteTsd *pTsd = sqlite3Tsd();
  void *p = 0;

  if( n>0 && !pTsd->mallocFailed ){

    while( !(p = OSMALLOC(n)) && sqlite3_release_memory(n) );
    if( !p ){
      sqlite3Tsd()->mallocFailed = 1;
      OSMALLOC_FAILED();
    }
  }
  return p;
................................................................................
    return 0;
  }

  if( !p ){
    return sqlite3Malloc(n);
  }else{
    void *np = 0;

    while( !(np = OSREALLOC(p, n)) && sqlite3_release_memory(n) );
    if( !np ){
      pTsd->mallocFailed = 1;
      OSMALLOC_FAILED();
    }
    return np;
  }
................................................................................
  if( p ){
    OSFREE(p);
  }
}

/*
** A version of sqliteMalloc() that is always a function, not a macro.
** Currently, this is used only to alloc only used drawback.
*/
void *sqlite3MallocX(int n){
  return sqliteMalloc(n);
}

/*
** sqlite3Malloc
................................................................................
  }
  return p;
}
#endif

/*
** Return a pointer to the SqliteTsd associated with the calling thread.

*/

static SqliteTsd tsd = {
  0                    /* mallocFailed flag */




#ifndef NDEBUG
  , 1                  /* mallocAllowed flag */
#endif
#ifdef SQLITE_MEMDEBUG
  , 0
  , 0
  , 0
  , 0
#endif
};
SqliteTsd *sqlite3Tsd(){
  return &tsd;
}





void sqlite3MallocClearFailed(){
  sqlite3Tsd()->mallocFailed = 0;
}

















#ifndef NDEBUG
/*
** This function sets a flag in the thread-specific-data structure that will
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
*/
void sqlite3MallocDisallow(){







|







 







|







 







|
>
>







 







|
|
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>





>






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








<

>







 







>







 







|







 







>

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



>
>
>
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
...
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523

524
525
526
527
528
529
530
531
532
...
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
...
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
....
1244
1245
1246
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
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.152 2005/12/12 06:53:05 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** MALLOC WRAPPER ARCHITECTURE
................................................................................
** define it as an empty macro and set the amount of space reserved to 0.
*/
#if defined(__GLIBC__) && SQLITE_MEMDEBUG>1
  extern int backtrace(void **, int);
  #define TESTALLOC_STACKSIZE 128
  #define TESTALLOC_STACKFRAMES ((TESTALLOC_STACKSIZE-8)/sizeof(void*))
#else
  #define backtrace(x, y)
  #define TESTALLOC_STACKSIZE 0
  #define TESTALLOC_STACKFRAMES 0
#endif

/*
** Number of 32-bit guard words.  This should probably be a multiple of
** 2 since on 64-bit machines we want the value returned by sqliteMalloc()
................................................................................

/*
** Size reserved for storing file-name along with each malloc()ed blob.
*/
#define TESTALLOC_FILESIZE 64

/*
** Size reserved for storing the user string. Each time a Malloc() or Realloc()
** call succeeds, up to TESTALLOC_USERSIZE bytes of the string pointed to by
** sqlite3_malloc_id are stored along with the other test system metadata.
*/
#define TESTALLOC_USERSIZE 64
const char *sqlite3_malloc_id = 0;

/*
** Blocks used by the test layer have the following format:
**
................................................................................
  if( pp[1] ){
    ((void **)(pp[1]))[0] = p;
  }
}

/*
** This function sets the result of the Tcl interpreter passed as an argument
** to a list containing an entry for each currently outstanding call made to 
** sqliteMalloc and friends by the current thread. Each list entry is itself a
** list, consisting of the following (in order):
**
**     * The number of bytes allocated
**     * The __FILE__ macro at the time of the sqliteMalloc() call.
**     * The __LINE__ macro ...
**     * The value of the sqlite3_malloc_id variable ...
**     * The output of backtrace() (if available) ...
**
** Todo: We could have a version of this function that outputs to stdout, 
** to debug memory leaks when Tcl is not available.
*/
#ifdef TCLSH
#include <tcl.h>
int sqlite3OutstandingMallocs(Tcl_Interp *interp){
................................................................................
  }
  return 0;
}

void OSMALLOC_FAILED(){
  sqlite3Tsd()->isFail = 0;
}

int OSSIZEOF(void *p){
  if( p ){
    return sqlite3OsAllocationSize(p) - TESTALLOC_OVERHEAD;
  }
  return 0;
}

#else
#define OSMALLOC(x) sqlite3OsMalloc(x)
#define OSREALLOC(x,y) sqlite3OsRealloc(x,y)
#define OSFREE(x) sqlite3OsFree(x)
#define OSSIZEOF(x) sqlite3OsAllocationSize(x)
#define OSMALLOC_FAILED()
#endif
/*
** End code for memory allocation system test layer.
**--------------------------------------------------------------------------*/

/*
** The handleSoftLimit() function is called before each call to 
** sqlite3OsMalloc() or sqlite3OsRealloc(). The parameter 'n' is the number of
** extra bytes about to be allocated (for Realloc() this means the size of the
** new allocation less the size of the old allocation). If the extra allocation
** means that the total memory allocated to SQLite in this thread would exceed
** the limit set by sqlite3_soft_heap_limit(), then sqlite3_release_memory() is
** called to try to avoid this. No indication of whether or not this is
** successful is returned to the caller.
**
** If SQLITE_OMIT_SOFTHEAPLIMIT is defined, this function is a no-op.
*/
#ifndef SQLITE_OMIT_SOFTHEAPLIMIT
static void handleSoftLimit(int n){
  SqliteTsd *pTsd = sqlite3Tsd();
  pTsd->nAlloc += n;
  while( pTsd->nAlloc>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) );
}
#else
#define handleSoftLimit()
#endif

/*
** Allocate and return N bytes of uninitialised memory by calling
** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory 
** by calling sqlite3_release_memory().
*/
void *sqlite3MallocRaw(int n){
  SqliteTsd *pTsd = sqlite3Tsd();
  void *p = 0;

  if( n>0 && !pTsd->mallocFailed ){
    handleSoftLimit(n);
    while( !(p = OSMALLOC(n)) && sqlite3_release_memory(n) );
    if( !p ){
      sqlite3Tsd()->mallocFailed = 1;
      OSMALLOC_FAILED();
    }
  }
  return p;
................................................................................
    return 0;
  }

  if( !p ){
    return sqlite3Malloc(n);
  }else{
    void *np = 0;
    handleSoftLimit(n - OSSIZEOF(p));
    while( !(np = OSREALLOC(p, n)) && sqlite3_release_memory(n) );
    if( !np ){
      pTsd->mallocFailed = 1;
      OSMALLOC_FAILED();
    }
    return np;
  }
................................................................................
  if( p ){
    OSFREE(p);
  }
}

/*
** A version of sqliteMalloc() that is always a function, not a macro.
** Currently, this is used only to alloc to allocate the parser engine.
*/
void *sqlite3MallocX(int n){
  return sqliteMalloc(n);
}

/*
** sqlite3Malloc
................................................................................
  }
  return p;
}
#endif

/*
** Return a pointer to the SqliteTsd associated with the calling thread.
** TODO: Actually return thread-specific-data instead of this global pointer.
*/
SqliteTsd *sqlite3Tsd(){
  static SqliteTsd tsd = {
    0                    /* mallocFailed flag */
  #ifndef SQLITE_OMIT_SOFTHEAPLIMIT
    , 0xFFFFFFFF         /* nSoftHeapLimit */
    , 0                  /* nAlloc */
  #endif
  #ifndef NDEBUG
    , 1                  /* mallocAllowed flag */
  #endif
  #ifdef SQLITE_MEMDEBUG
    , 0
    , 0
    , 0
    , 0
  #endif
  };

  return &tsd;
}

/*
** Clear the "mallocFailed" flag. This should be invoked before exiting any
** entry points that may have called sqliteMalloc().
*/
void sqlite3MallocClearFailed(){
  sqlite3Tsd()->mallocFailed = 0;
}

#ifndef SQLITE_OMIT_SOFTHEAPLIMIT
/*
** Set the soft heap-size limit for the current thread.
*/
void sqlite3_soft_heap_limit(int n){
  unsigned int N;
  if( n<0 ){
    /* No limit */
    N = 0xFFFFFFFF;
  }else{
    N = n;
  }
  sqlite3Tsd()->nSoftHeapLimit = N;
}
#endif

#ifndef NDEBUG
/*
** This function sets a flag in the thread-specific-data structure that will
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
*/
void sqlite3MallocDisallow(){

Changes to test/tclsqlite.test.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# This file implements regression tests for TCL interface to the
# SQLite library. 
#
# Actually, all tests are based on the TCL interface, so the main
# interface is pretty well tested.  This file contains some addition
# tests for fringe issues that the main test suite does not cover.
#
# $Id: tclsqlite.test,v 1.45 2005/12/10 21:19:06 drh Exp $

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

# Check the error messages generated by tclsqlite
#
if {[sqlite3 -has-codec]} {
................................................................................
do_test tcl-1.1 {
  set v [catch {sqlite3 bogus} msg]
  lappend v $msg
} [list 1 "wrong # args: should be \"$r\""]
do_test tcl-1.2 {
  set v [catch {db bogus} msg]
  lappend v $msg
} {1 {bad option "bogus": must be authorizer, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, errorcode, eval, exists, function, last_insert_rowid, nullvalue, onecolumn, profile, progress, rekey, timeout, total_changes, trace, transaction, or version}}
do_test tcl-1.3 {
  execsql {CREATE TABLE t1(a int, b int)}
  execsql {INSERT INTO t1 VALUES(10,20)}
  set v [catch {
    db eval {SELECT * FROM t1} data {
      error "The error message"
    }
................................................................................
  set v [catch {db eval} msg]
  lappend v $msg
} {1 {wrong # args: should be "db eval SQL ?ARRAY-NAME? ?SCRIPT?"}}
do_test tcl-1.15 {
  set v [catch {db function} msg]
  lappend v $msg
} {1 {wrong # args: should be "db function NAME SCRIPT"}}
do_test tcl-1.14 {
  set v [catch {db last_insert_rowid xyz} msg]
  lappend v $msg
} {1 {wrong # args: should be "db last_insert_rowid "}}
do_test tcl-1.15 {
  set v [catch {db rekey} msg]
  lappend v $msg
} {1 {wrong # args: should be "db rekey KEY"}}
do_test tcl-1.16 {
  set v [catch {db timeout} msg]
  lappend v $msg
} {1 {wrong # args: should be "db timeout MILLISECONDS"}}
do_test tcl-1.17 {
  set v [catch {db collate} msg]
  lappend v $msg
} {1 {wrong # args: should be "db collate NAME SCRIPT"}}
do_test tcl-1.18 {
  set v [catch {db collation_needed} msg]
  lappend v $msg
} {1 {wrong # args: should be "db collation_needed SCRIPT"}}
do_test tcl-1.19 {
  set v [catch {db total_changes xyz} msg]
  lappend v $msg
} {1 {wrong # args: should be "db total_changes "}}
do_test tcl-1.20 {
  set v [catch {db copy} msg]
  lappend v $msg
} {1 {wrong # args: should be "db copy CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"}}







|







 







|







 







|



|



|



|



|



|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# This file implements regression tests for TCL interface to the
# SQLite library. 
#
# Actually, all tests are based on the TCL interface, so the main
# interface is pretty well tested.  This file contains some addition
# tests for fringe issues that the main test suite does not cover.
#
# $Id: tclsqlite.test,v 1.46 2005/12/12 06:53:05 danielk1977 Exp $

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

# Check the error messages generated by tclsqlite
#
if {[sqlite3 -has-codec]} {
................................................................................
do_test tcl-1.1 {
  set v [catch {sqlite3 bogus} msg]
  lappend v $msg
} [list 1 "wrong # args: should be \"$r\""]
do_test tcl-1.2 {
  set v [catch {db bogus} msg]
  lappend v $msg
} {1 {bad option "bogus": must be authorizer, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, errorcode, eval, exists, function, last_insert_rowid, nullvalue, onecolumn, profile, progress, rekey, soft_heap_limit, timeout, total_changes, trace, transaction, or version}}
do_test tcl-1.3 {
  execsql {CREATE TABLE t1(a int, b int)}
  execsql {INSERT INTO t1 VALUES(10,20)}
  set v [catch {
    db eval {SELECT * FROM t1} data {
      error "The error message"
    }
................................................................................
  set v [catch {db eval} msg]
  lappend v $msg
} {1 {wrong # args: should be "db eval SQL ?ARRAY-NAME? ?SCRIPT?"}}
do_test tcl-1.15 {
  set v [catch {db function} msg]
  lappend v $msg
} {1 {wrong # args: should be "db function NAME SCRIPT"}}
do_test tcl-1.16 {
  set v [catch {db last_insert_rowid xyz} msg]
  lappend v $msg
} {1 {wrong # args: should be "db last_insert_rowid "}}
do_test tcl-1.17 {
  set v [catch {db rekey} msg]
  lappend v $msg
} {1 {wrong # args: should be "db rekey KEY"}}
do_test tcl-1.18 {
  set v [catch {db timeout} msg]
  lappend v $msg
} {1 {wrong # args: should be "db timeout MILLISECONDS"}}
do_test tcl-1.19 {
  set v [catch {db collate} msg]
  lappend v $msg
} {1 {wrong # args: should be "db collate NAME SCRIPT"}}
do_test tcl-1.20 {
  set v [catch {db collation_needed} msg]
  lappend v $msg
} {1 {wrong # args: should be "db collation_needed SCRIPT"}}
do_test tcl-1.21 {
  set v [catch {db total_changes xyz} msg]
  lappend v $msg
} {1 {wrong # args: should be "db total_changes "}}
do_test tcl-1.20 {
  set v [catch {db copy} msg]
  lappend v $msg
} {1 {wrong # args: should be "db copy CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"}}