Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Testing coverage enhancements. (CVS 5358) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
fe80aa58a4ac12db5a92d25d28165f51 |
User & Date: | drh 2008-07-08 00:06:50.000 |
Context
2008-07-08
| ||
02:12 | Add tests to verify correct behavior when mutex initialization fails. (CVS 5359) (check-in: 65875005ac user: drh tags: trunk) | |
00:06 | Testing coverage enhancements. (CVS 5358) (check-in: fe80aa58a4 user: drh tags: trunk) | |
2008-07-07
| ||
19:52 | Make check-in (5356) compatible with builds that do not enable memory management. Remove unnecessary code from main.c. Add out-of-memory tests for sqlite3_complete16(). (CVS 5357) (check-in: 28f8b6bfcc user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
18 19 20 21 22 23 24 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** ** $Id: build.c,v 1.486 2008/07/08 00:06:50 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. |
︙ | ︙ | |||
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | ** Not everything is nestable. This facility is designed to permit ** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use ** care if you decide to try to use this routine for some other purposes. */ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ va_list ap; char *zSql; # define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar)) char saveBuf[SAVE_SZ]; if( pParse->nErr ) return; assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ va_start(ap, zFormat); zSql = sqlite3VMPrintf(pParse->db, zFormat, ap); va_end(ap); if( zSql==0 ){ pParse->db->mallocFailed = 1; return; /* A malloc must have failed */ } pParse->nested++; memcpy(saveBuf, &pParse->nVar, SAVE_SZ); memset(&pParse->nVar, 0, SAVE_SZ); | > | > | 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | ** Not everything is nestable. This facility is designed to permit ** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use ** care if you decide to try to use this routine for some other purposes. */ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ va_list ap; char *zSql; char *zErrMsg = 0; # define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar)) char saveBuf[SAVE_SZ]; if( pParse->nErr ) return; assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ va_start(ap, zFormat); zSql = sqlite3VMPrintf(pParse->db, zFormat, ap); va_end(ap); if( zSql==0 ){ pParse->db->mallocFailed = 1; return; /* A malloc must have failed */ } pParse->nested++; memcpy(saveBuf, &pParse->nVar, SAVE_SZ); memset(&pParse->nVar, 0, SAVE_SZ); sqlite3RunParser(pParse, zSql, &zErrMsg); sqlite3_free(zErrMsg); sqlite3_free(zSql); memcpy(&pParse->nVar, saveBuf, SAVE_SZ); pParse->nested--; } /* ** Locate the in-memory structure that describes a particular database |
︙ | ︙ |
Changes to src/test_mutex.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* ** 2008 June 18 ** ** 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. ** ************************************************************************* ** | | > > > | > > | | | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 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 | /* ** 2008 June 18 ** ** 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. ** ************************************************************************* ** ** $Id: test_mutex.c,v 1.5 2008/07/08 00:06:50 drh Exp $ */ #include "tcl.h" #include "sqlite3.h" #include <stdlib.h> #include <assert.h> #include <string.h> /* defined in test1.c */ const char *sqlite3TestErrorName(int); /* A countable mutex */ struct sqlite3_mutex { sqlite3_mutex *pReal; int eType; }; /* State variables */ static struct test_mutex_globals { int isInstalled; /* True if installed */ int disableInit; /* True to cause sqlite3_initalize() to fail */ int isInit; /* True if initialized */ sqlite3_mutex_methods m; /* Interface to "real" mutex system */ int aCounter[8]; /* Number of grabs of each type of mutex */ sqlite3_mutex aStatic[6]; /* The six static mutexes */ } g; /* Return true if the countable mutex is currently held */ static int counterMutexHeld(sqlite3_mutex *p){ return g.m.xMutexHeld(p->pReal); } /* Return true if the countable mutex is not currently held */ static int counterMutexNotheld(sqlite3_mutex *p){ return g.m.xMutexNotheld(p->pReal); } /* Initialize the countable mutex interface ** Or, if g.disableInit is non-zero, then do not initialize but instead ** return the value of g.disableInit as the result code. This can be used ** to simulate an initialization failure. */ static int counterMutexInit(void){ int rc; if( g.disableInit ) return g.disableInit; rc = g.m.xMutexInit(); g.isInit = 1; return rc; } /* ** Uninitialize the mutex subsystem */ static int counterMutexEnd(void){ assert( g.isInit ); g.isInit = 0; return g.m.xMutexEnd(); } /* ** Allocate a countable mutex */ static sqlite3_mutex *counterMutexAlloc(int eType){ sqlite3_mutex *pReal; sqlite3_mutex *pRet = 0; assert( g.isInit ); assert(eType<8 && eType>=0); pReal = g.m.xMutexAlloc(eType); if( !pReal ) return 0; if( eType==0 || eType==1 ){ pRet = (sqlite3_mutex *)malloc(sizeof(sqlite3_mutex)); }else{ pRet = &g.aStatic[eType-2]; } pRet->eType = eType; pRet->pReal = pReal; return pRet; } /* ** Free a countable mutex */ static void counterMutexFree(sqlite3_mutex *p){ assert( g.isInit ); g.m.xMutexFree(p->pReal); if( p->eType==0 || p->eType==1 ){ free(p); } } /* ** Enter a countable mutex. Block until entry is safe. */ static void counterMutexEnter(sqlite3_mutex *p){ assert( g.isInit ); g.aCounter[p->eType]++; g.m.xMutexEnter(p->pReal); } /* ** Try to enter a mutex. Return true on success. */ static int counterMutexTry(sqlite3_mutex *p){ assert( g.isInit ); g.aCounter[p->eType]++; return g.m.xMutexTry(p->pReal); } /* Leave a mutex */ static void counterMutexLeave(sqlite3_mutex *p){ assert( g.isInit ); g.m.xMutexLeave(p->pReal); } /* ** sqlite3_shutdown */ static int test_shutdown( |
︙ | ︙ | |||
297 298 299 300 301 302 303 304 305 | { "clear_mutex_counters", (Tcl_ObjCmdProc*)test_clear_mutex_counters }, }; int i; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } memset(&g, 0, sizeof(g)); return SQLITE_OK; } | > > > | 337 338 339 340 341 342 343 344 345 346 347 348 | { "clear_mutex_counters", (Tcl_ObjCmdProc*)test_clear_mutex_counters }, }; int i; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } memset(&g, 0, sizeof(g)); Tcl_LinkVar(interp, "disable_mutex_init", (char*)&g.disableInit, TCL_LINK_INT); return SQLITE_OK; } |
Changes to src/tokenize.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** ** $Id: tokenize.c,v 1.145 2008/07/08 00:06:50 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include <stdlib.h> /* ** The charMap() macro maps alphabetic characters into their |
︙ | ︙ | |||
370 371 372 373 374 375 376 | *tokenType = TK_ILLEGAL; return 1; } /* ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs | | | | > | 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | *tokenType = TK_ILLEGAL; return 1; } /* ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs ** then an and attempt is made to write an error message into ** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that ** error message. */ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ int nErr = 0; int i; void *pEngine; int tokenType; int lastTokenParsed = -1; sqlite3 *db = pParse->db; int mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; if( db->activeVdbeCnt==0 ){ db->u1.isInterrupted = 0; } pParse->rc = SQLITE_OK; pParse->zTail = pParse->zSql = zSql; i = 0; assert( pzErrMsg!=0 ); pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc); if( pEngine==0 ){ db->mallocFailed = 1; return SQLITE_NOMEM; } assert( pParse->sLastToken.dyn==0 ); assert( pParse->pNewTable==0 ); |
︙ | ︙ | |||
416 417 418 419 420 421 422 | break; } switch( tokenType ){ case TK_SPACE: case TK_COMMENT: { if( db->u1.isInterrupted ){ pParse->rc = SQLITE_INTERRUPT; | < | < < | | | < | 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | break; } switch( tokenType ){ case TK_SPACE: case TK_COMMENT: { if( db->u1.isInterrupted ){ pParse->rc = SQLITE_INTERRUPT; sqlite3SetString(pzErrMsg, "interrupt", (char*)0); goto abort_parse; } break; } case TK_ILLEGAL: { sqlite3_free(*pzErrMsg); *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"", &pParse->sLastToken); nErr++; goto abort_parse; } case TK_SEMI: { pParse->zTail = &zSql[i]; /* Fall thru into the default case */ } |
︙ | ︙ | |||
462 463 464 465 466 467 468 | if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0); } if( pParse->zErrMsg ){ | | | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0); } if( pParse->zErrMsg ){ if( *pzErrMsg==0 ){ *pzErrMsg = pParse->zErrMsg; }else{ sqlite3_free(pParse->zErrMsg); } pParse->zErrMsg = 0; nErr++; } |
︙ | ︙ |
Changes to test/bind.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2003 September 6 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script testing the sqlite_bind API. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2003 September 6 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script testing the sqlite_bind API. # # $Id: bind.test,v 1.43 2008/07/08 00:06:51 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl proc sqlite_step {stmt N VALS COLS} { upvar VALS vals |
︙ | ︙ | |||
87 88 89 90 91 92 93 94 95 96 97 98 99 100 | do_test bind-1.9 { sqlite3_reset $VM sqlite_bind $VM 1 {456} normal sqlite_step $VM N VALUES COLNAMES execsql {SELECT rowid, * FROM t1} } {1 123 abcdefg {} 2 456 abcdefg {}} do_test bind-1.99 { sqlite3_finalize $VM } SQLITE_OK # Prepare the statement in different ways depending on whether or not # the $var processing is compiled into the library. # | > > > > > > > > > > > > > | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | do_test bind-1.9 { sqlite3_reset $VM sqlite_bind $VM 1 {456} normal sqlite_step $VM N VALUES COLNAMES execsql {SELECT rowid, * FROM t1} } {1 123 abcdefg {} 2 456 abcdefg {}} do_test bind-1.10 { set rc [catch { sqlite3_prepare db {INSERT INTO t1 VALUES($abc:123,?,:abc)} -1 TAIL } msg] lappend rc $msg } {1 {(1) near ":123": syntax error}} do_test bind-1.11 { set rc [catch { sqlite3_prepare db {INSERT INTO t1 VALUES(@abc:xyz,?,:abc)} -1 TAIL } msg] lappend rc $msg } {1 {(1) near ":xyz": syntax error}} do_test bind-1.99 { sqlite3_finalize $VM } SQLITE_OK # Prepare the statement in different ways depending on whether or not # the $var processing is compiled into the library. # |
︙ | ︙ |
Added test/tokenize.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | # 2008 July 7 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script testing the tokenizer # # $Id: tokenize.test,v 1.1 2008/07/08 00:06:51 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl do_test tokenize-1.1 { catchsql {SELECT 1.0e+} } {1 {unrecognized token: "1.0e"}} do_test tokenize-1.2 { catchsql {SELECT 1.0E+} } {1 {unrecognized token: "1.0E"}} do_test tokenize-1.3 { catchsql {SELECT 1.0e-} } {1 {unrecognized token: "1.0e"}} do_test tokenize-1.4 { catchsql {SELECT 1.0E-} } {1 {unrecognized token: "1.0E"}} do_test tokenize-1.5 { catchsql {SELECT 1.0e+/} } {1 {unrecognized token: "1.0e"}} do_test tokenize-1.6 { catchsql {SELECT 1.0E+:} } {1 {unrecognized token: "1.0E"}} do_test tokenize-1.7 { catchsql {SELECT 1.0e-:} } {1 {unrecognized token: "1.0e"}} do_test tokenize-1.8 { catchsql {SELECT 1.0E-/} } {1 {unrecognized token: "1.0E"}} do_test tokenize-1.9 { catchsql {SELECT 1.0F+5} } {1 {unrecognized token: "1.0F"}} do_test tokenize-1.10 { catchsql {SELECT 1.0d-10} } {1 {unrecognized token: "1.0d"}} do_test tokenize-1.11 { catchsql {SELECT 1.0e,5} } {1 {unrecognized token: "1.0e"}} do_test tokenize-1.12 { catchsql {SELECT 1.0E.10} } {1 {unrecognized token: "1.0E"}} do_test tokenize-2.1 { catchsql {SELECT 1, 2 /*} } {1 {near "*": syntax error}} do_test tokenize-2.2 { catchsql {SELECT 1, 2 /* } } {0 {1 2}} finish_test |