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 |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
1637f3796015d1582ed8c6bc8bdf8c06 |
User & Date: | danielk1977 2005-12-12 06:53:04.000 |
Context
2005-12-14
| ||
20:11 | Properly zero-terminate UTF-16 collation names on an sqlite3_collation_needed16 callback. (CVS 2815) (check-in: 71a49d05bf 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: 1637f37960 user: danielk1977 tags: trunk) | |
2005-12-10
| ||
21:19 | Add the "exists" method to the TCL interface. (CVS 2813) (check-in: 8a355d7aad user: drh tags: trunk) | |
Changes
Changes to src/complete.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** 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. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** 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. */ |
︙ | ︙ | |||
251 252 253 254 255 256 257 258 259 260 261 262 263 | 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 */ | > > > | 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | 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 | ** ************************************************************************* ** 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. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** 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> /* |
︙ | ︙ | |||
66 67 68 69 70 71 72 | db->nChange += nChange; nCallback = 0; nCol = sqlite3_column_count(pStmt); azCols = sqliteMalloc(2*nCol*sizeof(const char *)); if( nCol && !azCols ){ | < | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | 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); |
︙ | ︙ | |||
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | 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; } | > > | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | 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 | ** ************************************************************************* ** 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. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** 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 |
︙ | ︙ | |||
148 149 150 151 152 153 154 155 156 157 158 159 160 161 | ** 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; } | > > > | 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | ** 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; } |
︙ | ︙ | |||
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 209 210 211 212 213 214 215 | 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; } if( pPrev ){ pPrev->pNext = db->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){ | > > > | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | 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; } if( pPrev ){ pPrev->pNext = db->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){ |
︙ | ︙ | |||
687 688 689 690 691 692 693 | z = sqlite3_value_text16(db->pErr); } return z; } #endif /* SQLITE_OMIT_UTF16 */ /* | | > | > > | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 | 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; } /* ** This routine does the work of opening a database on behalf of ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" ** is UTF-8 encoded. */ 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; |
︙ | ︙ | |||
737 738 739 740 741 742 743 | /* 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) || | | > > > > | | 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | /* 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); |
︙ | ︙ | |||
781 782 783 784 785 786 787 | ** is accessed. */ sqlite3RegisterBuiltinFunctions(db); sqlite3Error(db, SQLITE_OK, 0); db->magic = SQLITE_MAGIC_OPEN; opendb_out: | | | > < < | < < < < < | | 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 | ** 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, |
︙ | ︙ | |||
818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 | 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); } } | > > > > < | < | 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 | 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 |
︙ | ︙ | |||
997 998 999 1000 1001 1002 1003 | db->pCollNeededArg = pCollNeededArg; return SQLITE_OK; } #endif /* SQLITE_OMIT_UTF16 */ #ifndef SQLITE_OMIT_GLOBALRECOVER /* | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 | 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 | ** 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. ** | | | 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 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 |
︙ | ︙ | |||
439 440 441 442 443 444 445 | memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sqlite3RunParser(&sParse, zSql, &zErrMsg); if( sqlite3Tsd()->mallocFailed ){ sParse.rc = SQLITE_NOMEM; | < < < < < < | 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | 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 | ** 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. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** 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++. |
︙ | ︙ | |||
1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 | ** 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 | > > > > > > > > > > > > > > > | 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 | ** 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** 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 |
︙ | ︙ | |||
265 266 267 268 269 270 271 272 273 274 275 276 277 278 | /* ** 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 */ | > > > > > | 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | /* ** 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** 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> |
︙ | ︙ | |||
619 620 621 622 623 624 625 | 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", | | | | | | | | 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 | 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; } |
︙ | ︙ | |||
1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 | 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. */ | > > > > > > > > > > > > > > > > > > > > | 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 | 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. */ |
︙ | ︙ | |||
1957 1958 1959 1960 1961 1962 1963 | int mallocfail = sqlite3_iMallocFail; sqlite3_iMallocFail = 0; #endif Md5_Register(p->db); #ifdef SQLITE_MEMDEBUG sqlite3_iMallocFail = mallocfail; #endif | | | 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 | 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 | ** 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. ** | | | 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. ** ************************************************************************* ** 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> |
︙ | ︙ | |||
806 807 808 809 810 811 812 | if( argc==3 ){ if( Tcl_GetInt(interp, argv[2], &rep) ) return TCL_ERROR; }else{ rep = 0; } sqlite3_iMallocFail = n; sqlite3_iMallocReset = rep; | < | 806 807 808 809 810 811 812 813 814 815 816 817 818 819 | 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 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** 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 |
︙ | ︙ | |||
115 116 117 118 119 120 121 | ** 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 | | | > > | 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 141 142 143 144 145 146 147 148 149 | ** 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() ** to be 8-byte aligned. */ #define TESTALLOC_NGUARD 2 /* ** 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: ** |
︙ | ︙ | |||
360 361 362 363 364 365 366 | if( pp[1] ){ ((void **)(pp[1]))[0] = p; } } /* ** This function sets the result of the Tcl interpreter passed as an argument | | | > > > > > > > | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | 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){ |
︙ | ︙ | |||
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 | } 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; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < > | 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 | } 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; |
︙ | ︙ | |||
504 505 506 507 508 509 510 511 512 513 514 515 516 517 | 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; } | > | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | 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; } |
︙ | ︙ | |||
525 526 527 528 529 530 531 | if( p ){ OSFREE(p); } } /* ** A version of sqliteMalloc() that is always a function, not a macro. | | | 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 | 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 |
︙ | ︙ | |||
1204 1205 1206 1207 1208 1209 1210 1211 | } return p; } #endif /* ** Return a pointer to the SqliteTsd associated with the calling thread. */ | > > | | > > > > | | | | | | | | | | < > > > > > > > > > > > > > > > > > > > > | 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 | } 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 | # 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. # | | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | # 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]} { set r "sqlite_orig HANDLE FILENAME ?-key CODEC-KEY?" } else { set r "sqlite3 HANDLE FILENAME ?MODE?" } 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" } |
︙ | ︙ | |||
106 107 108 109 110 111 112 | 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"}} | | | | | | | | 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 | 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?"}} |
︙ | ︙ |