/ Check-in [152e9940]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Coverage tests for vacuum.c (CVS 1776)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 152e9940b919a53fcd0da4091dbf75ab8ef15b38
User & Date: danielk1977 2004-06-30 09:49:23
Context
2004-06-30
10:54
Make sure vacuum.test closes all files. (CVS 1777) check-in: 4077f9a3 user: danielk1977 tags: trunk
09:49
Coverage tests for vacuum.c (CVS 1776) check-in: 152e9940 user: danielk1977 tags: trunk
08:20
Fixes for compiler warnings. Also more coverage. (CVS 1775) check-in: fa19c77b user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/attach.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 implement the ATTACH and DETACH commands.
    13     13   **
    14         -** $Id: attach.c,v 1.20 2004/06/29 08:59:35 danielk1977 Exp $
           14  +** $Id: attach.c,v 1.21 2004/06/30 09:49:23 danielk1977 Exp $
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   
    18     18   /*
    19     19   ** This routine is called by the parser to process an ATTACH statement:
    20     20   **
    21     21   **     ATTACH DATABASE filename AS dbname
................................................................................
    27     27     Db *aNew;
    28     28     int rc, i;
    29     29     char *zFile, *zName;
    30     30     sqlite *db;
    31     31     Vdbe *v;
    32     32   
    33     33     v = sqlite3GetVdbe(pParse);
           34  +  if( !v ) return;
    34     35     sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
    35     36     if( pParse->explain ) return;
    36     37     db = pParse->db;
    37     38     if( db->nDb>=MAX_ATTACHED+2 ){
    38     39       sqlite3ErrorMsg(pParse, "too many attached databases - max %d", 
    39     40          MAX_ATTACHED);
    40     41       pParse->rc = SQLITE_ERROR;
................................................................................
   136    137   void sqlite3Detach(Parse *pParse, Token *pDbname){
   137    138     int i;
   138    139     sqlite *db;
   139    140     Vdbe *v;
   140    141     Db *pDb = 0;
   141    142   
   142    143     v = sqlite3GetVdbe(pParse);
          144  +  if( !v ) return;
   143    145     sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
   144    146     if( pParse->explain ) return;
   145    147     db = pParse->db;
   146    148     for(i=0; i<db->nDb; i++){
   147    149       pDb = &db->aDb[i];
   148    150       if( pDb->pBt==0 || pDb->zName==0 ) continue;
   149    151       if( strlen(pDb->zName)!=pDbname->n ) continue;

Changes to src/main.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: main.c,v 1.242 2004/06/29 13:18:24 danielk1977 Exp $
           17  +** $Id: main.c,v 1.243 2004/06/30 09:49:24 danielk1977 Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** A pointer to this structure is used to communicate information
................................................................................
   958    958     int nBytes,               /* Length of zSql in bytes. */
   959    959     sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
   960    960     const char** pzTail       /* OUT: End of parsed string */
   961    961   ){
   962    962     Parse sParse;
   963    963     char *zErrMsg = 0;
   964    964     int rc = SQLITE_OK;
          965  +
          966  +  if( sqlite3_malloc_failed ){
          967  +    return SQLITE_NOMEM;
          968  +  }
   965    969   
   966    970     assert( ppStmt );
   967    971     *ppStmt = 0;
   968    972     if( sqlite3SafetyOn(db) ){
   969    973       return SQLITE_MISUSE;
   970    974     }
   971    975   

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.147 2004/06/28 04:52:30 danielk1977 Exp $
           21  +** @(#) $Id: pager.c,v 1.148 2004/06/30 09:49:24 danielk1977 Exp $
    22     22   */
    23     23   #include "os.h"         /* Must be first to enable large file support */
    24     24   #include "sqliteInt.h"
    25     25   #include "pager.h"
    26     26   #include <assert.h>
    27     27   #include <string.h>
    28     28   
................................................................................
  2313   2313     pPager->setMaster = 0;
  2314   2314     pPager->journalHdr = 0;
  2315   2315     if( rc!=SQLITE_OK ){
  2316   2316       sqliteFree(pPager->aInJournal);
  2317   2317       pPager->aInJournal = 0;
  2318   2318       sqlite3OsUnlock(&pPager->fd, SHARED_LOCK);
  2319   2319       pPager->state = PAGER_SHARED;
  2320         -    return SQLITE_CANTOPEN;
         2320  +    return rc;
  2321   2321     }
  2322   2322     sqlite3OsOpenDirectory(pPager->zDirectory, &pPager->jfd);
  2323   2323     pPager->journalOpen = 1;
  2324   2324     pPager->journalStarted = 0;
  2325   2325     pPager->needSync = 0;
  2326   2326     pPager->alwaysRollback = 0;
  2327   2327     pPager->nRec = 0;

Changes to src/parse.y.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains SQLite's grammar for SQL.  Process this file
    13     13   ** using the lemon parser generator to generate C code that runs
    14     14   ** the parser.  Lemon will also generate a header file containing
    15     15   ** numeric codes for all of the tokens.
    16     16   **
    17         -** @(#) $Id: parse.y,v 1.128 2004/06/26 06:37:07 danielk1977 Exp $
           17  +** @(#) $Id: parse.y,v 1.129 2004/06/30 09:49:24 danielk1977 Exp $
    18     18   */
    19     19   %token_prefix TK_
    20     20   %token_type {Token}
    21     21   %default_type {Token}
    22     22   %extra_argument {Parse *pParse}
    23     23   %syntax_error {
    24     24     if( pParse->zErrMsg==0 ){
................................................................................
   438    438   orderby_opt(A) ::= ORDER BY sortlist(X).      {A = X;}
   439    439   sortlist(A) ::= sortlist(X) COMMA sortitem(Y) collate(C) sortorder(Z). {
   440    440     A = sqlite3ExprListAppend(X,Y,C.n>0?&C:0);
   441    441     if( A ) A->a[A->nExpr-1].sortOrder = Z;
   442    442   }
   443    443   sortlist(A) ::= sortitem(Y) collate(C) sortorder(Z). {
   444    444     A = sqlite3ExprListAppend(0,Y,C.n>0?&C:0);
   445         -  if( A ) A->a[0].sortOrder = Z;
          445  +  if( A && A->a ) A->a[0].sortOrder = Z;
   446    446   }
   447    447   sortitem(A) ::= expr(X).   {A = X;}
   448    448   
   449    449   %type sortorder {int}
   450    450   %type collate {Token}
   451    451   
   452    452   sortorder(A) ::= ASC.           {A = SQLITE_SO_ASC;}

Changes to src/pragma.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 implement the PRAGMA command.
    13     13   **
    14         -** $Id: pragma.c,v 1.56 2004/06/29 08:59:35 danielk1977 Exp $
           14  +** $Id: pragma.c,v 1.57 2004/06/30 09:49:24 danielk1977 Exp $
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   #include <ctype.h>
    18     18   
    19     19   #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
    20     20   # include "pager.h"
    21     21   # include "btree.h"
................................................................................
   144    144   
   145    145     /* Interpret the [database.] part of the pragma statement. iDb is the
   146    146     ** index of the database this pragma is being applied to in db.aDb[]. */
   147    147     iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
   148    148     if( iDb<0 ) return;
   149    149   
   150    150     zLeft = sqlite3NameFromToken(pId);
          151  +  if( !zLeft ) return;
   151    152     if( minusFlag ){
   152    153       zRight = 0;
   153    154       sqlite3SetNString(&zRight, "-", 1, pValue->z, pValue->n, 0);
   154    155     }else{
   155    156       zRight = sqlite3NameFromToken(pValue);
   156    157     }
   157    158   

Changes to src/vacuum.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to implement the VACUUM command.
    13     13   **
    14     14   ** Most of the code in this file may be omitted by defining the
    15     15   ** SQLITE_OMIT_VACUUM macro.
    16     16   **
    17         -** $Id: vacuum.c,v 1.25 2004/06/30 06:30:26 danielk1977 Exp $
           17  +** $Id: vacuum.c,v 1.26 2004/06/30 09:49:24 danielk1977 Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   
    22     22   #if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
    23     23   /*
    24     24   ** Generate a random name of 20 character in length.
................................................................................
    78     78   ** In version 1.0.x of SQLite, the VACUUM command would call
    79     79   ** gdbm_reorganize() on all the database tables.  But beginning
    80     80   ** with 2.0.0, SQLite no longer uses GDBM so this command has
    81     81   ** become a no-op.
    82     82   */
    83     83   void sqlite3Vacuum(Parse *pParse, Token *pTableName){
    84     84     Vdbe *v = sqlite3GetVdbe(pParse);
    85         -  sqlite3VdbeAddOp(v, OP_Vacuum, 0, 0);
           85  +  if( v ){
           86  +    sqlite3VdbeAddOp(v, OP_Vacuum, 0, 0);
           87  +  }
    86     88     return;
    87     89   }
    88     90   
    89     91   /*
    90     92   ** This routine implements the OP_Vacuum opcode of the VDBE.
    91     93   */
    92     94   int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
................................................................................
   106    108       goto end_of_vacuum;
   107    109     }
   108    110   
   109    111     /* Get the full pathname of the database file and create a
   110    112     ** temporary filename in the same directory as the original file.
   111    113     */
   112    114     zFilename = sqlite3BtreeGetFilename(db->aDb[0].pBt);
   113         -  if( zFilename==0 ){
   114         -    /* The in-memory database. Do nothing. */
   115         -    goto end_of_vacuum;
          115  +  assert( zFilename );
          116  +  if( zFilename[0]=='\0' ){
          117  +    /* The in-memory database. Do nothing. Return directly to avoid causing
          118  +    ** an error trying to DETACH the vacuum_db (which never got attached)
          119  +    ** in the exit-handler.
          120  +    */
          121  +    return SQLITE_OK;
   116    122     }
   117    123     nFilename = strlen(zFilename);
   118    124     zTemp = sqliteMalloc( nFilename+100 );
   119    125     if( zTemp==0 ){
   120    126       rc = SQLITE_NOMEM;
   121    127       goto end_of_vacuum;
   122    128     }
   123    129     strcpy(zTemp, zFilename);
   124         -  for(i=0; i<10; i++){
          130  +  i = 0;
          131  +  do {
   125    132       zTemp[nFilename] = '-';
   126    133       randomName((unsigned char*)&zTemp[nFilename+1]);
   127         -    if( !sqlite3OsFileExists(zTemp) ) break;
   128         -  }
          134  +  } while( i<10 && sqlite3OsFileExists(zTemp) );
   129    135   
   130    136     /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
   131    137     ** can be set to 'off' for this file, as it is not recovered if a crash
   132    138     ** occurs anyway. The integrity of the database is maintained by a
   133    139     ** (possibly synchronous) transaction opened on the main database before
   134    140     ** sqlite3BtreeCopyFile() is called.
   135    141     **
   136    142     ** An optimisation would be to use a non-journaled pager.
   137    143     */
   138    144     zSql = sqlite3MPrintf("ATTACH '%s' AS vacuum_db;", zTemp);
   139         -  execSql(db, "PRAGMA vacuum_db.synchronous = off;");
   140    145     if( !zSql ){
   141    146       rc = SQLITE_NOMEM;
   142    147       goto end_of_vacuum;
   143    148     }
   144    149     rc = execSql(db, zSql);
   145    150     sqliteFree(zSql);
   146    151     zSql = 0;
   147    152     if( rc!=SQLITE_OK ) goto end_of_vacuum;
          153  +  execSql(db, "PRAGMA vacuum_db.synchronous = off;");
   148    154   
   149    155     /* Begin a transaction */
   150    156     rc = execSql(db, "BEGIN;");
   151    157     if( rc!=SQLITE_OK ) goto end_of_vacuum;
   152    158   
   153    159     /* Query the schema of the main database. Create a mirror schema
   154    160     ** in the temporary database.
................................................................................
   227    233     ** database. No locks are held on any other files (since the main file
   228    234     ** was committed at the btree level). So it safe to end the transaction
   229    235     ** by manually setting the autoCommit flag to true and detaching the
   230    236     ** vacuum database. The vacuum_db journal file is deleted when the pager
   231    237     ** is closed by the DETACH.
   232    238     */
   233    239     db->autoCommit = 1;
   234         -  execSql(db, "DETACH vacuum_db;");
          240  +  if( rc==SQLITE_OK ){
          241  +    rc = execSql(db, "DETACH vacuum_db;");
          242  +  }else{
          243  +    execSql(db, "DETACH vacuum_db;");
          244  +  }
   235    245     if( zTemp ){
   236    246       sqlite3OsDelete(zTemp);
   237    247       sqliteFree(zTemp);
   238    248     }
   239    249     if( zSql ) sqliteFree( zSql );
   240    250   #endif
   241    251     return rc;
   242    252   } 

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.397 2004/06/30 06:30:26 danielk1977 Exp $
           46  +** $Id: vdbe.c,v 1.398 2004/06/30 09:49:24 danielk1977 Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
  1244   1244       assert( pOp[-1].p3type==P3_COLLSEQ );
  1245   1245       assert( pOp[-1].opcode==OP_CollSeq );
  1246   1246       ctx.pColl = (CollSeq *)pOp[-1].p3;
  1247   1247     }
  1248   1248     if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  1249   1249     (*ctx.pFunc->xFunc)(&ctx, n, apVal);
  1250   1250     if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
         1251  +  if( sqlite3_malloc_failed ) goto no_mem;
  1251   1252     popStack(&pTos, n);
  1252   1253   
  1253   1254     /* If any auxilary data functions have been called by this user function,
  1254   1255     ** immediately call the destructor for any non-static values.
  1255   1256     */
  1256   1257     if( ctx.pVdbeFunc ){
  1257   1258       sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p2);

Changes to test/malloc.test.

    10     10   #***********************************************************************
    11     11   # This file attempts to check the library in an out-of-memory situation.
    12     12   # When compiled with -DMEMORY_DEBUG=1, the SQLite library accepts a special
    13     13   # command (sqlite_malloc_fail N) which causes the N-th malloc to fail.  This
    14     14   # special feature is used to see what happens in the library if a malloc
    15     15   # were to really fail due to an out-of-memory situation.
    16     16   #
    17         -# $Id: malloc.test,v 1.9 2004/06/26 13:51:34 danielk1977 Exp $
           17  +# $Id: malloc.test,v 1.10 2004/06/30 09:49:24 danielk1977 Exp $
    18     18   
    19     19   set testdir [file dirname $argv0]
    20     20   source $testdir/tester.tcl
    21     21   
    22     22   # Only run these tests if memory debugging is turned on.
    23     23   #
    24     24   if {[info command sqlite_malloc_stat]==""} {
................................................................................
   255    255          lappend v $v2
   256    256        }
   257    257     } {1 1}
   258    258   }
   259    259   
   260    260   # Ensure that no file descriptors were leaked.
   261    261   do_test malloc-5.X {
          262  +  catch {db close}
          263  +  set sqlite_open_file_count
          264  +} {0}
          265  +
          266  +for {set go 1; set i 1} {$go} {incr i} {
          267  +  do_test malloc-6.$i {
          268  +     sqlite_malloc_fail 0
          269  +     catch {db close}
          270  +     catch {file delete -force test.db}
          271  +     catch {file delete -force test.db-journal}
          272  +     sqlite3 db test.db
          273  +     execsql {
          274  +         BEGIN TRANSACTION;
          275  +         CREATE TABLE t1(a);
          276  +         INSERT INTO t1 VALUES(1);
          277  +         INSERT INTO t1 SELECT a*2 FROM t1;
          278  +         INSERT INTO t1 SELECT a*2 FROM t1;
          279  +         INSERT INTO t1 SELECT a*2 FROM t1;
          280  +         INSERT INTO t1 SELECT a*2 FROM t1;
          281  +         INSERT INTO t1 SELECT a*2 FROM t1;
          282  +         INSERT INTO t1 SELECT a*2 FROM t1;
          283  +         INSERT INTO t1 SELECT a*2 FROM t1;
          284  +         INSERT INTO t1 SELECT a*2 FROM t1;
          285  +         INSERT INTO t1 SELECT a*2 FROM t1;
          286  +         INSERT INTO t1 SELECT a*2 FROM t1;
          287  +         DELETE FROM t1 where rowid%5 = 0;
          288  +         COMMIT;
          289  +     }
          290  +     sqlite_malloc_fail $i
          291  +     set v [catch {execsql {
          292  +       VACUUM;
          293  +     }} msg]
          294  +     set leftover [lindex [sqlite_malloc_stat] 2]
          295  +     if {$leftover>0} {
          296  +       if {$leftover>1} {puts "\nLeftover: $leftover\nReturn=$v  Message=$msg"}
          297  +       set ::go 0
          298  +       set v {1 1}
          299  +     } else {
          300  +       set v2 [expr {$msg=="" || $msg=="out of memory"}]
          301  +       if {!$v2} {puts "\nError message returned: $msg"}
          302  +       lappend v $v2
          303  +     }
          304  +  } {1 1}
          305  +}
          306  +
          307  +# Ensure that no file descriptors were leaked.
          308  +do_test malloc-6.X {
   262    309     catch {db close}
   263    310     set sqlite_open_file_count
   264    311   } {0}
   265    312   
   266    313   sqlite_malloc_fail 0
   267    314   finish_test

Changes to test/vacuum.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 VACUUM statement.
    13     13   #
    14         -# $Id: vacuum.test,v 1.21 2004/06/19 00:16:32 drh Exp $
           14  +# $Id: vacuum.test,v 1.22 2004/06/30 09:49:24 danielk1977 Exp $
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19     19   proc cksum {{db db}} {
    20     20     set sql "SELECT name, type, sql FROM sqlite_master ORDER BY name, type"
    21     21     set txt [$db eval $sql]\n
................................................................................
   195    195     }
   196    196   } {}
   197    197   do_test vacuum-6.4 {
   198    198     execsql {
   199    199       select count(*) from "abc abc" WHERE a = X'00112233';
   200    200     }
   201    201   } {1}
          202  +
          203  +# Check what happens when an in-memory database is vacuumed.
          204  +do_test vacuum-7.0 {
          205  +  sqlite3 db2 :memory:
          206  +  execsql {
          207  +    CREATE TABLE t1(t);
          208  +    VACUUM;
          209  +  } db2
          210  +} {}
   202    211   
   203    212   # finish_test