Improvements to test coverage in the lemon-generated parser and in the
sqlite3_get_table() interface. (CVS 4745)

FossilOrigin-Name: 9f95d79daeb5e7f6fd62f3c896dae4d332121d1c
diff --git a/src/btmutex.c b/src/btmutex.c
index 36c22e8..58a1b56 100644
--- a/src/btmutex.c
+++ b/src/btmutex.c
@@ -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 @@
   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 @@
       pLater->locked = 1;
     }
   }
+#endif /* SQLITE_MUTEX_NOOP */
 }
 
 /*
diff --git a/src/main.c b/src/main.c
index 2d9d2ca..bc79451 100644
--- a/src/main.c
+++ b/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 (*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 @@
 ** 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 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 @@
 ** 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 @@
   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(*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 @@
   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 @@
   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 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 @@
   }
 
 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,
diff --git a/src/table.c b/src/table.c
index a79a6ac..48782e8 100644
--- a/src/table.c
+++ b/src/table.c
@@ -75,12 +75,14 @@
       }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 @@
   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 @@
       }
       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 @@
     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;
diff --git a/src/test9.c b/src/test9.c
index 1e92245..a1fb49b 100644
--- a/src/test9.c
+++ b/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 @@
   }
   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 @@
     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;
diff --git a/src/test_config.c b/src/test_config.c
index dcbd8ed..b47ca89 100644
--- a/src/test_config.c
+++ b/src/test_config.c
@@ -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 @@
 ** 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", "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
diff --git a/src/where.c b/src/where.c
index ae8fb4b..50bcea2 100644
--- a/src/where.c
+++ b/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 @@
     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 @@
     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);
       }
     }