mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-18 10:21:03 +03:00
Improvements to test coverage in the lemon-generated parser and in the
sqlite3_get_table() interface. (CVS 4745) FossilOrigin-Name: 9f95d79daeb5e7f6fd62f3c896dae4d332121d1c
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
** $Id: btmutex.c,v 1.8 2007/12/07 18:55:28 drh Exp $
|
||||
** $Id: btmutex.c,v 1.9 2008/01/23 12:52:41 drh Exp $
|
||||
**
|
||||
** This file contains code used to implement mutexes on Btree objects.
|
||||
** This code really belongs in btree.c. But btree.c is getting too
|
||||
@@ -61,6 +61,7 @@ void sqlite3BtreeEnter(Btree *p){
|
||||
p->wantToLock++;
|
||||
if( p->locked ) return;
|
||||
|
||||
#ifndef SQLITE_MUTEX_NOOP
|
||||
/* In most cases, we should be able to acquire the lock we
|
||||
** want without having to go throught the ascending lock
|
||||
** procedure that follows. Just be sure not to block.
|
||||
@@ -92,6 +93,7 @@ void sqlite3BtreeEnter(Btree *p){
|
||||
pLater->locked = 1;
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_MUTEX_NOOP */
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
36
src/main.c
36
src/main.c
@@ -14,7 +14,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: main.c,v 1.413 2008/01/23 03:03:05 drh Exp $
|
||||
** $Id: main.c,v 1.414 2008/01/23 12:52:41 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -374,9 +374,6 @@ int sqlite3_busy_handler(
|
||||
int (*xBusy)(void*,int),
|
||||
void *pArg
|
||||
){
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->busyHandler.xFunc = xBusy;
|
||||
db->busyHandler.pArg = pArg;
|
||||
@@ -419,9 +416,6 @@ void sqlite3_progress_handler(
|
||||
** specified number of milliseconds before returning 0.
|
||||
*/
|
||||
int sqlite3_busy_timeout(sqlite3 *db, int ms){
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
if( ms>0 ){
|
||||
db->busyTimeout = ms;
|
||||
sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
|
||||
@@ -461,9 +455,6 @@ int sqlite3CreateFunc(
|
||||
int nName;
|
||||
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
if( zFunctionName==0 ||
|
||||
(xFunc && (xFinal || xStep)) ||
|
||||
(!xFunc && (xFinal && !xStep)) ||
|
||||
@@ -849,12 +840,12 @@ const void *sqlite3_errmsg16(sqlite3 *db){
|
||||
** passed to this function, we assume a malloc() failed during sqlite3_open().
|
||||
*/
|
||||
int sqlite3_errcode(sqlite3 *db){
|
||||
if( !db || db->mallocFailed ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
if( !sqlite3SafetyCheckSickOrOk(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
if( !db || db->mallocFailed ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
return db->errCode & db->errMask;
|
||||
}
|
||||
|
||||
@@ -873,9 +864,6 @@ static int createCollation(
|
||||
CollSeq *pColl;
|
||||
int enc2;
|
||||
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
|
||||
/* If SQLITE_UTF16 is specified as the encoding type, transform this
|
||||
@@ -1217,7 +1205,7 @@ int sqlite3_create_collation16(
|
||||
int(*xCompare)(void*,int,const void*,int,const void*)
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
char *zName8;
|
||||
char *zName8;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
assert( !db->mallocFailed );
|
||||
zName8 = sqlite3Utf16to8(db, zName, -1);
|
||||
@@ -1240,9 +1228,6 @@ int sqlite3_collation_needed(
|
||||
void *pCollNeededArg,
|
||||
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
|
||||
){
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->xCollNeeded = xCollNeeded;
|
||||
db->xCollNeeded16 = 0;
|
||||
@@ -1261,9 +1246,6 @@ int sqlite3_collation_needed16(
|
||||
void *pCollNeededArg,
|
||||
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
|
||||
){
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->xCollNeeded = 0;
|
||||
db->xCollNeeded16 = xCollNeeded16;
|
||||
@@ -1345,9 +1327,7 @@ int sqlite3_table_column_metadata(
|
||||
int autoinc = 0;
|
||||
|
||||
/* Ensure the database schema has been loaded */
|
||||
if( !sqlite3SafetyCheckOk(db) || sqlite3SafetyOn(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
(void)sqlite3SafetyOn(db);
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
rc = sqlite3Init(db, &zErrMsg);
|
||||
if( SQLITE_OK!=rc ){
|
||||
@@ -1405,9 +1385,7 @@ int sqlite3_table_column_metadata(
|
||||
}
|
||||
|
||||
error_out:
|
||||
if( sqlite3SafetyOff(db) ){
|
||||
rc = SQLITE_MISUSE;
|
||||
}
|
||||
(void)sqlite3SafetyOff(db);
|
||||
|
||||
/* Whether the function call succeeded or failed, set the output parameters
|
||||
** to whatever their local counterparts contain. If an error did occur,
|
||||
|
||||
25
src/table.c
25
src/table.c
@@ -75,12 +75,14 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
|
||||
}else{
|
||||
z = sqlite3_mprintf("%s", colv[i]);
|
||||
}
|
||||
if( z==0 ) goto malloc_failed;
|
||||
p->azResult[p->nData++] = z;
|
||||
}
|
||||
}else if( p->nColumn!=nCol ){
|
||||
sqlite3SetString(&p->zErrMsg,
|
||||
"sqlite3_get_table() called with two or more incompatible queries",
|
||||
(char*)0);
|
||||
sqlite3_free(p->zErrMsg);
|
||||
p->zErrMsg = sqlite3_mprintf(
|
||||
"sqlite3_get_table() called with two or more incompatible queries"
|
||||
);
|
||||
p->rc = SQLITE_ERROR;
|
||||
return 1;
|
||||
}
|
||||
@@ -139,15 +141,13 @@ int sqlite3_get_table(
|
||||
res.nData = 1;
|
||||
res.nAlloc = 20;
|
||||
res.rc = SQLITE_OK;
|
||||
res.azResult = sqlite3_malloc( sizeof(char*)*res.nAlloc );
|
||||
if( res.azResult==0 ) return SQLITE_NOMEM;
|
||||
res.azResult = sqlite3_malloc(sizeof(char*)*res.nAlloc );
|
||||
if( res.azResult==0 ){
|
||||
db->errCode = SQLITE_NOMEM;
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
res.azResult[0] = 0;
|
||||
rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
|
||||
#ifndef NDEBUG
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
assert((rc&db->errMask)==rc && (res.rc&db->errMask)==res.rc);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
#endif
|
||||
if( res.azResult ){
|
||||
assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
|
||||
res.azResult[0] = (char*)res.nData;
|
||||
@@ -161,9 +161,7 @@ int sqlite3_get_table(
|
||||
}
|
||||
sqlite3_free(res.zErrMsg);
|
||||
}
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->errCode = res.rc;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
db->errCode = res.rc; /* Assume 32-bit assignment is atomic */
|
||||
return res.rc;
|
||||
}
|
||||
sqlite3_free(res.zErrMsg);
|
||||
@@ -176,6 +174,7 @@ int sqlite3_get_table(
|
||||
azNew = sqlite3_realloc( res.azResult, sizeof(char*)*(res.nData+1) );
|
||||
if( azNew==0 ){
|
||||
sqlite3_free_table(&res.azResult[1]);
|
||||
db->errCode = SQLITE_NOMEM;
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
res.nAlloc = res.nData+1;
|
||||
|
||||
52
src/test9.c
52
src/test9.c
@@ -14,7 +14,7 @@
|
||||
** for completeness. Test code is written in C for these cases
|
||||
** as there is not much point in binding to Tcl.
|
||||
**
|
||||
** $Id: test9.c,v 1.4 2007/08/21 10:44:16 drh Exp $
|
||||
** $Id: test9.c,v 1.5 2008/01/23 12:52:41 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@@ -131,41 +131,22 @@ static int c_misuse_test(
|
||||
}
|
||||
sqlite3_close(db);
|
||||
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
rc = sqlite3_collation_needed16(db, 0, 0);
|
||||
if( rc!=SQLITE_MISUSE ){
|
||||
zErrFunction = "sqlite3_collation_needed16";
|
||||
goto error_out;
|
||||
}
|
||||
#endif
|
||||
|
||||
rc = sqlite3_collation_needed(db, 0, 0);
|
||||
if( rc!=SQLITE_MISUSE ){
|
||||
zErrFunction = "sqlite3_collation_needed";
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
rc = sqlite3_create_collation(db, 0, 0, 0, 0);
|
||||
if( rc!=SQLITE_MISUSE ){
|
||||
zErrFunction = "sqlite3_create_collation";
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
rc = sqlite3_create_function(db, 0, 0, 0, 0, 0, 0, 0);
|
||||
if( rc!=SQLITE_MISUSE ){
|
||||
zErrFunction = "sqlite3_create_function";
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
rc = sqlite3_busy_handler(db, 0, 0);
|
||||
if( rc!=SQLITE_MISUSE ){
|
||||
zErrFunction = "sqlite3_busy_handler";
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
rc = sqlite3_errcode(db);
|
||||
if( rc!=SQLITE_MISUSE ){
|
||||
zErrFunction = "sqlite3_busy_handler";
|
||||
zErrFunction = "sqlite3_errcode";
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
rc = sqlite3_prepare(db, 0, 0, 0, 0);
|
||||
if( rc!=SQLITE_MISUSE ){
|
||||
zErrFunction = "sqlite3_prepare";
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
rc = sqlite3_prepare_v2(db, 0, 0, 0, 0);
|
||||
if( rc!=SQLITE_MISUSE ){
|
||||
zErrFunction = "sqlite3_prepare_v2";
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
@@ -175,6 +156,11 @@ static int c_misuse_test(
|
||||
zErrFunction = "sqlite3_prepare16";
|
||||
goto error_out;
|
||||
}
|
||||
rc = sqlite3_prepare16_v2(db, 0, 0, 0, 0);
|
||||
if( rc!=SQLITE_MISUSE ){
|
||||
zErrFunction = "sqlite3_prepare16_v2";
|
||||
goto error_out;
|
||||
}
|
||||
#endif
|
||||
|
||||
return TCL_OK;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
** The focus of this file is providing the TCL testing layer
|
||||
** access to compile-time constants.
|
||||
**
|
||||
** $Id: test_config.c,v 1.18 2008/01/22 23:37:10 drh Exp $
|
||||
** $Id: test_config.c,v 1.19 2008/01/23 12:52:41 drh Exp $
|
||||
*/
|
||||
|
||||
#include "sqliteLimit.h"
|
||||
@@ -44,6 +44,8 @@ int sqlite3MAX_LIKE_PATTERN_LENGTH = SQLITE_MAX_LIKE_PATTERN_LENGTH;
|
||||
** procedures use this to determine when tests should be omitted.
|
||||
*/
|
||||
static void set_options(Tcl_Interp *interp){
|
||||
int rc = 0;
|
||||
|
||||
#ifdef SQLITE_32BIT_ROWID
|
||||
Tcl_SetVar2(interp, "sqlite_options", "rowid32", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
@@ -366,12 +368,13 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
|
||||
Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
rc = sqlite3_threadsafe();
|
||||
#if SQLITE_THREADSAFE
|
||||
Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY);
|
||||
assert( sqlite3_threadsafe() );
|
||||
assert( rc );
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "0", TCL_GLOBAL_ONLY);
|
||||
assert( !sqlite3_threadsafe() );
|
||||
assert( !rc );
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_TRACE
|
||||
|
||||
16
src/where.c
16
src/where.c
@@ -16,7 +16,7 @@
|
||||
** so is applicable. Because this module is responsible for selecting
|
||||
** indices, you might also think of this module as the "query optimizer".
|
||||
**
|
||||
** $Id: where.c,v 1.285 2008/01/23 03:03:05 drh Exp $
|
||||
** $Id: where.c,v 1.286 2008/01/23 12:52:41 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -540,11 +540,9 @@ static int isLikeOrGlob(
|
||||
return 0;
|
||||
}
|
||||
pColl = pLeft->pColl;
|
||||
assert( pColl!=0 || pLeft->iColumn==-1 );
|
||||
if( pColl==0 ){
|
||||
/* TODO: Coverage testing doesn't get this case. Is it actually possible
|
||||
** for an expression of type TK_COLUMN to not have an assigned collation
|
||||
** sequence at this point?
|
||||
*/
|
||||
/* No collation is defined for the ROWID. Use the default. */
|
||||
pColl = db->pDfltColl;
|
||||
}
|
||||
if( (pColl->type!=SQLITE_COLL_BINARY || noCase) &&
|
||||
@@ -1859,13 +1857,7 @@ static void whereInfoFree(WhereInfo *pWInfo){
|
||||
for(i=0; i<pWInfo->nLevel; i++){
|
||||
sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo;
|
||||
if( pInfo ){
|
||||
if( pInfo->needToFreeIdxStr ){
|
||||
/* Coverage: Don't think this can be reached. By the time this
|
||||
** function is called, the index-strings have been passed
|
||||
** to the vdbe layer for deletion.
|
||||
*/
|
||||
sqlite3_free(pInfo->idxStr);
|
||||
}
|
||||
assert( pInfo->needToFreeIdxStr==0 );
|
||||
sqlite3_free(pInfo);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user