/ Check-in [f1e44eb3]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Additional coverage testing. Fix a segfault following OOM in sqltie3_load_extension(). (CVS 5523)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:f1e44eb323f05495cbae25113aebcc50d16b40df
User & Date: drh 2008-08-02 03:50:39
Context
2008-08-02
15:10
Increase the ref-count on the sqlite3_vtab structure before calling either the xNext or xFilter methods. (CVS 5524) check-in: 6e41455f user: danielk1977 tags: trunk
03:50
Additional coverage testing. Fix a segfault following OOM in sqltie3_load_extension(). (CVS 5523) check-in: f1e44eb3 user: drh tags: trunk
2008-08-01
20:10
Bring test coverage up to 99%. (CVS 5522) check-in: 2cd6bae8 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    18     18   **     CREATE INDEX
    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **
    25         -** $Id: build.c,v 1.491 2008/07/28 19:34:53 drh Exp $
           25  +** $Id: build.c,v 1.492 2008/08/02 03:50:39 drh Exp $
    26     26   */
    27     27   #include "sqliteInt.h"
    28     28   #include <ctype.h>
    29     29   
    30     30   /*
    31     31   ** This routine is called when a new SQL statement is beginning to
    32     32   ** be parsed.  Initialize the pParse structure as needed.
................................................................................
   133    133     sqlite3 *db;
   134    134     Vdbe *v;
   135    135   
   136    136     db = pParse->db;
   137    137     if( db->mallocFailed ) return;
   138    138     if( pParse->nested ) return;
   139    139     if( pParse->nErr ) return;
   140         -  if( !pParse->pVdbe ){
   141         -    if( pParse->rc==SQLITE_OK && pParse->nErr ){
   142         -      pParse->rc = SQLITE_ERROR;
   143         -      return;
   144         -    }
   145         -  }
   146    140   
   147    141     /* Begin by generating some termination code at the end of the
   148    142     ** vdbe program
   149    143     */
   150    144     v = sqlite3GetVdbe(pParse);
   151    145     if( v ){
   152    146       sqlite3VdbeAddOp0(v, OP_Halt);

Changes to src/legacy.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: legacy.c,v 1.28 2008/07/28 19:34:53 drh Exp $
           17  +** $Id: legacy.c,v 1.29 2008/08/02 03:50:39 drh Exp $
    18     18   */
    19     19   
    20     20   #include "sqliteInt.h"
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** Execute SQL code.  Return one of the SQLITE_ success/failure
................................................................................
    80     80               azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
    81     81               if( azCols==0 ){
    82     82                 goto exec_out;
    83     83               }
    84     84             }
    85     85             for(i=0; i<nCol; i++){
    86     86               azCols[i] = (char *)sqlite3_column_name(pStmt, i);
    87         -            if( !azCols[i] ){
    88         -              db->mallocFailed = 1;
    89         -              goto exec_out;
    90         -            }
           87  +            /* sqlite3VdbeSetColName() installs column names as UTF8
           88  +            ** strings so there is no way for sqlite3_column_name() to fail. */
           89  +            assert( azCols[i]!=0 );
    91     90             }
    92     91             nCallback++;
    93     92           }
    94     93           if( rc==SQLITE_ROW ){
    95     94             azVals = &azCols[nCol];
    96     95             for(i=0; i<nCol; i++){
    97     96               azVals[i] = (char *)sqlite3_column_text(pStmt, i);

Changes to src/loadext.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to dynamically load extensions into
    13     13   ** the SQLite library.
    14     14   **
    15         -** $Id: loadext.c,v 1.52 2008/07/28 19:34:53 drh Exp $
           15  +** $Id: loadext.c,v 1.53 2008/08/02 03:50:39 drh Exp $
    16     16   */
    17     17   
    18     18   #ifndef SQLITE_CORE
    19     19     #define SQLITE_CORE 1  /* Disable the API redefinition in sqlite3ext.h */
    20     20   #endif
    21     21   #include "sqlite3ext.h"
    22     22   #include "sqliteInt.h"
................................................................................
   388    388       }
   389    389       sqlite3_free(zErrmsg);
   390    390       sqlite3OsDlClose(pVfs, handle);
   391    391       return SQLITE_ERROR;
   392    392     }
   393    393   
   394    394     /* Append the new shared library handle to the db->aExtension array. */
   395         -  db->nExtension++;
   396         -  aHandle = sqlite3DbMallocZero(db, sizeof(handle)*db->nExtension);
          395  +  aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
   397    396     if( aHandle==0 ){
   398    397       return SQLITE_NOMEM;
   399    398     }
   400    399     if( db->nExtension>0 ){
   401         -    memcpy(aHandle, db->aExtension, sizeof(handle)*(db->nExtension-1));
          400  +    memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
   402    401     }
   403    402     sqlite3DbFree(db, db->aExtension);
   404    403     db->aExtension = aHandle;
   405    404   
   406         -  db->aExtension[db->nExtension-1] = handle;
          405  +  db->aExtension[db->nExtension++] = handle;
   407    406     return SQLITE_OK;
   408    407   }
   409    408   int sqlite3_load_extension(
   410    409     sqlite3 *db,          /* Load the extension into this database connection */
   411    410     const char *zFile,    /* Name of the shared library containing extension */
   412    411     const char *zProc,    /* Entry point.  Use "sqlite3_extension_init" if 0 */
   413    412     char **pzErrMsg       /* Put error message here if not 0 */

Changes to src/pager.c.

    14     14   ** The pager is used to access a database disk file.  It implements
    15     15   ** atomic commit and rollback through the use of a journal file that
    16     16   ** is separate from the database file.  The pager also implements file
    17     17   ** locking to prevent two processes from writing the same database
    18     18   ** file simultaneously, or one process from reading the database while
    19     19   ** another is writing.
    20     20   **
    21         -** @(#) $Id: pager.c,v 1.468 2008/08/01 10:50:23 danielk1977 Exp $
           21  +** @(#) $Id: pager.c,v 1.469 2008/08/02 03:50:39 drh Exp $
    22     22   */
    23     23   #ifndef SQLITE_OMIT_DISKIO
    24     24   #include "sqliteInt.h"
    25     25   #include <assert.h>
    26     26   #include <string.h>
    27     27   
    28     28   /*
................................................................................
  4576   4576   ** stored at byte 24 of the pager file.
  4577   4577   */
  4578   4578   static int pager_incr_changecounter(Pager *pPager, int isDirect){
  4579   4579     PgHdr *pPgHdr;
  4580   4580     u32 change_counter;
  4581   4581     int rc = SQLITE_OK;
  4582   4582   
         4583  +#ifndef SQLITE_ENABLE_ATOMIC_WRITE
         4584  +  assert( isDirect==0 );  /* isDirect is only true for atomic writes */
         4585  +#endif
  4583   4586     if( !pPager->changeCountDone ){
  4584   4587       /* Open page 1 of the file for writing. */
  4585   4588       rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
  4586   4589       if( rc!=SQLITE_OK ) return rc;
  4587   4590   
  4588   4591       if( !isDirect ){
  4589   4592         rc = sqlite3PagerWrite(pPgHdr);
................................................................................
  4594   4597       }
  4595   4598   
  4596   4599       /* Increment the value just read and write it back to byte 24. */
  4597   4600       change_counter = sqlite3Get4byte((u8*)pPager->dbFileVers);
  4598   4601       change_counter++;
  4599   4602       put32bits(((char*)PGHDR_TO_DATA(pPgHdr))+24, change_counter);
  4600   4603   
         4604  +#ifdef SQLITE_ENABLE_ATOMIC_WRITE
  4601   4605       if( isDirect && pPager->fd->pMethods ){
  4602   4606         const void *zBuf = PGHDR_TO_DATA(pPgHdr);
  4603   4607         rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
  4604   4608       }
         4609  +#endif
  4605   4610   
  4606   4611       /* Release the page reference. */
  4607   4612       sqlite3PagerUnref(pPgHdr);
  4608   4613       pPager->changeCountDone = 1;
  4609   4614     }
  4610   4615     return rc;
  4611   4616   }

Changes to src/prepare.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains the implementation of the sqlite3_prepare()
    13     13   ** interface, and routines that contribute to loading the database schema
    14     14   ** from disk.
    15     15   **
    16         -** $Id: prepare.c,v 1.90 2008/07/28 19:34:53 drh Exp $
           16  +** $Id: prepare.c,v 1.91 2008/08/02 03:50:39 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include <ctype.h>
    20     20   
    21     21   /*
    22     22   ** Fill the InitData structure with an error message that indicates
    23     23   ** that the database is corrupt.
................................................................................
   220    220       rc = SQLITE_NOMEM;
   221    221       goto error_out;
   222    222     }
   223    223     sqlite3BtreeEnter(pDb->pBt);
   224    224     rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, curMain);
   225    225     if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
   226    226       sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
   227         -    goto leave_error_out;
          227  +    goto initone_error_out;
   228    228     }
   229    229   
   230    230     /* Get the database meta information.
   231    231     **
   232    232     ** Meta values are as follows:
   233    233     **    meta[0]   Schema cookie.  Changes with each schema change.
   234    234     **    meta[1]   File format of schema layer.
................................................................................
   242    242     **    meta[9]
   243    243     **
   244    244     ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
   245    245     ** the possible values of meta[4].
   246    246     */
   247    247     if( rc==SQLITE_OK ){
   248    248       int i;
   249         -    for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){
          249  +    for(i=0; i<sizeof(meta)/sizeof(meta[0]); i++){
   250    250         rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
   251         -    }
   252         -    if( rc ){
   253         -      sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
   254         -      goto leave_error_out;
          251  +      if( rc ){
          252  +        sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
          253  +        goto initone_error_out;
          254  +      }
   255    255       }
   256    256     }else{
   257    257       memset(meta, 0, sizeof(meta));
   258    258     }
   259    259     pDb->pSchema->schema_cookie = meta[0];
   260    260   
   261    261     /* If opening a non-empty database, check the text encoding. For the
................................................................................
   270    270         db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0);
   271    271       }else{
   272    272         /* If opening an attached database, the encoding much match ENC(db) */
   273    273         if( meta[4]!=ENC(db) ){
   274    274           sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
   275    275               " text encoding as main database");
   276    276           rc = SQLITE_ERROR;
   277         -        goto leave_error_out;
          277  +        goto initone_error_out;
   278    278         }
   279    279       }
   280    280     }else{
   281    281       DbSetProperty(db, iDb, DB_Empty);
   282    282     }
   283    283     pDb->pSchema->enc = ENC(db);
   284    284   
................................................................................
   299    299     pDb->pSchema->file_format = meta[1];
   300    300     if( pDb->pSchema->file_format==0 ){
   301    301       pDb->pSchema->file_format = 1;
   302    302     }
   303    303     if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
   304    304       sqlite3SetString(pzErrMsg, db, "unsupported file format");
   305    305       rc = SQLITE_ERROR;
   306         -    goto leave_error_out;
          306  +    goto initone_error_out;
   307    307     }
   308    308   
   309    309     /* Ticket #2804:  When we open a database in the newer file format,
   310    310     ** clear the legacy_file_format pragma flag so that a VACUUM will
   311    311     ** not downgrade the database and thus invalidate any descending
   312    312     ** indices that the user might have created.
   313    313     */
................................................................................
   364    364       rc = SQLITE_OK;
   365    365     }
   366    366   
   367    367     /* Jump here for an error that occurs after successfully allocating
   368    368     ** curMain and calling sqlite3BtreeEnter(). For an error that occurs
   369    369     ** before that point, jump to error_out.
   370    370     */
   371         -leave_error_out:
          371  +initone_error_out:
   372    372     sqlite3BtreeCloseCursor(curMain);
   373    373     sqlite3_free(curMain);
   374    374     sqlite3BtreeLeave(pDb->pBt);
   375    375   
   376    376   error_out:
   377    377     if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
   378    378       db->mallocFailed = 1;

Changes to src/select.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains C code routines that are called by the parser
    13     13   ** to handle SELECT statements in SQLite.
    14     14   **
    15         -** $Id: select.c,v 1.461 2008/08/01 18:47:02 drh Exp $
           15  +** $Id: select.c,v 1.462 2008/08/02 03:50:39 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   
    20     20   /*
    21     21   ** Delete all the content of a Select structure but do not deallocate
    22     22   ** the select structure itself.
................................................................................
  1887   1887     SelectDest dest;      /* Alternative data destination */
  1888   1888     Select *pDelete = 0;  /* Chain of simple selects to delete */
  1889   1889     sqlite3 *db;          /* Database connection */
  1890   1890   
  1891   1891     /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
  1892   1892     ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
  1893   1893     */
  1894         -  if( p==0 || p->pPrior==0 ){
  1895         -    rc = 1;
  1896         -    goto multi_select_end;
  1897         -  }
         1894  +  assert( p && p->pPrior );  /* Calling function guarantees this much */
  1898   1895     db = pParse->db;
  1899   1896     pPrior = p->pPrior;
  1900   1897     assert( pPrior->pRightmost!=pPrior );
  1901   1898     assert( pPrior->pRightmost==p->pRightmost );
  1902   1899     if( pPrior->pOrderBy ){
  1903   1900       sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
  1904   1901         selectOpName(p->op));
................................................................................
  1908   1905     if( pPrior->pLimit ){
  1909   1906       sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before",
  1910   1907         selectOpName(p->op));
  1911   1908       rc = 1;
  1912   1909       goto multi_select_end;
  1913   1910     }
  1914   1911   
  1915         -  /* Make sure we have a valid query engine.  If not, create a new one.
  1916         -  */
  1917   1912     v = sqlite3GetVdbe(pParse);
  1918         -  if( v==0 ){
  1919         -    rc = 1;
  1920         -    goto multi_select_end;
  1921         -  }
         1913  +  assert( v!=0 );  /* The VDBE already created by calling function */
  1922   1914   
  1923   1915     /* Create the destination temporary table if necessary
  1924   1916     */
  1925   1917     dest = *pDest;
  1926   1918     if( dest.eDest==SRT_EphemTab ){
  1927   1919       assert( p->pEList );
  1928   1920       sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr);
................................................................................
  3996   3988           sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0);
  3997   3989           sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy);
  3998   3990           j = nGroupBy+1;
  3999   3991           for(i=0; i<sAggInfo.nColumn; i++){
  4000   3992             struct AggInfo_col *pCol = &sAggInfo.aCol[i];
  4001   3993             if( pCol->iSorterColumn>=j ){
  4002   3994               int r1 = j + regBase;
  4003         -            int r2 = sqlite3ExprCodeGetColumn(pParse, 
         3995  +#ifndef NDEBUG
         3996  +            int r2 = 
         3997  +#endif
         3998  +                     sqlite3ExprCodeGetColumn(pParse, 
  4004   3999                                  pCol->pTab, pCol->iColumn, pCol->iTable, r1, 0);
  4005         -            if( r1!=r2 ){
  4006         -              sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1);
  4007         -            }
  4008   4000               j++;
         4001  +
         4002  +            /* sAggInfo.aCol[] only contains one entry per column.  So
         4003  +            ** The reference to pCol->iColumn,pCol->iTable must have been
         4004  +            ** the first reference to that column.  Hence, 
         4005  +            ** sqliteExprCodeGetColumn is guaranteed to put the result in
         4006  +            ** the column requested. 
         4007  +            */
         4008  +            assert( r1==r2 );
  4009   4009             }
  4010   4010           }
  4011   4011           regRecord = sqlite3GetTempReg(pParse);
  4012   4012           sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
  4013   4013           sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, regRecord);
  4014   4014           sqlite3ReleaseTempReg(pParse, regRecord);
  4015   4015           sqlite3ReleaseTempRange(pParse, regBase, nCol);

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.749 2008/08/01 17:37:41 danielk1977 Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.750 2008/08/02 03:50:39 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** Include the configuration header output by 'configure' if we're using the
    21     21   ** autoconf-based build
................................................................................
  2260   2260   #endif
  2261   2261   
  2262   2262   #ifdef SQLITE_OMIT_VIRTUALTABLE
  2263   2263   #  define sqlite3VtabClear(X)
  2264   2264   #  define sqlite3VtabSync(X,Y) (Y)
  2265   2265   #  define sqlite3VtabRollback(X)
  2266   2266   #  define sqlite3VtabCommit(X)
  2267         -#  define sqlite3VtabTransferError(A,B,C)
  2268   2267   #else
  2269   2268      void sqlite3VtabClear(Table*);
  2270   2269      int sqlite3VtabSync(sqlite3 *db, char **);
  2271   2270      int sqlite3VtabRollback(sqlite3 *db);
  2272   2271      int sqlite3VtabCommit(sqlite3 *db);
  2273         -   void sqlite3VtabTransferError(sqlite3 *db, int, sqlite3_vtab*);
  2274   2272   #endif
  2275   2273   void sqlite3VtabMakeWritable(Parse*,Table*);
  2276   2274   void sqlite3VtabLock(sqlite3_vtab*);
  2277   2275   void sqlite3VtabUnlock(sqlite3*, sqlite3_vtab*);
  2278   2276   void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
  2279   2277   void sqlite3VtabFinishParse(Parse*, Token*);
  2280   2278   void sqlite3VtabArgInit(Parse*);

Changes to src/test_func.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing all sorts of SQLite interfaces.  This code
    13     13   ** implements new SQL functions used by the test scripts.
    14     14   **
    15         -** $Id: test_func.c,v 1.9 2008/07/31 01:47:11 shane Exp $
           15  +** $Id: test_func.c,v 1.10 2008/08/02 03:50:39 drh Exp $
    16     16   */
    17     17   #include "sqlite3.h"
    18     18   #include "tcl.h"
    19     19   #include <stdlib.h>
    20     20   #include <string.h>
    21     21   #include <assert.h>
    22     22   
................................................................................
   304    304   */
   305    305   static int autoinstall_test_funcs(
   306    306     void * clientData,
   307    307     Tcl_Interp *interp,
   308    308     int objc,
   309    309     Tcl_Obj *CONST objv[]
   310    310   ){
   311         -  sqlite3_auto_extension((void*)registerTestFunctions);
          311  +  int rc = sqlite3_auto_extension((void*)registerTestFunctions);
          312  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
   312    313     return TCL_OK;
   313    314   }
   314    315   
   315    316   /*
   316    317   ** A bogus step function and finalizer function.
   317    318   */
   318    319   static void tStep(sqlite3_context *a, int b, sqlite3_value **c){}

Changes to src/test_loadext.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Test extension for testing the sqlite3_load_extension() function.
    13     13   **
    14         -** $Id: test_loadext.c,v 1.2 2008/06/19 15:44:00 drh Exp $
           14  +** $Id: test_loadext.c,v 1.3 2008/08/02 03:50:39 drh Exp $
    15     15   */
    16     16   #include <string.h>
    17     17   #include "sqlite3ext.h"
    18     18   SQLITE_EXTENSION_INIT1
    19     19   
    20     20   /*
    21     21   ** The half() SQL function returns half of its input value.
................................................................................
    94     94   ** Extension load function.
    95     95   */
    96     96   int testloadext_init(
    97     97     sqlite3 *db, 
    98     98     char **pzErrMsg, 
    99     99     const sqlite3_api_routines *pApi
   100    100   ){
          101  +  int nErr = 0;
   101    102     SQLITE_EXTENSION_INIT2(pApi);
   102         -  sqlite3_create_function(db, "half", 1, SQLITE_ANY, 0, halfFunc, 0, 0);
   103         -  sqlite3_create_function(db, "sqlite3_status", 1, SQLITE_ANY, 0,
          103  +  nErr |= sqlite3_create_function(db, "half", 1, SQLITE_ANY, 0, halfFunc, 0, 0);
          104  +  nErr |= sqlite3_create_function(db, "sqlite3_status", 1, SQLITE_ANY, 0,
          105  +                          statusFunc, 0, 0);
          106  +  nErr |= sqlite3_create_function(db, "sqlite3_status", 2, SQLITE_ANY, 0,
   104    107                             statusFunc, 0, 0);
   105         -  sqlite3_create_function(db, "sqlite3_status", 2, SQLITE_ANY, 0,
   106         -                          statusFunc, 0, 0);
   107         -  return 0;
          108  +  return nErr ? SQLITE_ERROR : SQLITE_OK;
   108    109   }
   109    110   
   110    111   /*
   111    112   ** Another extension entry point. This one always fails.
   112    113   */
   113    114   int testbrokenext_init(
   114    115     sqlite3 *db, 

Changes to src/vdbeInt.h.

    11     11   *************************************************************************
    12     12   ** This is the header file for information that is private to the
    13     13   ** VDBE.  This information used to all be at the top of the single
    14     14   ** source code file "vdbe.c".  When that file became too big (over
    15     15   ** 6000 lines long) it was split up into several smaller files and
    16     16   ** this header information was factored out.
    17     17   **
    18         -** $Id: vdbeInt.h,v 1.152 2008/07/30 13:14:55 drh Exp $
           18  +** $Id: vdbeInt.h,v 1.153 2008/08/02 03:50:39 drh Exp $
    19     19   */
    20     20   #ifndef _VDBEINT_H_
    21     21   #define _VDBEINT_H_
    22     22   
    23     23   /*
    24     24   ** intToKey() and keyToInt() used to transform the rowid.  But with
    25     25   ** the latest versions of the design they are no-ops.
................................................................................
   314    314     int inTempTrans;        /* True if temp database is transactioned */
   315    315     int nResColumn;         /* Number of columns in one row of the result set */
   316    316     char **azResColumn;     /* Values for one row of result */ 
   317    317     char *zErrMsg;          /* Error message written here */
   318    318     Mem *pResultSet;        /* Pointer to an array of results */
   319    319     u8 explain;             /* True if EXPLAIN present on SQL command */
   320    320     u8 changeCntOn;         /* True to update the change-counter */
   321         -  u8 aborted;             /* True if ROLLBACK in another VM causes an abort */
   322    321     u8 expired;             /* True if the VM needs to be recompiled */
   323    322     u8 minWriteFileFormat;  /* Minimum file format for writable database files */
   324    323     u8 inVtabMethod;        /* See comments above */
   325    324     int nChange;            /* Number of db changes made since last reset */
   326    325     i64 startTime;          /* Time when query started - used for profiling */
   327    326     int btreeMask;          /* Bitmask of db->aDb[] entries referenced */
   328    327     BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */

Changes to src/vdbeapi.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** This file contains code use to implement APIs that are part of the
    14     14   ** VDBE.
    15     15   **
    16         -** $Id: vdbeapi.c,v 1.137 2008/08/01 20:10:08 drh Exp $
           16  +** $Id: vdbeapi.c,v 1.138 2008/08/02 03:50:39 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "vdbeInt.h"
    20     20   
    21     21   #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
    22     22   /*
    23     23   ** The following structure contains pointers to the end points of a
................................................................................
   431    431       return SQLITE_MISUSE;
   432    432     }
   433    433   
   434    434     /* Assert that malloc() has not failed */
   435    435     db = p->db;
   436    436     assert( !db->mallocFailed );
   437    437   
   438         -  if( p->aborted ){
   439         -    return SQLITE_ABORT;
   440         -  }
   441    438     if( p->pc<=0 && p->expired ){
   442    439       if( p->rc==SQLITE_OK ){
   443    440         p->rc = SQLITE_SCHEMA;
   444    441       }
   445    442       rc = SQLITE_ERROR;
   446    443       goto end_of_step;
   447    444     }

Changes to src/vdbeaux.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used for creating, destroying, and populating
    13     13   ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
    14     14   ** to version 2.8.7, all this code was combined into the vdbe.c source file.
    15     15   ** But that file was getting too big so this subroutines were split out.
    16     16   **
    17         -** $Id: vdbeaux.c,v 1.404 2008/08/01 20:10:08 drh Exp $
           17  +** $Id: vdbeaux.c,v 1.405 2008/08/02 03:50:39 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include <ctype.h>
    21     21   #include "vdbeInt.h"
    22     22   
    23     23   
    24     24   
................................................................................
  1756   1756           sqlite3VdbePrintOp(out, i, &p->aOp[i]);
  1757   1757         }
  1758   1758         fclose(out);
  1759   1759       }
  1760   1760     }
  1761   1761   #endif
  1762   1762     p->magic = VDBE_MAGIC_INIT;
  1763         -  p->aborted = 0;
  1764   1763     return p->rc & db->errMask;
  1765   1764   }
  1766   1765    
  1767   1766   /*
  1768   1767   ** Clean up and delete a VDBE after execution.  Return an integer which is
  1769   1768   ** the result code.  Write any error message text into *pzErrMsg.
  1770   1769   */

Changes to src/vtab.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to help implement virtual tables.
    13     13   **
    14         -** $Id: vtab.c,v 1.73 2008/08/01 17:37:41 danielk1977 Exp $
           14  +** $Id: vtab.c,v 1.74 2008/08/02 03:50:39 drh Exp $
    15     15   */
    16     16   #ifndef SQLITE_OMIT_VIRTUALTABLE
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   static int createModule(
    20     20     sqlite3 *db,                    /* Database in which module is registered */
    21     21     const char *zName,              /* Name assigned to this module */
................................................................................
   786    786     zLowerName = sqlite3DbStrDup(db, pDef->zName);
   787    787     if( zLowerName ){
   788    788       for(z=(unsigned char*)zLowerName; *z; z++){
   789    789         *z = sqlite3UpperToLower[*z];
   790    790       }
   791    791       rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
   792    792       sqlite3DbFree(db, zLowerName);
   793         -    sqlite3VtabTransferError(db, rc, pVtab);
          793  +    if( pVtab->zErrMsg ){
          794  +      sqlite3Error(db, rc, "%s", pVtab->zErrMsg);
          795  +      sqlite3DbFree(db, pVtab->zErrMsg);
          796  +      pVtab->zErrMsg = 0;
          797  +    }
   794    798     }
   795    799     if( rc==0 ){
   796    800       return pDef;
   797    801     }
   798    802   
   799    803     /* Create a new ephemeral function definition for the overloaded
   800    804     ** function */
................................................................................
   827    831     if( pParse->apVtabLock ){
   828    832       pParse->apVtabLock[pParse->nVtabLock++] = pTab;
   829    833     }else{
   830    834       pParse->db->mallocFailed = 1;
   831    835     }
   832    836   }
   833    837   
   834         -/*
   835         -** Transfer a virtual table error into the database connection.
   836         -*/
   837         -void sqlite3VtabTransferError(sqlite3 *db, int rc, sqlite3_vtab *pVtab){
   838         -  if( pVtab->zErrMsg ){
   839         -    sqlite3Error(db, rc, "%s", pVtab->zErrMsg);
   840         -    sqlite3DbFree(db, pVtab->zErrMsg);
   841         -    pVtab->zErrMsg = 0;
   842         -  }
   843         -}
   844         -
   845    838   #endif /* SQLITE_OMIT_VIRTUALTABLE */

Changes to test/autovacuum.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing the SELECT statement.
    13     13   #
    14         -# $Id: autovacuum.test,v 1.26 2007/04/07 15:03:17 danielk1977 Exp $
           14  +# $Id: autovacuum.test,v 1.27 2008/08/02 03:50:39 drh Exp $
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19     19   # If this build of the library does not support auto-vacuum, omit this
    20     20   # whole file.
    21     21   ifcapable {!autovacuum || !pragma} {
................................................................................
   638    638       BEGIN;
   639    639       DELETE FROM t4;
   640    640       COMMIT;
   641    641       SELECT count(*) FROM t1;
   642    642     }
   643    643     expr {[file size test.db] / 1024}
   644    644   } {286}
          645  +
          646  +#------------------------------------------------------------------------
          647  +# Additional tests.
          648  +#
          649  +# Try to determine the autovacuum setting for a database that is locked.
          650  +#
          651  +do_test autovacuum-8.1 {
          652  +  db close
          653  +  sqlite3 db test.db
          654  +  sqlite3 db2 test.db
          655  +  db eval {PRAGMA auto_vacuum}
          656  +} {1}
          657  +do_test autovacuum-8.2 {
          658  +  db eval {BEGIN EXCLUSIVE}
          659  +  catchsql {PRAGMA auto_vacuum} db2
          660  +} {1 {database is locked}}
          661  +catch {db2 close}
          662  +catch {db eval {COMMIT}}
          663  +    
   645    664   
   646    665   finish_test

Changes to test/limit.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing the LIMIT ... OFFSET ... clause
    13     13   #  of SELECT statements.
    14     14   #
    15         -# $Id: limit.test,v 1.31 2008/01/16 18:20:42 danielk1977 Exp $
           15  +# $Id: limit.test,v 1.32 2008/08/02 03:50:39 drh Exp $
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Build some test data
    21     21   #
    22     22   execsql {
................................................................................
   440    440   ifcapable subquery {
   441    441   do_test limit-11.1 {
   442    442     db eval {
   443    443        SELECT x FROM (SELECT x FROM t1 ORDER BY x LIMIT 0) ORDER BY x
   444    444     }
   445    445   } {}
   446    446   } ;# ifcapable subquery
          447  +
          448  +# Test error processing.
          449  +#
          450  +do_test limit-12.1 {
          451  +  catchsql {
          452  +     SELECT * FROM t1 LIMIT replace(1)
          453  +  }
          454  +} {1 {wrong number of arguments to function replace()}}
          455  +do_test limit-12.2 {
          456  +  catchsql {
          457  +     SELECT * FROM t1 LIMIT 5 OFFSET replace(1)
          458  +  }
          459  +} {1 {wrong number of arguments to function replace()}}
          460  +do_test limit-12.3 {
          461  +  catchsql {
          462  +     SELECT * FROM t1 LIMIT x
          463  +  }
          464  +} {1 {no such column: x}}
          465  +do_test limit-12.4 {
          466  +  catchsql {
          467  +     SELECT * FROM t1 LIMIT 1 OFFSET x
          468  +  }
          469  +} {1 {no such column: x}}
          470  +
   447    471   
   448    472   finish_test

Changes to test/loadext.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is extension loading.
    13     13   #
    14         -# $Id: loadext.test,v 1.13 2008/06/30 15:09:29 danielk1977 Exp $
           14  +# $Id: loadext.test,v 1.14 2008/08/02 03:50:39 drh Exp $
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19     19   ifcapable !load_ext {
    20     20     finish_test
    21     21     return
................................................................................
   249    249   do_test loadext-4.3 {
   250    250     sqlite3_enable_load_extension db 0
   251    251     catchsql {
   252    252       SELECT load_extension($::testextension,'testloadext_init')
   253    253     }
   254    254   } {1 {not authorized}}
   255    255   
          256  +source $testdir/malloc_common.tcl
          257  +
   256    258   
          259  +# Malloc failure in sqlite3_auto_extension and sqlite3_load_extension
          260  +#
          261  +do_malloc_test loadext-5 -tclprep {
          262  +  sqlite3_reset_auto_extension
          263  +} -tclbody {
          264  +  if {[autoinstall_test_functions]==7} {error "out of memory"}
          265  +}
          266  +do_malloc_test loadext-6 -tclbody {
          267  +  db enable_load_extension 1
          268  +  sqlite3_load_extension db $::testextension testloadext_init
          269  +}
          270  +autoinstall_test_functions
   257    271   
   258    272   finish_test

Added test/mallocI.test.

            1  +# 2008 August 01
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This test script checks malloc failures in various obscure operations.
           13  +# 
           14  +# $Id: mallocI.test,v 1.1 2008/08/02 03:50:39 drh Exp $
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +source $testdir/malloc_common.tcl
           19  +
           20  +# Malloc failures in a view.
           21  +#
           22  +do_malloc_test mallocI-1 -sqlprep {
           23  +  CREATE TABLE t1(a,b,c,d);
           24  +  CREATE VIEW v1 AS SELECT a*b, c*d FROM t1 ORDER BY b-d;
           25  +} -sqlbody {
           26  +  SELECT * FROM v1
           27  +}
           28  +
           29  +# Malloc failure while trying to service a pragma on a TEMP database.
           30  +#
           31  +do_malloc_test mallocI-2 -sqlbody {
           32  +  PRAGMA temp.page_size
           33  +}
           34  +
           35  +# Malloc failure while creating a table from a SELECT statement.
           36  +#
           37  +do_malloc_test mallocI-3 -sqlprep {
           38  +  CREATE TABLE t1(a,b,c);
           39  +} -sqlbody {
           40  +  CREATE TABLE t2 AS SELECT b,c FROM t1;
           41  +}
           42  +
           43  +finish_test

Changes to test/misc7.test.

     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   #
    13         -# $Id: misc7.test,v 1.22 2008/08/01 15:06:30 drh Exp $
           13  +# $Id: misc7.test,v 1.23 2008/08/02 03:50:40 drh Exp $
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   
    18     18   do_test misc7-1-misuse {
    19     19     c_misuse_test
    20     20   } {}
................................................................................
   239    239   
   240    240   db close
   241    241   file delete -force test.db
   242    242   file delete -force test.db-journal
   243    243   sqlite3 db test.db
   244    244   
   245    245   ifcapable explain {
   246         -  do_test misc7-14 {
          246  +  do_test misc7-14.1 {
   247    247       execsql {
   248    248         CREATE TABLE abc(a PRIMARY KEY, b, c);
   249    249       }
   250    250       execsql {
   251    251         EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 WHERE rowid = 1;
   252    252       }
   253    253     } {0 0 {TABLE abc AS t2 USING PRIMARY KEY}}
   254         -  do_test misc7-15 {
          254  +  do_test misc7-14.2 {
   255    255       execsql {
   256    256         EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 WHERE a = 1;
   257    257       }
   258    258     } {0 0 {TABLE abc AS t2 WITH INDEX sqlite_autoindex_abc_1}}
          259  +  do_test misc7-14.3 {
          260  +    execsql {
          261  +      EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 ORDER BY a;
          262  +    }
          263  +  } {0 0 {TABLE abc AS t2 WITH INDEX sqlite_autoindex_abc_1 ORDER BY}}
   259    264   }
   260    265   
   261    266   db close
   262    267   file delete -force test.db
   263    268   file delete -force test.db-journal
   264    269   sqlite3 db test.db
   265    270   

Changes to test/select5.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing aggregate functions and the
    13     13   # GROUP BY and HAVING clauses of SELECT statements.
    14     14   #
    15         -# $Id: select5.test,v 1.17 2008/01/16 18:20:42 danielk1977 Exp $
           15  +# $Id: select5.test,v 1.18 2008/08/02 03:50:40 drh Exp $
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Build some test data
    21     21   #
    22     22   execsql {
................................................................................
   118    118     execsql {
   119    119       SELECT sum(x) FROM t1 WHERE x>100
   120    120     }
   121    121   } {{}}
   122    122   
   123    123   # Some tests for queries with a GROUP BY clause but no aggregate functions.
   124    124   #
   125         -# Note: The query in test case 5-5.5 are not legal SQL. So if the 
          125  +# Note: The query in test cases 5.1 through 5.5 are not legal SQL. So if the 
   126    126   # implementation changes in the future and it returns different results,
   127    127   # this is not such a big deal.
   128    128   #
   129    129   do_test select5-5.1 {
   130    130     execsql {
   131    131       CREATE TABLE t2(a, b, c);
   132    132       INSERT INTO t2 VALUES(1, 2, 3);
................................................................................
   151    151     } 
   152    152   } {1 2 1 4 6 4}
   153    153   do_test select5-5.5 {
   154    154     execsql {
   155    155       SELECT a, b FROM t2 GROUP BY a;
   156    156     } 
   157    157   } {1 4 6 4}
          158  +
          159  +# Test rendering of columns for the GROUP BY clause.
          160  +#
          161  +do_test select5-5.11 {
          162  +breakpoint
          163  +  execsql {
          164  +    SELECT max(c), b*a, b, a FROM t2 GROUP BY b*a, b, a
          165  +  }
          166  +} {3 2 2 1 5 4 4 1 7 24 4 6}
   158    167   
   159    168   # NULL compare equal to each other for the purposes of processing
   160    169   # the GROUP BY clause.
   161    170   #
   162    171   do_test select5-6.1 {
   163    172     execsql {
   164    173       CREATE TABLE t3(x,y);

Changes to test/vacuum3.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is changing the database page size using a 
    13     13   # VACUUM statement.
    14     14   #
    15         -# $Id: vacuum3.test,v 1.6 2008/07/12 14:52:21 drh Exp $
           15  +# $Id: vacuum3.test,v 1.7 2008/08/02 03:50:40 drh Exp $
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # If the VACUUM statement is disabled in the current build, skip all
    21     21   # the tests in this file.
    22     22   #
................................................................................
   298    298       CREATE TABLE t2 AS SELECT * FROM t1;
   299    299       CREATE TABLE t3 AS SELECT * FROM t1;
   300    300       COMMIT;
   301    301       DROP TABLE t2;
   302    302     } -sqlbody {
   303    303       PRAGMA page_size = 512;
   304    304       VACUUM;
          305  +  } 
          306  +  do_malloc_test vacuum3-malloc-2 -sqlprep { 
          307  +    PRAGMA encoding=UTF16;
          308  +    CREATE TABLE t1(a, b, c);
          309  +    INSERT INTO t1 VALUES(1, 2, 3);
          310  +    CREATE TABLE t2(x,y,z);
          311  +    INSERT INTO t2 SELECT * FROM t1;
          312  +  } -sqlbody {
          313  +    VACUUM;
   305    314     } 
   306    315   }
   307    316   
   308    317   finish_test