/ Check-in [bb0e7e38]
Login

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

Overview
Comment:Fix an assertion fault that can occur while autovacuuming a corrupt database file. Add the SQLITE_OMIT_COMPLETE compile-time parameter. (CVS 2361)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:bb0e7e3857a06347b08d93553ac603e737322262
User & Date: drh 2005-02-26 17:31:27
Context
2005-02-26
18:10
Add the SQLITE_OMIT_FLAG_PRAGMAS compile-time option. (CVS 2362) check-in: c167e905 user: drh tags: trunk
17:31
Fix an assertion fault that can occur while autovacuuming a corrupt database file. Add the SQLITE_OMIT_COMPLETE compile-time parameter. (CVS 2361) check-in: bb0e7e38 user: drh tags: trunk
2005-02-24
04:51
Revised man page from Bill Bumgarner. (CVS 2360) check-in: 5c99bea5 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1839
1840
1841
1842
1843
1844
1845
1846



1847
1848
1849
1850
1851
1852
1853
....
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698


4699
4700
4701
4702
4703
4704
4705
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.248 2005/02/15 16:23:02 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
    /* If iDbPage is a pointer map page, or the pending-byte page, skip it. */
    if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
      continue;
    }

    rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
    assert( eType!=PTRMAP_ROOTPAGE );




    /* If iDbPage is free, do not swap it.  */
    if( eType==PTRMAP_FREEPAGE ){
      continue;
    }
    rc = getPage(pBt, iDbPage, &pDbMemPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
................................................................................

      releasePage(pPageMove);
      rc = getPage(pBt, pgnoRoot, &pRoot);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
      assert( eType!=PTRMAP_ROOTPAGE );
      assert( eType!=PTRMAP_FREEPAGE );
      if( rc!=SQLITE_OK ){
        releasePage(pRoot);
        return rc;
      }


      rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove);
      releasePage(pRoot);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = getPage(pBt, pgnoRoot, &pRoot);
      if( rc!=SQLITE_OK ){







|







 







|
>
>
>







 







<
<
|



>
>







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
....
4689
4690
4691
4692
4693
4694
4695


4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.249 2005/02/26 17:31:27 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
    /* If iDbPage is a pointer map page, or the pending-byte page, skip it. */
    if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
      continue;
    }

    rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
    if( eType==PTRMAP_ROOTPAGE ){
      rc = SQLITE_CORRUPT;
      goto autovacuum_out;
    }

    /* If iDbPage is free, do not swap it.  */
    if( eType==PTRMAP_FREEPAGE ){
      continue;
    }
    rc = getPage(pBt, iDbPage, &pDbMemPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
................................................................................

      releasePage(pPageMove);
      rc = getPage(pBt, pgnoRoot, &pRoot);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);


      if( rc!=SQLITE_OK || eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
        releasePage(pRoot);
        return rc;
      }
      assert( eType!=PTRMAP_ROOTPAGE );
      assert( eType!=PTRMAP_FREEPAGE );
      rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove);
      releasePage(pRoot);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = getPage(pBt, pgnoRoot, &pRoot);
      if( rc!=SQLITE_OK ){

Changes to src/tclsqlite.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
725
726
727
728
729
730
731

732
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.118 2005/01/25 04:27:55 danielk1977 Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
................................................................................
  /*    $db complete SQL
  **
  ** Return TRUE if SQL is a complete SQL statement.  Return FALSE if
  ** additional lines of input are needed.  This is similar to the
  ** built-in "info complete" command of Tcl.
  */
  case DB_COMPLETE: {

    Tcl_Obj *pResult;
    int isComplete;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "SQL");
      return TCL_ERROR;
    }
    isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetBooleanObj(pResult, isComplete);

    break;
  }

  /*
  **    $db errorcode
  **
  ** Return the numeric error code that was returned by the most recent







|







 







>









>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.119 2005/02/26 17:31:27 drh Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
................................................................................
  /*    $db complete SQL
  **
  ** Return TRUE if SQL is a complete SQL statement.  Return FALSE if
  ** additional lines of input are needed.  This is similar to the
  ** built-in "info complete" command of Tcl.
  */
  case DB_COMPLETE: {
#ifndef SQLITE_OMIT_COMPLETE
    Tcl_Obj *pResult;
    int isComplete;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "SQL");
      return TCL_ERROR;
    }
    isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetBooleanObj(pResult, isComplete);
#endif
    break;
  }

  /*
  **    $db errorcode
  **
  ** Return the numeric error code that was returned by the most recent

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
....
2718
2719
2720
2721
2722
2723
2724






2725
2726
2727
2728
2729
2730
2731
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.130 2005/02/17 00:03:07 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
*/
static int test_complete16(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
#ifndef SQLITE_OMIT_UTF16
  char *zBuf;

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>");
    return TCL_ERROR;
  }

  zBuf = Tcl_GetByteArrayFromObj(objv[1], 0);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf)));
#endif /* SQLITE_OMIT_UTF16 */
  return TCL_OK;
}

/*
** Usage: sqlite3_step STMT
**
** Advance the statement to the next row.
................................................................................
#endif

#ifdef SQLITE_OMIT_BLOB_LITERAL
  Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY);
#endif







#ifdef SQLITE_OMIT_COMPOUND_SELECT
  Tcl_SetVar2(interp, "sqlite_options", "compound", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "compound", "1", TCL_GLOBAL_ONLY);
#endif








|







 







|









|







 







>
>
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
....
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.131 2005/02/26 17:31:27 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
*/
static int test_complete16(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
#if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16)
  char *zBuf;

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>");
    return TCL_ERROR;
  }

  zBuf = Tcl_GetByteArrayFromObj(objv[1], 0);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf)));
#endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */
  return TCL_OK;
}

/*
** Usage: sqlite3_step STMT
**
** Advance the statement to the next row.
................................................................................
#endif

#ifdef SQLITE_OMIT_BLOB_LITERAL
  Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_COMPLETE
  Tcl_SetVar2(interp, "sqlite_options", "complete", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "complete", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_COMPOUND_SELECT
  Tcl_SetVar2(interp, "sqlite_options", "compound", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "compound", "1", TCL_GLOBAL_ONLY);
#endif

Changes to src/tokenize.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
427
428
429
430
431
432
433





434
435
436
437
438
439
440
...
658
659
660
661
662
663
664

*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.100 2005/01/31 12:42:29 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
  sqliteFree(pParse->apVarExpr);
  if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
    pParse->rc = SQLITE_ERROR;
  }
  return nErr;
}






/*
** Token types used by the sqlite3_complete() routine.  See the header
** comments on that procedure for additional information.
*/
#define tkSEMI    0
#define tkWS      1
#define tkOTHER   2
................................................................................
  if( zSql8 ){
    rc = sqlite3_complete(zSql8);
  }
  sqlite3ValueFree(pVal);
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */








|







 







>
>
>
>
>







 







>
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
...
663
664
665
666
667
668
669
670
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.101 2005/02/26 17:31:27 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
  sqliteFree(pParse->apVarExpr);
  if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
    pParse->rc = SQLITE_ERROR;
  }
  return nErr;
}

/* The sqlite3_complete() API may be omitted (to save code space) by
** defining the following symbol.
*/
#ifndef SQLITE_OMIT_COMPLETE

/*
** Token types used by the sqlite3_complete() routine.  See the header
** comments on that procedure for additional information.
*/
#define tkSEMI    0
#define tkWS      1
#define tkOTHER   2
................................................................................
  if( zSql8 ){
    rc = sqlite3_complete(zSql8);
  }
  sqlite3ValueFree(pVal);
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_OMIT_COMPLETE */

Changes to test/enc2.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
444
445
446
447
448
449
450

451
452
453
454
455
456
457

458
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The focus of
# this file is testing the SQLite routines used for converting between the
# various suported unicode encodings (UTF-8, UTF-16, UTF-16le and
# UTF-16be).
#
# $Id: enc2.test,v 1.21 2005/02/13 23:34:25 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If UTF16 support is disabled, ignore the tests in this file
#
ifcapable {!utf16} {
................................................................................
db2 close

proc utf16 {utf8} {
  set utf16 [encoding convertto unicode $utf8]
  append utf16 "\x00\x00"
  return $utf16
}

do_test enc2-8.1 {
  sqlite3_complete16 [utf16 "SELECT * FROM t1;"]
} {1}
do_test enc2-8.2 {
  sqlite3_complete16 [utf16 "SELECT * FROM"]
} {0}


finish_test







|







 







>
|
|
|
|
|
|
|
>

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The focus of
# this file is testing the SQLite routines used for converting between the
# various suported unicode encodings (UTF-8, UTF-16, UTF-16le and
# UTF-16be).
#
# $Id: enc2.test,v 1.22 2005/02/26 17:31:28 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# If UTF16 support is disabled, ignore the tests in this file
#
ifcapable {!utf16} {
................................................................................
db2 close

proc utf16 {utf8} {
  set utf16 [encoding convertto unicode $utf8]
  append utf16 "\x00\x00"
  return $utf16
}
ifcapable {complete} {
  do_test enc2-8.1 {
    sqlite3_complete16 [utf16 "SELECT * FROM t1;"]
  } {1}
  do_test enc2-8.2 {
    sqlite3_complete16 [utf16 "SELECT * FROM"]
  } {0}
}

finish_test

Changes to test/main.test.

7
8
9
10
11
12
13
14
15
16
17




18
19
20
21
22
23
24
...
234
235
236
237
238
239
240


241
242
243
244
245
246
247
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is exercising the code in main.c.
#
# $Id: main.test,v 1.19 2005/01/11 17:46:42 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl





# Tests of the sqlite_complete() function.
#
do_test main-1.1 {
  db complete {This is a test}
} {0}
do_test main-1.2 {
................................................................................
} {1}
do_test main-1.35 {
  db complete {hi /**/ there;}
} {1}
do_test main-1.36 {
  db complete {hi there/***/;}
} {1}




# Try to open a database with a corrupt database file.
#
do_test main-2.0 {
  catch {db close}
  file delete -force test.db







|



>
>
>
>







 







>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is exercising the code in main.c.
#
# $Id: main.test,v 1.20 2005/02/26 17:31:28 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Only do the next group of tests if the sqlite3_complete API is available
#
ifcapable {complete} {

# Tests of the sqlite_complete() function.
#
do_test main-1.1 {
  db complete {This is a test}
} {0}
do_test main-1.2 {
................................................................................
} {1}
do_test main-1.35 {
  db complete {hi /**/ there;}
} {1}
do_test main-1.36 {
  db complete {hi there/***/;}
} {1}

} ;# end ifcapable {complete}


# Try to open a database with a corrupt database file.
#
do_test main-2.0 {
  catch {db close}
  file delete -force test.db

Changes to test/tclsqlite.test.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
92
93
94
95
96
97
98

99
100
101
102

103
104
105
106
107
108
109
# This file implements regression tests for TCL interface to the
# SQLite library. 
#
# Actually, all tests are based on the TCL interface, so the main
# interface is pretty well tested.  This file contains some addition
# tests for fringe issues that the main test suite does not cover.
#
# $Id: tclsqlite.test,v 1.37 2005/01/24 00:28:43 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Check the error messages generated by tclsqlite
#
if {[sqlite3 -has-codec]} {
................................................................................
  set v [catch {db changes xyz} msg]
  lappend v $msg
} {1 {wrong # args: should be "db changes "}}
do_test tcl-1.12 {
  set v [catch {db commit_hook a b c} msg]
  lappend v $msg
} {1 {wrong # args: should be "db commit_hook ?CALLBACK?"}}

do_test tcl-1.13 {
  set v [catch {db complete} msg]
  lappend v $msg
} {1 {wrong # args: should be "db complete SQL"}}

do_test tcl-1.14 {
  set v [catch {db eval} msg]
  lappend v $msg
} {1 {wrong # args: should be "db eval SQL ?ARRAY-NAME? ?SCRIPT?"}}
do_test tcl-1.15 {
  set v [catch {db function} msg]
  lappend v $msg







|







 







>
|
|
|
|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# This file implements regression tests for TCL interface to the
# SQLite library. 
#
# Actually, all tests are based on the TCL interface, so the main
# interface is pretty well tested.  This file contains some addition
# tests for fringe issues that the main test suite does not cover.
#
# $Id: tclsqlite.test,v 1.38 2005/02/26 17:31:28 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Check the error messages generated by tclsqlite
#
if {[sqlite3 -has-codec]} {
................................................................................
  set v [catch {db changes xyz} msg]
  lappend v $msg
} {1 {wrong # args: should be "db changes "}}
do_test tcl-1.12 {
  set v [catch {db commit_hook a b c} msg]
  lappend v $msg
} {1 {wrong # args: should be "db commit_hook ?CALLBACK?"}}
ifcapable {complete} {
  do_test tcl-1.13 {
    set v [catch {db complete} msg]
    lappend v $msg
  } {1 {wrong # args: should be "db complete SQL"}}
}
do_test tcl-1.14 {
  set v [catch {db eval} msg]
  lappend v $msg
} {1 {wrong # args: should be "db eval SQL ?ARRAY-NAME? ?SCRIPT?"}}
do_test tcl-1.15 {
  set v [catch {db function} msg]
  lappend v $msg