/ Check-in [b0a3becd]
Login

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

Overview
Comment:Fix bugs associated with the codec. (CVS 1846)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:b0a3becd82b9a4203c23f35dc5a5fd725e046f21
User & Date: drh 2004-07-22 15:02:25
Context
2004-07-22
15:45
Change sqlite* to sqlite3* in the API reference for version 3.0. Ticket #818. (CVS 1847) check-in: 7c96dadd user: drh tags: trunk
15:02
Fix bugs associated with the codec. (CVS 1846) check-in: b0a3becd user: drh tags: trunk
02:40
Changes in support of using a codec. (CVS 1845) check-in: 58505bf9 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to main.mk.

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

# This is how we compile
#
TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src

# Object files for the SQLite library.
#
LIBOBJ = attach.o auth.o btree.o build.o date.o delete.o \
         expr.o func.o hash.o insert.o \
         main.o opcodes.o os_mac.o os_unix.o os_win.o \
         pager.o parse.o pragma.o printf.o random.o \
         select.o table.o tclsqlite.o tokenize.o trigger.o \
         update.o util.o vacuum.o \
         vdbe.o vdbeapi.o vdbeaux.o vdbemem.o \
         where.o utf.o legacy.o







|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

# This is how we compile
#
TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src

# Object files for the SQLite library.
#
LIBOBJ+= attach.o auth.o btree.o build.o date.o delete.o \
         expr.o func.o hash.o insert.o \
         main.o opcodes.o os_mac.o os_unix.o os_win.o \
         pager.o parse.o pragma.o printf.o random.o \
         select.o table.o tclsqlite.o tokenize.o trigger.o \
         update.o util.o vacuum.o \
         vdbe.o vdbeapi.o vdbeaux.o vdbemem.o \
         where.o utf.o legacy.o

Changes to src/attach.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26






27
28
29
30
31
32
33
..
87
88
89
90
91
92
93
94
95

96
97
98

99




100
101














102
103
104
105
106
107
108
**    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.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.24 2004/07/22 02:40:38 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called by the parser to process an ATTACH statement:
**
**     ATTACH DATABASE filename AS dbname
**
** The pFilename and pDbname arguments are the tokens that define the
** filename and dbname in the ATTACH statement.
*/
void sqlite3Attach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){






  Db *aNew;
  int rc, i;
  char *zFile, *zName;
  sqlite *db;
  Vdbe *v;

  v = sqlite3GetVdbe(pParse);
................................................................................
  aNew->zName = zName;
  aNew->safety_level = 3;
  rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
  if( rc ){
    sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
  }
#if SQLITE_HAS_CODEC
  assert( pKey!=0 );
  if( pKey->n>0 ){

    extern int sqlite3CodecAttach(sqlite*, int, void*, int);
    char *zKey = 0;
    int nKey;

    sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);




    zKey = sqlite3NameFromToken(pKey);
    nKey = strlen(zKey);














  }
#endif
  sqliteFree(zFile);
  db->flags &= ~SQLITE_Initialized;
  if( pParse->nErr==0 && rc==SQLITE_OK ){
    rc = sqlite3ReadSchema(pParse);
  }







|











|
>
>
>
>
>
>







 







<
<
>
|
|

>
|
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
..
93
94
95
96
97
98
99


100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
**    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.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.25 2004/07/22 15:02:25 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called by the parser to process an ATTACH statement:
**
**     ATTACH DATABASE filename AS dbname
**
** The pFilename and pDbname arguments are the tokens that define the
** filename and dbname in the ATTACH statement.
*/
void sqlite3Attach(
  Parse *pParse,       /* The parser context */
  Token *pFilename,    /* Name of database file */
  Token *pDbname,      /* Name of the database to use internally */
  int keyType,         /* 0: no key.  1: TEXT,  2: BLOB */
  Token *pKey          /* Text of the key for keytype 2 and 3 */
){
  Db *aNew;
  int rc, i;
  char *zFile, *zName;
  sqlite *db;
  Vdbe *v;

  v = sqlite3GetVdbe(pParse);
................................................................................
  aNew->zName = zName;
  aNew->safety_level = 3;
  rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
  if( rc ){
    sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
  }
#if SQLITE_HAS_CODEC


  {
    extern int sqlite3CodecAttach(sqlite3*, int, void*, int);
    char *zKey;
    int nKey;
    if( keyType==0 ){
      /* No key specified.  Use the key from the main database */
      extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
      sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
    }else if( keyType==1 ){
      /* Key specified as text */
      zKey = sqlite3NameFromToken(pKey);
      nKey = strlen(zKey);
    }else{
      /* Key specified as a BLOB */
      char *zTemp;
      assert( keyType==2 );
      pKey->z++;
      pKey->n--;
      zTemp = sqlite3NameFromToken(pKey);
      zKey = sqlite3HexToBlob(zTemp);
      sqliteFree(zTemp);
    }
    sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
    if( keyType ){
      sqliteFree(zKey);
    }
  }
#endif
  sqliteFree(zFile);
  db->flags &= ~SQLITE_Initialized;
  if( pParse->nErr==0 && rc==SQLITE_OK ){
    rc = sqlite3ReadSchema(pParse);
  }

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
997
998
999
1000
1001
1002
1003
1004
1005

1006
1007
1008
1009
1010
1011
1012
....
2512
2513
2514
2515
2516
2517
2518


2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.152 2004/07/22 01:19:35 drh Exp $
*/
#include "os.h"         /* Must be first to enable large file support */
#include "sqliteInt.h"
#include "pager.h"
#include <assert.h>
#include <string.h>

................................................................................
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
    char zBuf[SQLITE_MAX_PAGE_SIZE];
    if( !pPg->dirty ) continue;
    if( (int)pPg->pgno <= pPager->origDbSize ){
      sqlite3OsSeek(&pPager->fd, pPager->pageSize*(off_t)(pPg->pgno-1));
      rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize);
      TRACE2("REFETCH page %d\n", pPg->pgno);
      CODEC(pPager, zBuf, pPg->pgno, 2);
      if( rc ) break;

    }else{
      memset(zBuf, 0, pPager->pageSize);
    }
    if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), pPager->pageSize) ){
      memcpy(PGHDR_TO_DATA(pPg), zBuf, pPager->pageSize);
      if( pPager->xReiniter ){
        pPager->xReiniter(PGHDR_TO_DATA(pPg), pPager->pageSize);
................................................................................
        assert( pHist->pOrig==0 );
        pHist->pOrig = sqliteMallocRaw( pPager->pageSize );
        if( pHist->pOrig ){
          memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
        }
        pPg->inJournal = 1;
      }else{


        u32 cksum = pager_cksum(pPager, pPg->pgno, pData);
        saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
        store32bits(cksum, pPg, pPager->pageSize);
        szPg = pPager->pageSize+8;
        store32bits(pPg->pgno, pPg, -4);
        CODEC(pPager, pData, pPg->pgno, 7);
        rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
        pPager->journalOff += szPg;
        TRACE3("JOURNAL page %d needSync=%d\n", pPg->pgno, pPg->needSync);
        CODEC(pPager, pData, pPg->pgno, 0);
        *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
        if( rc!=SQLITE_OK ){
          sqlite3pager_rollback(pPager);







|







 







<

>







 







>
>
|




<







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
1011
1012
....
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525

2526
2527
2528
2529
2530
2531
2532
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.153 2004/07/22 15:02:25 drh Exp $
*/
#include "os.h"         /* Must be first to enable large file support */
#include "sqliteInt.h"
#include "pager.h"
#include <assert.h>
#include <string.h>

................................................................................
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
    char zBuf[SQLITE_MAX_PAGE_SIZE];
    if( !pPg->dirty ) continue;
    if( (int)pPg->pgno <= pPager->origDbSize ){
      sqlite3OsSeek(&pPager->fd, pPager->pageSize*(off_t)(pPg->pgno-1));
      rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize);
      TRACE2("REFETCH page %d\n", pPg->pgno);

      if( rc ) break;
      CODEC(pPager, zBuf, pPg->pgno, 2);
    }else{
      memset(zBuf, 0, pPager->pageSize);
    }
    if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), pPager->pageSize) ){
      memcpy(PGHDR_TO_DATA(pPg), zBuf, pPager->pageSize);
      if( pPager->xReiniter ){
        pPager->xReiniter(PGHDR_TO_DATA(pPg), pPager->pageSize);
................................................................................
        assert( pHist->pOrig==0 );
        pHist->pOrig = sqliteMallocRaw( pPager->pageSize );
        if( pHist->pOrig ){
          memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
        }
        pPg->inJournal = 1;
      }else{
        u32 cksum;
        CODEC(pPager, pData, pPg->pgno, 7);
        cksum = pager_cksum(pPager, pPg->pgno, pData);
        saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
        store32bits(cksum, pPg, pPager->pageSize);
        szPg = pPager->pageSize+8;
        store32bits(pPg->pgno, pPg, -4);

        rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
        pPager->journalOff += szPg;
        TRACE3("JOURNAL page %d needSync=%d\n", pPg->pgno, pPg->needSync);
        CODEC(pPager, pData, pPg->pgno, 0);
        *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
        if( rc!=SQLITE_OK ){
          sqlite3pager_rollback(pPager);

Changes to src/parse.y.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
50
51
52
53
54
55
56





57
58
59
60
61
62
63
...
889
890
891
892
893
894
895
896
897
898
899
900




901
902
903
904
905
906
907
908
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.130 2004/07/20 14:06:52 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
................................................................................
**
**      UPDATE ON (a,b,c)
**
** Then the "b" IdList records the list "a,b,c".
*/
struct TrigEvent { int a; IdList * b; };






} // end %include

// These are extra tokens used by the lexer but never seen by the
// parser.  We put them in a rule so that the parser generator will
// add them to the parse.h output file.
//
%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
................................................................................
////////////////////////  DROP TRIGGER statement //////////////////////////////
cmd ::= DROP TRIGGER nm(X) dbnm(D). {
  sqlite3DropTrigger(pParse,sqlite3SrcListAppend(0,&X,&D));
}

//////////////////////// ATTACH DATABASE file AS name /////////////////////////
cmd ::= ATTACH database_kw_opt ids(F) AS nm(D) key_opt(K). {
  sqlite3Attach(pParse, &F, &D, &K);
}
%type key_opt {Token}
key_opt(A) ::= USING ids(X).  { A = X; }
key_opt(A) ::= .              { A.z = 0; A.n = 0; }





database_kw_opt ::= DATABASE.
database_kw_opt ::= .

//////////////////////// DETACH DATABASE name /////////////////////////////////
cmd ::= DETACH database_kw_opt nm(D). {
  sqlite3Detach(pParse, &D);
}







|







 







>
>
>
>
>







 







|

|
<
|
>
>
>
>








10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
...
894
895
896
897
898
899
900
901
902
903

904
905
906
907
908
909
910
911
912
913
914
915
916
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.131 2004/07/22 15:02:25 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
................................................................................
**
**      UPDATE ON (a,b,c)
**
** Then the "b" IdList records the list "a,b,c".
*/
struct TrigEvent { int a; IdList * b; };

/*
** An instance of this structure holds the ATTACH key and the key type.
*/
struct AttachKey { int type;  Token key; };

} // end %include

// These are extra tokens used by the lexer but never seen by the
// parser.  We put them in a rule so that the parser generator will
// add them to the parse.h output file.
//
%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
................................................................................
////////////////////////  DROP TRIGGER statement //////////////////////////////
cmd ::= DROP TRIGGER nm(X) dbnm(D). {
  sqlite3DropTrigger(pParse,sqlite3SrcListAppend(0,&X,&D));
}

//////////////////////// ATTACH DATABASE file AS name /////////////////////////
cmd ::= ATTACH database_kw_opt ids(F) AS nm(D) key_opt(K). {
  sqlite3Attach(pParse, &F, &D, K.type, &K.key);
}
%type key_opt {struct AttachKey}

key_opt(A) ::= .                     { A.type = 0; }
%ifdef SQLITE_HAS_CODEC
key_opt(A) ::= KEY ids(X).           { A.type=1; A.key = X; }
key_opt(A) ::= KEY BLOB(X).          { A.type=2; A.Key = X; }
%endif

database_kw_opt ::= DATABASE.
database_kw_opt ::= .

//////////////////////// DETACH DATABASE name /////////////////////////////////
cmd ::= DETACH database_kw_opt nm(D). {
  sqlite3Detach(pParse, &D);
}

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.307 2004/07/22 01:19:35 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#include "config.h"
#include "sqlite3.h"
#include "hash.h"
................................................................................
  void sqlite3AuthContextPop(AuthContext*);
#else
# define sqlite3AuthRead(a,b,c)
# define sqlite3AuthCheck(a,b,c,d,e)    SQLITE_OK
# define sqlite3AuthContextPush(a,b,c)
# define sqlite3AuthContextPop(a)  ((void)(a))
#endif
void sqlite3Attach(Parse*, Token*, Token*, Token*);
void sqlite3Detach(Parse*, Token*);
int sqlite3BtreeFactory(const sqlite *db, const char *zFilename,
                       int omitJournal, int nCache, Btree **ppBtree);
int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.308 2004/07/22 15:02:25 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#include "config.h"
#include "sqlite3.h"
#include "hash.h"
................................................................................
  void sqlite3AuthContextPop(AuthContext*);
#else
# define sqlite3AuthRead(a,b,c)
# define sqlite3AuthCheck(a,b,c,d,e)    SQLITE_OK
# define sqlite3AuthContextPush(a,b,c)
# define sqlite3AuthContextPop(a)  ((void)(a))
#endif
void sqlite3Attach(Parse*, Token*, Token*, int, Token*);
void sqlite3Detach(Parse*, Token*);
int sqlite3BtreeFactory(const sqlite *db, const char *zFilename,
                       int omitJournal, int nCache, Btree **ppBtree);
int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
299
300
301
302
303
304
305
























































306
307
308
309
310
311
312
....
2324
2325
2326
2327
2328
2329
2330
2331
2332


2333
2334
2335
2336
2337
2338
2339
**    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.94 2004/07/17 21:56:10 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db));
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}

























































/*
** Usage:  sqlite3_close DB
**
** Closes the database opened by sqlite3_open.
*/
static int sqlite_test_close(
................................................................................
     { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
     { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
     { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
#ifdef SQLITE_DEBUG
     { "sqlite_malloc_fail",            (Tcl_CmdProc*)sqlite_malloc_fail    },
     { "sqlite_malloc_stat",            (Tcl_CmdProc*)sqlite_malloc_stat    },
#endif
     { "sqlite_bind",                    (Tcl_CmdProc*)test_bind             },
     { "breakpoint",                     (Tcl_CmdProc*)test_breakpoint       },


  };
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
     void *clientData;
  } aObjCmd[] = {
     { "sqlite3_bind_int",              test_bind_int,      0 },







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
....
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
**    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.95 2004/07/22 15:02:26 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db));
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}

/*
** Usage:  sqlite3_key DB KEY
**
** Set the codec key.
*/
static int test_key(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite *db;
  const char *zKey;
  int nKey;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  zKey = argv[2];
  nKey = strlen(zKey);
#ifdef SQLITE_HAS_CODEC
  sqlite3_key(db, zKey, nKey);
#endif
  return TCL_OK;
}

/*
** Usage:  sqlite3_rekey DB KEY
**
** Change the codec key.
*/
static int test_rekey(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite *db;
  const char *zKey;
  int nKey;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  zKey = argv[2];
  nKey = strlen(zKey);
#ifdef SQLITE_HAS_CODEC
  sqlite3_rekey(db, zKey, nKey);
#endif
  return TCL_OK;
}

/*
** Usage:  sqlite3_close DB
**
** Closes the database opened by sqlite3_open.
*/
static int sqlite_test_close(
................................................................................
     { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
     { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
     { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
#ifdef SQLITE_DEBUG
     { "sqlite_malloc_fail",            (Tcl_CmdProc*)sqlite_malloc_fail    },
     { "sqlite_malloc_stat",            (Tcl_CmdProc*)sqlite_malloc_stat    },
#endif
     { "sqlite_bind",                   (Tcl_CmdProc*)test_bind             },
     { "breakpoint",                    (Tcl_CmdProc*)test_breakpoint       },
     { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
     { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
  };
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
     void *clientData;
  } aObjCmd[] = {
     { "sqlite3_bind_int",              test_bind_int,      0 },

Changes to test/capi3.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
439
440
441
442
443
444
445

446
447
448
449
450
451
452
...
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481

482


483
484
485
486
487

488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543

544


545
546
547
548
549
550
551
...
757
758
759
760
761
762
763
764
#    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 script testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.19 2004/06/30 06:30:26 danielk1977 Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
} SQLITE_OK

set ::ENC [execsql {pragma encoding}]
db close

do_test capi3-6.0 {
  set DB [sqlite3_open test.db]

  set sql {SELECT a FROM t1 order by rowid}
  set STMT [sqlite3_prepare $DB $sql -1 TAIL]
  expr 0
} {0}
do_test capi3-6.1 {
  sqlite3_close $DB
} {SQLITE_BUSY}
................................................................................
do_test capi3-6.3 {
  sqlite3_finalize $STMT
} {SQLITE_OK}
do_test capi3-6.4 {
  sqlite3_close $DB
} {SQLITE_OK}


# Test what happens when the library encounters a newer file format.
# Do this by updating the file format via the btree layer.
do_test capi3-7.1 {
  set ::bt [btree_open test.db 10 0]
  btree_begin_transaction $::bt
  set meta [btree_get_meta $::bt]
  lset meta 2 2
  eval [concat btree_update_meta $::bt [lrange $meta 0 end]]
  btree_commit $::bt
  btree_close $::bt
} {}
do_test capi3-7.2 {
  sqlite3 db test.db
breakpoint
  catchsql {
    SELECT * FROM sqlite_master;
  }
} {1 {unsupported file format}}




# Now test that the library correctly handles bogus entries in the
# sqlite_master table (schema corruption).
do_test capi3-8.1 {
  db close
  file delete -force test.db

  sqlite3 db test.db
  execsql {
    CREATE TABLE t1(a);
  }
  db close
} {}
do_test capi3-8.2 {
  set ::bt [btree_open test.db 10 0]
  btree_begin_transaction $::bt
  set ::bc [btree_cursor $::bt 1 1]

  # Build a 5-field row record consisting of 5 null records. This is
  # officially black magic.
  catch {unset data}
  set data [binary format c6 {6 0 0 0 0 0}]
  btree_insert $::bc 5 $data

  btree_close_cursor $::bc
  btree_commit $::bt
  btree_close $::bt
} {}
do_test capi3-8.3 {
  sqlite3 db test.db
  catchsql {
    SELECT * FROM sqlite_master;
  }
} {1 {malformed database schema}}
do_test capi3-8.4 {
  set ::bt [btree_open test.db 10 0]
  btree_begin_transaction $::bt
  set ::bc [btree_cursor $::bt 1 1]

  # Build a 5-field row record. The first field is a string 'table', and
  # subsequent fields are all NULL. Replace the other broken record with
  # this one and try to read the schema again. The broken record uses
  # either UTF-8 or native UTF-16 (if this file is being run by
  # utf16.test).
  if { [string match UTF-16* $::ENC] } {
    set data [binary format c6a10 {6 33 0 0 0 0} [utf16 table]]
  } else {
    set data [binary format c6a5 {6 23 0 0 0 0} table]
  }
  btree_insert $::bc 5 $data

  btree_close_cursor $::bc
  btree_commit $::bt
  btree_close $::bt
} {}
do_test capi3-8.5 {
  db close 
  sqlite3 db test.db
  catchsql {
    SELECT * FROM sqlite_master;
  }
} {1 {malformed database schema}}
db close

file delete -force test.db



# Test the english language string equivalents for sqlite error codes
set code2english [list \
SQLITE_OK         {not an error} \
SQLITE_ERROR      {SQL logic error or missing database} \
SQLITE_INTERNAL   {internal SQLite implementation flaw} \
SQLITE_PERM       {access permission denied} \
................................................................................
    COMMIT;
    SELECT a FROM t1;
  }
} {1 2 3 4}


finish_test








|







 







>







 







>
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
>
|
>
>
|
|
|
<
|
>
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>

>
>







 







<
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
...
764
765
766
767
768
769
770

#    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 script testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.20 2004/07/22 15:02:26 drh Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
} SQLITE_OK

set ::ENC [execsql {pragma encoding}]
db close

do_test capi3-6.0 {
  set DB [sqlite3_open test.db]
  sqlite3_key $DB xyzzy
  set sql {SELECT a FROM t1 order by rowid}
  set STMT [sqlite3_prepare $DB $sql -1 TAIL]
  expr 0
} {0}
do_test capi3-6.1 {
  sqlite3_close $DB
} {SQLITE_BUSY}
................................................................................
do_test capi3-6.3 {
  sqlite3_finalize $STMT
} {SQLITE_OK}
do_test capi3-6.4 {
  sqlite3_close $DB
} {SQLITE_OK}

if {![sqlite3 -has-codec]} {
  # Test what happens when the library encounters a newer file format.
  # Do this by updating the file format via the btree layer.
  do_test capi3-7.1 {
    set ::bt [btree_open test.db 10 0]
    btree_begin_transaction $::bt
    set meta [btree_get_meta $::bt]
    lset meta 2 2
    eval [concat btree_update_meta $::bt [lrange $meta 0 end]]
    btree_commit $::bt
    btree_close $::bt
  } {}
  do_test capi3-7.2 {
    sqlite3 db test.db

    catchsql {
      SELECT * FROM sqlite_master;
    }
  } {1 {unsupported file format}}
  db close
}

if {![sqlite3 -has-codec]} {
  # Now test that the library correctly handles bogus entries in the
  # sqlite_master table (schema corruption).
  do_test capi3-8.1 {

    file delete -force test.db
    file delete -force test.db-journal
    sqlite3 db test.db
    execsql {
      CREATE TABLE t1(a);
    }
    db close
  } {}
  do_test capi3-8.2 {
    set ::bt [btree_open test.db 10 0]
    btree_begin_transaction $::bt
    set ::bc [btree_cursor $::bt 1 1]

    # Build a 5-field row record consisting of 5 null records. This is
    # officially black magic.
    catch {unset data}
    set data [binary format c6 {6 0 0 0 0 0}]
    btree_insert $::bc 5 $data

    btree_close_cursor $::bc
    btree_commit $::bt
    btree_close $::bt
  } {}
  do_test capi3-8.3 {
    sqlite3 db test.db
    catchsql {
      SELECT * FROM sqlite_master;
    }
  } {1 {malformed database schema}}
  do_test capi3-8.4 {
    set ::bt [btree_open test.db 10 0]
    btree_begin_transaction $::bt
    set ::bc [btree_cursor $::bt 1 1]
  
    # Build a 5-field row record. The first field is a string 'table', and
    # subsequent fields are all NULL. Replace the other broken record with
    # this one and try to read the schema again. The broken record uses
    # either UTF-8 or native UTF-16 (if this file is being run by
    # utf16.test).
    if { [string match UTF-16* $::ENC] } {
      set data [binary format c6a10 {6 33 0 0 0 0} [utf16 table]]
    } else {
      set data [binary format c6a5 {6 23 0 0 0 0} table]
    }
    btree_insert $::bc 5 $data
  
    btree_close_cursor $::bc
    btree_commit $::bt
    btree_close $::bt
  } {}
  do_test capi3-8.5 {
    db close 
    sqlite3 db test.db
    catchsql {
      SELECT * FROM sqlite_master;
    }
  } {1 {malformed database schema}}
  db close
}
file delete -force test.db
file delete -force test.db-journal


# Test the english language string equivalents for sqlite error codes
set code2english [list \
SQLITE_OK         {not an error} \
SQLITE_ERROR      {SQL logic error or missing database} \
SQLITE_INTERNAL   {internal SQLite implementation flaw} \
SQLITE_PERM       {access permission denied} \
................................................................................
    COMMIT;
    SELECT a FROM t1;
  }
} {1 2 3 4}


finish_test

Changes to test/lock2.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#    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 script is database locks between competing processes.
#
# $Id: lock2.test,v 1.2 2004/06/28 11:52:46 drh Exp $


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

# Launch another testfixture process to be controlled by this one. A
# channel name is returned that may be passed as the first argument to proc
................................................................................
# lock2-1.7: Attempt to reaquire a SHARED lock with the second process.
#            this fails due to the PENDING lock.
# lock2-1.8: Ensure the first process can now upgrade to EXCLUSIVE.
#
do_test lock2-1.1 {
  set ::tf1 [launch_testfixture]
  testfixture $::tf1 {
    sqlite3 db test.db
    db eval {select * from sqlite_master}
  }
} {}
do_test lock2-1.2 {
  execsql {
    BEGIN;
    CREATE TABLE abc(a, b, c);







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#    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 script is database locks between competing processes.
#
# $Id: lock2.test,v 1.3 2004/07/22 15:02:26 drh Exp $


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

# Launch another testfixture process to be controlled by this one. A
# channel name is returned that may be passed as the first argument to proc
................................................................................
# lock2-1.7: Attempt to reaquire a SHARED lock with the second process.
#            this fails due to the PENDING lock.
# lock2-1.8: Ensure the first process can now upgrade to EXCLUSIVE.
#
do_test lock2-1.1 {
  set ::tf1 [launch_testfixture]
  testfixture $::tf1 {
    sqlite3 db test.db -key xyzzy
    db eval {select * from sqlite_master}
  }
} {}
do_test lock2-1.2 {
  execsql {
    BEGIN;
    CREATE TABLE abc(a, b, c);

Changes to test/pragma.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the PRAGMA command.
#
# $Id: pragma.test,v 1.15 2004/06/26 19:35:30 drh Exp $

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

# Test organization:
#
# pragma-1.*: Test cache_size, default_cache_size and synchronous on main db.
................................................................................
    pragma aux.synchronous;
  } 
} {2 1}

# Construct a corrupted index and make sure the integrity_check
# pragma finds it.
#
if {![sqlite3 -has-codec]} {

do_test pragma-3.1 {
  execsql {
    BEGIN;
    CREATE TABLE t2(a,b,c);
    CREATE INDEX i2 ON t2(a);
    INSERT INTO t2 VALUES(11,2,3);
    INSERT INTO t2 VALUES(22,3,4);
    COMMIT;
    SELECT rowid, * from t2;
  }
} {1 11 2 3 2 22 3 4}

do_test pragma-3.2 {
  set rootpage [execsql {SELECT rootpage FROM sqlite_master WHERE name='i2'}]
  set db [btree_open test.db 100 0]
  btree_begin_transaction $db
  set c [btree_cursor $db $rootpage 1]
  btree_first $c
  btree_delete $c
  btree_commit $db
  btree_close $db
  execsql {PRAGMA integrity_check}
} {{rowid 1 missing from index i2} {wrong # of entries in index i2}}
}; # endif has-codec

do_test pragma-3.3 {
  execsql {
    DROP INDEX i2;
  } 
} {}

# Test modifying the cache_size of an attached database.







|







 







|
>











>
|
|
|
|
|
|
|
|
|
|
|
<
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the PRAGMA command.
#
# $Id: pragma.test,v 1.16 2004/07/22 15:02:26 drh Exp $

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

# Test organization:
#
# pragma-1.*: Test cache_size, default_cache_size and synchronous on main db.
................................................................................
    pragma aux.synchronous;
  } 
} {2 1}

# Construct a corrupted index and make sure the integrity_check
# pragma finds it.
#
# These tests won't work if the database is encrypted
#
do_test pragma-3.1 {
  execsql {
    BEGIN;
    CREATE TABLE t2(a,b,c);
    CREATE INDEX i2 ON t2(a);
    INSERT INTO t2 VALUES(11,2,3);
    INSERT INTO t2 VALUES(22,3,4);
    COMMIT;
    SELECT rowid, * from t2;
  }
} {1 11 2 3 2 22 3 4}
if {![sqlite3 -has-codec]} {
  do_test pragma-3.2 {
    set rootpage [execsql {SELECT rootpage FROM sqlite_master WHERE name='i2'}]
    set db [btree_open test.db 100 0]
    btree_begin_transaction $db
    set c [btree_cursor $db $rootpage 1]
    btree_first $c
    btree_delete $c
    btree_commit $db
    btree_close $db
    execsql {PRAGMA integrity_check}
  } {{rowid 1 missing from index i2} {wrong # of entries in index i2}}

}
do_test pragma-3.3 {
  execsql {
    DROP INDEX i2;
  } 
} {}

# Test modifying the cache_size of an attached database.

Changes to test/quick.test.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#    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.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: quick.test,v 1.27 2004/07/19 00:39:46 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {}
set ISQUICK 1

................................................................................
set EXCLUDE {
  all.test
  quick.test
  btree2.test
  malloc.test
  memleak.test
  misuse.test
  format3.test
  crash.test
  utf16.test
}

if {[sqlite3 -has-codec]} {
  lappend EXCLUDE \
    attach.test \
    attach2.test \
    auth.test \
    format3.test \
    version.test
}

foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
  set tail [file tail $testfile]
  if {[lsearch -exact $EXCLUDE $tail]>=0} continue
  source $testfile
  catch {db close}







|







 







<





|
<
<
|
<
<







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
21
22
23
24
25
26
27

28
29
30
31
32
33


34


35
36
37
38
39
40
41
#    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.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: quick.test,v 1.28 2004/07/22 15:02:26 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {}
set ISQUICK 1

................................................................................
set EXCLUDE {
  all.test
  quick.test
  btree2.test
  malloc.test
  memleak.test
  misuse.test

  crash.test
  utf16.test
}

if {[sqlite3 -has-codec]} {
  # lappend EXCLUDE \


  #  conflict.test


}

foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
  set tail [file tail $testfile]
  if {[lsearch -exact $EXCLUDE $tail]>=0} continue
  source $testfile
  catch {db close}

Changes to test/types.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
33
34
35
36
37
38
39




40
41
42
43
44
45
46
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. Specfically
# it tests that the different storage classes (integer, real, text etc.)
# all work correctly.
#
# $Id: types.test,v 1.9 2004/06/30 03:08:25 drh Exp $

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

# Tests in this file are organized roughly as follows:
#
# types-1.*.*: Test that values are stored using the expected storage
................................................................................
# types-2.3.*: NULL
# types-2.4.*: TEXT
# types-2.5.*: Records with a few different storage classes.
#
# types-3.*: Test that the '=' operator respects manifest types.
#






# Create a table with one column for each type of affinity
do_test types-1.1.0 {
  execsql {
    CREATE TABLE t1(i integer, n numeric, t text, o blob);
  }
} {}







|







 







>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. Specfically
# it tests that the different storage classes (integer, real, text etc.)
# all work correctly.
#
# $Id: types.test,v 1.10 2004/07/22 15:02:26 drh Exp $

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

# Tests in this file are organized roughly as follows:
#
# types-1.*.*: Test that values are stored using the expected storage
................................................................................
# types-2.3.*: NULL
# types-2.4.*: TEXT
# types-2.5.*: Records with a few different storage classes.
#
# types-3.*: Test that the '=' operator respects manifest types.
#

# Disable encryption on the database for this test.
db close
set DB [sqlite3 db test.db]
sqlite3_rekey $DB {}

# Create a table with one column for each type of affinity
do_test types-1.1.0 {
  execsql {
    CREATE TABLE t1(i integer, n numeric, t text, o blob);
  }
} {}