Testing coverage enhancements to sqlite3_get_table() and to the SELECT
code generator. (CVS 4746)

FossilOrigin-Name: 45c59802f6d35c7745b96c578ab43d5a336fe822
diff --git a/src/expr.c b/src/expr.c
index 7cd0134..e74bdd1 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.351 2008/01/19 23:50:26 drh Exp $
+** $Id: expr.c,v 1.352 2008/01/23 14:51:49 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -2922,14 +2922,9 @@
 **
 ** This routine should only be called after the expression has been
 ** analyzed by sqlite3ExprResolveNames().
-**
-** If errors are seen, leave an error message in zErrMsg and return
-** the number of errors.
 */
-int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
-  int nErr = pNC->pParse->nErr;
+void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
   walkExprTree(pExpr, analyzeAggregate, pNC);
-  return pNC->pParse->nErr - nErr;
 }
 
 /*
@@ -2938,16 +2933,14 @@
 **
 ** If an error is found, the analysis is cut short.
 */
-int sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){
+void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){
   struct ExprList_item *pItem;
   int i;
-  int nErr = 0;
   if( pList ){
-    for(pItem=pList->a, i=0; nErr==0 && i<pList->nExpr; i++, pItem++){
-      nErr += sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr);
+    for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
+      sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr);
     }
   }
-  return nErr;
 }
 
 /*
diff --git a/src/select.c b/src/select.c
index 5579a81..48925b5 100644
--- a/src/select.c
+++ b/src/select.c
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.406 2008/01/19 03:35:59 drh Exp $
+** $Id: select.c,v 1.407 2008/01/23 14:51:50 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -502,7 +502,7 @@
 ** then data is pulled from srcTab and pEList is used only to get the
 ** datatypes for each column.
 */
-static int selectInnerLoop(
+static void selectInnerLoop(
   Parse *pParse,          /* The parser context */
   Select *p,              /* The complete select statement being coded */
   ExprList *pEList,       /* List of values being extracted */
@@ -524,7 +524,7 @@
   int nResultCol;             /* Number of result columns */
   int nToFree;                /* Number of result columns to release */
 
-  if( v==0 ) return 0;
+  if( v==0 ) return;
   assert( pEList!=0 );
 
   /* If there was a LIMIT clause on the SELECT statement, then do the check
@@ -577,7 +577,7 @@
   }
 
   if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
-    return 0;
+    return;
   }
 
   switch( eDest ){
@@ -722,7 +722,6 @@
     sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak);
   }
   sqlite3ReleaseTempRange(pParse, regResult, nToFree);
-  return 0;
 }
 
 /*
@@ -2057,12 +2056,8 @@
         computeLimitRegisters(pParse, p, iBreak);
         sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
         iStart = sqlite3VdbeCurrentAddr(v);
-        rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
-                             pOrderBy, -1, &dest, iCont, iBreak, 0);
-        if( rc ){
-          rc = 1;
-          goto multi_select_end;
-        }
+        selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
+                        pOrderBy, -1, &dest, iCont, iBreak, 0);
         sqlite3VdbeResolveLabel(v, iCont);
         sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
         sqlite3VdbeResolveLabel(v, iBreak);
@@ -2141,12 +2136,8 @@
       iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
       sqlite3VdbeAddOp3(v, OP_NotFound, tab2, iCont, r1);
       sqlite3ReleaseTempReg(pParse, r1);
-      rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
-                             pOrderBy, -1, &dest, iCont, iBreak, 0);
-      if( rc ){
-        rc = 1;
-        goto multi_select_end;
-      }
+      selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
+                      pOrderBy, -1, &dest, iCont, iBreak, 0);
       sqlite3VdbeResolveLabel(v, iCont);
       sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
       sqlite3VdbeResolveLabel(v, iBreak);
@@ -2919,13 +2910,11 @@
 ** corresponding bit in argument mask is not set. If mask takes the
 ** special value 0xffffffff, then all columns are populated.
 */
-int sqlite3SelectMask(Parse *pParse, Select *p, u32 mask){
+void sqlite3SelectMask(Parse *pParse, Select *p, u32 mask){
   if( !p->pPrior && !p->isDistinct && mask!=0xffffffff ){
     ExprList *pEList;
     int i;
-    if( sqlite3SelectResolve(pParse, p, 0) ){
-      return SQLITE_ERROR;
-    }
+    sqlite3SelectResolve(pParse, p, 0);
     pEList = p->pEList;
     for(i=0; i<pEList->nExpr && i<32; i++){
       if( !(mask&((u32)1<<i)) ){
@@ -2934,7 +2923,6 @@
       }
     }
   }
-  return SQLITE_OK;
 }
 #endif
 
@@ -3201,9 +3189,6 @@
   */
   if( pOrderBy ){
     KeyInfo *pKeyInfo;
-    if( pParse->nErr ){
-      goto select_end;
-    }
     pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
     pOrderBy->iECursor = pParse->nTab++;
     p->addrOpenEphm[2] = addrSortIndex =
@@ -3258,10 +3243,8 @@
     /* Use the standard inner loop
     */
     assert(!isDistinct);
-    if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, -1, pDest,
-                    pWInfo->iContinue, pWInfo->iBreak, aff) ){
-       goto select_end;
-    }
+    selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, -1, pDest,
+                    pWInfo->iContinue, pWInfo->iBreak, aff);
 
     /* End the database scan loop.
     */
@@ -3302,20 +3285,14 @@
     sNC.pAggInfo = &sAggInfo;
     sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
     sAggInfo.pGroupBy = pGroupBy;
-    if( sqlite3ExprAnalyzeAggList(&sNC, pEList) ){
-      goto select_end;
-    }
-    if( sqlite3ExprAnalyzeAggList(&sNC, pOrderBy) ){
-      goto select_end;
-    }
-    if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){
-      goto select_end;
+    sqlite3ExprAnalyzeAggList(&sNC, pEList);
+    sqlite3ExprAnalyzeAggList(&sNC, pOrderBy);
+    if( pHaving ){
+      sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
     }
     sAggInfo.nAccumulator = sAggInfo.nColumn;
     for(i=0; i<sAggInfo.nFunc; i++){
-      if( sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList) ){
-        goto select_end;
-      }
+      sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList);
     }
     if( db->mallocFailed ) goto select_end;
 
@@ -3377,12 +3354,9 @@
       if( pHaving ){
         sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
       }
-      rc = selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
-                           distinct, pDest,
-                           addrOutputRow+1, addrSetAbort, aff);
-      if( rc ){
-        goto select_end;
-      }
+      selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
+                      distinct, pDest,
+                      addrOutputRow+1, addrSetAbort, aff);
       sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
       VdbeComment((v, "end groupby result generator"));
 
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 1c9951d..f8393fe 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.654 2008/01/23 03:03:05 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.655 2008/01/23 14:51:50 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1760,7 +1760,7 @@
 Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
                          Expr*,ExprList*,int,Expr*,Expr*);
 void sqlite3SelectDelete(Select*);
-int sqlite3SelectMask(Parse *, Select *, u32);
+void sqlite3SelectMask(Parse *, Select *, u32);
 Table *sqlite3SrcListLookup(Parse*, SrcList*);
 int sqlite3IsReadOnly(Parse*, Table*, int);
 void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
@@ -1785,8 +1785,8 @@
 char *sqlite3NameFromToken(sqlite3*, Token*);
 int sqlite3ExprCompare(Expr*, Expr*);
 int sqlite3ExprResolveNames(NameContext *, Expr *);
-int sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
-int sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
+void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
+void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
 Vdbe *sqlite3GetVdbe(Parse*);
 Expr *sqlite3CreateIdExpr(Parse *, const char*);
 void sqlite3Randomness(int, void*);
diff --git a/src/table.c b/src/table.c
index 48782e8..88a96ee 100644
--- a/src/table.c
+++ b/src/table.c
@@ -70,11 +70,7 @@
   if( p->nRow==0 ){
     p->nColumn = nCol;
     for(i=0; i<nCol; i++){
-      if( colv[i]==0 ){
-        z = sqlite3_mprintf("");
-      }else{
-        z = sqlite3_mprintf("%s", colv[i]);
-      }
+      z = sqlite3_mprintf("%s", colv[i]);
       if( z==0 ) goto malloc_failed;
       p->azResult[p->nData++] = z;
     }
@@ -130,7 +126,7 @@
 ){
   int rc;
   TabResult res;
-  if( pazResult==0 ){ return SQLITE_ERROR; }
+
   *pazResult = 0;
   if( pnColumn ) *pnColumn = 0;
   if( pnRow ) *pnRow = 0;
@@ -148,10 +144,8 @@
   }
   res.azResult[0] = 0;
   rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
-  if( res.azResult ){
-    assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
-    res.azResult[0] = (char*)res.nData;
-  }
+  assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
+  res.azResult[0] = (char*)res.nData;
   if( (rc&0xff)==SQLITE_ABORT ){
     sqlite3_free_table(&res.azResult[1]);
     if( res.zErrMsg ){
@@ -195,7 +189,7 @@
   if( azResult ){
     int i, n;
     azResult--;
-    if( azResult==0 ) return;
+    assert( azResult!=0 );
     n = (int)azResult[0];
     for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
     sqlite3_free(azResult);
diff --git a/src/test1.c b/src/test1.c
index 2774892..5fb8fa7 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.286 2008/01/22 21:30:53 drh Exp $
+** $Id: test1.c,v 1.287 2008/01/23 14:51:50 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -494,7 +494,7 @@
 }
 
 /*
-** Usage:  sqlite3_get_table_printf  DB  FORMAT  STRING
+** Usage:  sqlite3_get_table_printf  DB  FORMAT  STRING  ?--no-counts?
 **
 ** Invoke the sqlite3_get_table_printf() interface using the open database
 ** DB.  The SQL is the string FORMAT.  The format string should contain
@@ -515,24 +515,35 @@
   int i;
   char zBuf[30];
   char *zSql;
-  if( argc!=4 ){
+  int resCount = -1;
+  if( argc==5 ){
+    if( Tcl_GetInt(interp, argv[4], &resCount) ) return TCL_ERROR;
+  }
+  if( argc!=4 && argc!=5 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
-       " DB FORMAT STRING", 0);
+       " DB FORMAT STRING ?COUNT?", 0);
     return TCL_ERROR;
   }
   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
   Tcl_DStringInit(&str);
   zSql = sqlite3_mprintf(argv[2],argv[3]);
-  rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr);
+  if( argc==5 ){
+    rc = sqlite3_get_table(db, zSql, &aResult, 0, 0, &zErr);
+  }else{
+    rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr);
+    resCount = (nRow+1)*nCol;
+  }
   sqlite3_free(zSql);
   sprintf(zBuf, "%d", rc);
   Tcl_AppendElement(interp, zBuf);
   if( rc==SQLITE_OK ){
-    sprintf(zBuf, "%d", nRow);
-    Tcl_AppendElement(interp, zBuf);
-    sprintf(zBuf, "%d", nCol);
-    Tcl_AppendElement(interp, zBuf);
-    for(i=0; i<(nRow+1)*nCol; i++){
+    if( argc==4 ){
+      sprintf(zBuf, "%d", nRow);
+      Tcl_AppendElement(interp, zBuf);
+      sprintf(zBuf, "%d", nCol);
+      Tcl_AppendElement(interp, zBuf);
+    }
+    for(i=0; i<resCount; i++){
       Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");
     }
   }else{