/ Check-in [4a72a7bb]
Login

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

Overview
Comment:Continuing progress on the journal_mode pragma. It still does not work. (CVS 5027)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4a72a7bb9c5793cdaf4ee038482053e042d8db54
User & Date: drh 2008-04-17 20:59:38
Context
2008-04-18
09:01
Allow OP_MoveGt and similar to use an array of registers instead of a serialized record. Modify one type of index range scan to use this. (CVS 5028) check-in: c448f15a user: danielk1977 tags: trunk
2008-04-17
20:59
Continuing progress on the journal_mode pragma. It still does not work. (CVS 5027) check-in: 4a72a7bb user: drh tags: trunk
19:14
Additional work on ticket #3015. The previous fix (check-in (4919)) did not appear to work in all cases and it disabled indexing in some places where it should not have. New test cases added to help insure that the current fix is better. (CVS 5026) check-in: 0d2e258e user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
....
3231
3232
3233
3234
3235
3236
3237


3238
3239
3240
3241
3242
3243
3244
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.480 2008/04/11 17:11:27 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
      sqlite3ErrorMsg(pParse, "unable to open a temporary database "
        "file for storing temporary tables");
      pParse->rc = rc;
      return 1;
    }
    assert( (db->flags & SQLITE_InTrans)==0 || db->autoCommit );
    assert( db->aDb[1].pSchema );


  }
  return 0;
}

/*
** Generate VDBE code that will verify the schema cookie and start
** a read-transaction for all named database files.







|







 







>
>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
....
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.481 2008/04/17 20:59:38 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
      sqlite3ErrorMsg(pParse, "unable to open a temporary database "
        "file for storing temporary tables");
      pParse->rc = rc;
      return 1;
    }
    assert( (db->flags & SQLITE_InTrans)==0 || db->autoCommit );
    assert( db->aDb[1].pSchema );
    sqlite3PagerJournalMode(sqlite3BtreePager(db->aDb[1].pBt),
                            db->dfltJournalMode);
  }
  return 0;
}

/*
** Generate VDBE code that will verify the schema cookie and start
** a read-transaction for all named database files.

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
....
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325

1326
1327

1328
1329
1330
1331
1332
1333
1334
....
1354
1355
1356
1357
1358
1359
1360


1361
1362
1363
1364
1365
1366
1367
1368
....
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
....
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879

3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900

3901
3902
3903
3904
3905
3906
3907
....
3977
3978
3979
3980
3981
3982
3983
3984

3985
3986
3987
3988
3989
3990
3991
....
4114
4115
4116
4117
4118
4119
4120
4121

4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
....
5213
5214
5215
5216
5217
5218
5219
5220

5221
5222
5223
5224

5225
5226
5227
5228
5229
5230
5231
5232
5233
** 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.428 2008/04/17 17:02:01 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
................................................................................
  u8 needSync;                /* True if an fsync() is needed on the journal */
  u8 dirtyCache;              /* True if cached pages have changed */
  u8 alwaysRollback;          /* Disable DontRollback() for all pages */
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  u8 doNotSync;               /* Boolean. While true, do not spill the cache */
  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
  u8 persistJournal;          /* True if persistent_journal=ON */
  u8 changeCountDone;         /* Set after incrementing the change-counter */
  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
  int errCode;                /* One of several kinds of errors */
  int dbSize;                 /* Number of pages in the file */
  int origDbSize;             /* dbSize before the current change */
  int stmtSize;               /* Size of database (in pages) at stmt_begin() */
  int nRec;                   /* Number of pages written to the journal */
................................................................................

/*
** Execute a rollback if a transaction is active and unlock the 
** database file. If the pager has already entered the error state, 
** do not attempt the rollback.
*/
static void pagerUnlockAndRollback(Pager *p){
  assert( p->state>=PAGER_RESERVED || p->journalOpen==0 );
  if( p->errCode==SQLITE_OK && p->state>=PAGER_RESERVED ){
    sqlite3PagerRollback(p);
  }
  pager_unlock(p);

  assert( p->errCode || !p->journalOpen || (p->exclusiveMode&&!p->journalOff) );
  assert( p->errCode || !p->stmtOpen || p->exclusiveMode );

}

/*
** This routine ends a transaction.  A transaction is ended by either
** a COMMIT or a ROLLBACK.
**
** When this routine is called, the pager has the journal file open and
................................................................................
  }
  sqlite3PagerStmtCommit(pPager);
  if( pPager->stmtOpen && !pPager->exclusiveMode ){
    sqlite3OsClose(pPager->stfd);
    pPager->stmtOpen = 0;
  }
  if( pPager->journalOpen ){


    if( pPager->exclusiveMode && (rc = zeroJournalHdr(pPager))==SQLITE_OK ){
      pPager->journalOff = 0;
      pPager->journalStarted = 0;
    }else{
      sqlite3OsClose(pPager->jfd);
      pPager->journalOpen = 0;
      if( rc==SQLITE_OK ){
        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
................................................................................
  pPager->errCode = 0;
  pPager->exclusiveMode = 0;
  pager_reset(pPager);
  pagerUnlockAndRollback(pPager);
  enable_simulated_io_errors();
  PAGERTRACE2("CLOSE %d\n", PAGERID(pPager));
  IOTRACE(("CLOSE %p\n", pPager))
  assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
  if( pPager->journalOpen ){
    sqlite3OsClose(pPager->jfd);
  }
  sqlite3BitvecDestroy(pPager->pInJournal);
  if( pPager->stmtOpen ){
    sqlite3OsClose(pPager->stfd);
  }
................................................................................
static int pager_open_journal(Pager *pPager){
  sqlite3_vfs *pVfs = pPager->pVfs;
  int flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_CREATE);

  int rc;
  assert( !MEMDB );
  assert( pPager->state>=PAGER_RESERVED );
  assert( pPager->journalOpen==0 );
  assert( pPager->useJournal );
  assert( pPager->pInJournal==0 );
  sqlite3PagerPagecount(pPager);
  pagerLeave(pPager);
  pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
  pagerEnter(pPager);
  if( pPager->pInJournal==0 ){
    rc = SQLITE_NOMEM;
    goto failed_to_open_journal;
  }


  if( pPager->tempFile ){
    flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL);
  }else{
    flags |= (SQLITE_OPEN_MAIN_JOURNAL);
  }
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
  rc = sqlite3JournalOpen(
      pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
  );
#else
  rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
#endif
  assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
  pPager->journalOff = 0;
  pPager->setMaster = 0;
  pPager->journalHdr = 0;
  if( rc!=SQLITE_OK ){
    if( rc==SQLITE_NOMEM ){
      sqlite3OsDelete(pVfs, pPager->zJournal, 0);
    }
    goto failed_to_open_journal;

  }
  pPager->journalOpen = 1;
  pPager->journalStarted = 0;
  pPager->needSync = 0;
  pPager->alwaysRollback = 0;
  pPager->nRec = 0;
  if( pPager->errCode ){
................................................................................
      }
      if( rc!=SQLITE_OK ){
        pagerLeave(pPager);
        return rc;
      }
      pPager->dirtyCache = 0;
      PAGERTRACE2("TRANSACTION %d\n", PAGERID(pPager));
      if( pPager->useJournal && !pPager->tempFile ){

        rc = pager_open_journal(pPager);
      }
    }
  }else if( pPager->journalOpen && pPager->journalOff==0 ){
    /* This happens when the pager was in exclusive-access mode last
    ** time a (read or write) transaction was successfully concluded
    ** by this connection. Instead of deleting the journal file it was 
................................................................................
    */
    assert( pPager->state!=PAGER_UNLOCK );
    rc = sqlite3PagerBegin(pPg, 0);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    assert( pPager->state>=PAGER_RESERVED );
    if( !pPager->journalOpen && pPager->useJournal ){

      rc = pager_open_journal(pPager);
      if( rc!=SQLITE_OK ) return rc;
    }
    assert( pPager->journalOpen || !pPager->useJournal );
    pPager->dirtyCache = 1;
  
    /* The transaction journal now exists and we have a RESERVED or an
    ** EXCLUSIVE lock on the main database file.  Write the current page to
    ** the transaction journal if it is not there already.
    */
    if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){
      if( (int)pPg->pgno <= pPager->origDbSize ){
        if( MEMDB ){
          PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
          PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
          assert( pHist->pOrig==0 );
          pHist->pOrig = sqlite3_malloc( pPager->pageSize );
          if( !pHist->pOrig ){
................................................................................
** The returned value is either PAGER_JOURNALMODE_DELETE or
** PAGER_JOURNALMODE_PERSIST, indicating the current (possibly updated)
** journal-mode.
*/
int sqlite3PagerJournalMode(Pager *pPager, int eMode){
  assert( eMode==PAGER_JOURNALMODE_QUERY
            || eMode==PAGER_JOURNALMODE_DELETE
            || eMode==PAGER_JOURNALMODE_PERSIST );

  assert( PAGER_JOURNALMODE_QUERY<0 );
  assert( PAGER_JOURNALMODE_DELETE>=0 && PAGER_JOURNALMODE_PERSIST>=0 );
  if( eMode>=0 && !pPager->tempFile ){
    pPager->persistJournal = eMode;

  }
  return (int)pPager->persistJournal;
}

#ifdef SQLITE_TEST
/*
** Print a listing of all referenced pages and their ref count.
*/
void sqlite3PagerRefdump(Pager *pPager){







|







 







|







 







|




>


>







 







>
>
|







 







<







 







<











>
|
|
|
|
|

|
|
|

|

|
|
|
|
|
|
|
|
|
>







 







|
>







 







|
>



<






|







 







|
>


|
<
>

|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
....
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
....
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
....
2715
2716
2717
2718
2719
2720
2721

2722
2723
2724
2725
2726
2727
2728
....
3864
3865
3866
3867
3868
3869
3870

3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
....
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
....
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130

4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
....
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229

5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
** 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.429 2008/04/17 20:59:38 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
................................................................................
  u8 needSync;                /* True if an fsync() is needed on the journal */
  u8 dirtyCache;              /* True if cached pages have changed */
  u8 alwaysRollback;          /* Disable DontRollback() for all pages */
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  u8 doNotSync;               /* Boolean. While true, do not spill the cache */
  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
  u8 journalMode;             /* On of the PAGER_JOURNALMODE_* values */
  u8 changeCountDone;         /* Set after incrementing the change-counter */
  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
  int errCode;                /* One of several kinds of errors */
  int dbSize;                 /* Number of pages in the file */
  int origDbSize;             /* dbSize before the current change */
  int stmtSize;               /* Size of database (in pages) at stmt_begin() */
  int nRec;                   /* Number of pages written to the journal */
................................................................................

/*
** Execute a rollback if a transaction is active and unlock the 
** database file. If the pager has already entered the error state, 
** do not attempt the rollback.
*/
static void pagerUnlockAndRollback(Pager *p){
  /* assert( p->state>=PAGER_RESERVED || p->journalOpen==0 ); */
  if( p->errCode==SQLITE_OK && p->state>=PAGER_RESERVED ){
    sqlite3PagerRollback(p);
  }
  pager_unlock(p);
#if 0
  assert( p->errCode || !p->journalOpen || (p->exclusiveMode&&!p->journalOff) );
  assert( p->errCode || !p->stmtOpen || p->exclusiveMode );
#endif
}

/*
** This routine ends a transaction.  A transaction is ended by either
** a COMMIT or a ROLLBACK.
**
** When this routine is called, the pager has the journal file open and
................................................................................
  }
  sqlite3PagerStmtCommit(pPager);
  if( pPager->stmtOpen && !pPager->exclusiveMode ){
    sqlite3OsClose(pPager->stfd);
    pPager->stmtOpen = 0;
  }
  if( pPager->journalOpen ){
    if( (pPager->exclusiveMode ||
         pPager->journalMode==PAGER_JOURNALMODE_PERSIST) 
       && (rc = zeroJournalHdr(pPager))==SQLITE_OK ){
      pPager->journalOff = 0;
      pPager->journalStarted = 0;
    }else{
      sqlite3OsClose(pPager->jfd);
      pPager->journalOpen = 0;
      if( rc==SQLITE_OK ){
        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
................................................................................
  pPager->errCode = 0;
  pPager->exclusiveMode = 0;
  pager_reset(pPager);
  pagerUnlockAndRollback(pPager);
  enable_simulated_io_errors();
  PAGERTRACE2("CLOSE %d\n", PAGERID(pPager));
  IOTRACE(("CLOSE %p\n", pPager))

  if( pPager->journalOpen ){
    sqlite3OsClose(pPager->jfd);
  }
  sqlite3BitvecDestroy(pPager->pInJournal);
  if( pPager->stmtOpen ){
    sqlite3OsClose(pPager->stfd);
  }
................................................................................
static int pager_open_journal(Pager *pPager){
  sqlite3_vfs *pVfs = pPager->pVfs;
  int flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_CREATE);

  int rc;
  assert( !MEMDB );
  assert( pPager->state>=PAGER_RESERVED );

  assert( pPager->useJournal );
  assert( pPager->pInJournal==0 );
  sqlite3PagerPagecount(pPager);
  pagerLeave(pPager);
  pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
  pagerEnter(pPager);
  if( pPager->pInJournal==0 ){
    rc = SQLITE_NOMEM;
    goto failed_to_open_journal;
  }

  if( pPager->journalOpen==0 ){
    if( pPager->tempFile ){
      flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL);
    }else{
      flags |= (SQLITE_OPEN_MAIN_JOURNAL);
    }
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
    rc = sqlite3JournalOpen(
        pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
    );
#else
    rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
#endif
    assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
    pPager->journalOff = 0;
    pPager->setMaster = 0;
    pPager->journalHdr = 0;
    if( rc!=SQLITE_OK ){
      if( rc==SQLITE_NOMEM ){
        sqlite3OsDelete(pVfs, pPager->zJournal, 0);
      }
      goto failed_to_open_journal;
    }
  }
  pPager->journalOpen = 1;
  pPager->journalStarted = 0;
  pPager->needSync = 0;
  pPager->alwaysRollback = 0;
  pPager->nRec = 0;
  if( pPager->errCode ){
................................................................................
      }
      if( rc!=SQLITE_OK ){
        pagerLeave(pPager);
        return rc;
      }
      pPager->dirtyCache = 0;
      PAGERTRACE2("TRANSACTION %d\n", PAGERID(pPager));
      if( pPager->useJournal && !pPager->tempFile
             && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
        rc = pager_open_journal(pPager);
      }
    }
  }else if( pPager->journalOpen && pPager->journalOff==0 ){
    /* This happens when the pager was in exclusive-access mode last
    ** time a (read or write) transaction was successfully concluded
    ** by this connection. Instead of deleting the journal file it was 
................................................................................
    */
    assert( pPager->state!=PAGER_UNLOCK );
    rc = sqlite3PagerBegin(pPg, 0);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    assert( pPager->state>=PAGER_RESERVED );
    if( !pPager->journalOpen && pPager->useJournal
          && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
      rc = pager_open_journal(pPager);
      if( rc!=SQLITE_OK ) return rc;
    }

    pPager->dirtyCache = 1;
  
    /* The transaction journal now exists and we have a RESERVED or an
    ** EXCLUSIVE lock on the main database file.  Write the current page to
    ** the transaction journal if it is not there already.
    */
    if( !pPg->inJournal && (pPager->journalOpen || MEMDB) ){
      if( (int)pPg->pgno <= pPager->origDbSize ){
        if( MEMDB ){
          PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
          PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
          assert( pHist->pOrig==0 );
          pHist->pOrig = sqlite3_malloc( pPager->pageSize );
          if( !pHist->pOrig ){
................................................................................
** The returned value is either PAGER_JOURNALMODE_DELETE or
** PAGER_JOURNALMODE_PERSIST, indicating the current (possibly updated)
** journal-mode.
*/
int sqlite3PagerJournalMode(Pager *pPager, int eMode){
  assert( eMode==PAGER_JOURNALMODE_QUERY
            || eMode==PAGER_JOURNALMODE_DELETE
            || eMode==PAGER_JOURNALMODE_PERSIST
            || eMode==PAGER_JOURNALMODE_OFF );
  assert( PAGER_JOURNALMODE_QUERY<0 );
  assert( PAGER_JOURNALMODE_DELETE>=0 && PAGER_JOURNALMODE_PERSIST>=0 );
  if( eMode>=0 ){

    pPager->journalMode = eMode;
  }
  return (int)pPager->journalMode;
}

#ifdef SQLITE_TEST
/*
** Print a listing of all referenced pages and their ref count.
*/
void sqlite3PagerRefdump(Pager *pPager){

Changes to src/parse.y.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
928
929
930
931
932
933
934
935
936

937
938
939
940
941
942
943
**
*************************************************************************
** 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.242 2008/03/29 12:50:33 rse Exp $
*/

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.
................................................................................
cmd ::= VACUUM nm.             {sqlite3Vacuum(pParse);}
%endif  SQLITE_OMIT_ATTACH
%endif  SQLITE_OMIT_VACUUM

///////////////////////////// The PRAGMA command /////////////////////////////
//
%ifndef SQLITE_OMIT_PRAGMA
cmd ::= PRAGMA nm(X) dbnm(Z) EQ nmnum(Y).  {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) EQ ON(Y).  {sqlite3Pragma(pParse,&X,&Z,&Y,0);}

cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y). {
  sqlite3Pragma(pParse,&X,&Z,&Y,1);
}
cmd ::= PRAGMA nm(X) dbnm(Z) LP nmnum(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z).             {sqlite3Pragma(pParse,&X,&Z,0,0);}
nmnum(A) ::= plus_num(X).             {A = X;}
nmnum(A) ::= nm(X).                   {A = X;}







|







 







|
|
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
**
*************************************************************************
** 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.243 2008/04/17 20:59:38 drh Exp $
*/

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.
................................................................................
cmd ::= VACUUM nm.             {sqlite3Vacuum(pParse);}
%endif  SQLITE_OMIT_ATTACH
%endif  SQLITE_OMIT_VACUUM

///////////////////////////// The PRAGMA command /////////////////////////////
//
%ifndef SQLITE_OMIT_PRAGMA
cmd ::= PRAGMA nm(X) dbnm(Z) EQ nmnum(Y).   {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) EQ ON(Y).      {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) EQ DELETE(Y).  {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y). {
  sqlite3Pragma(pParse,&X,&Z,&Y,1);
}
cmd ::= PRAGMA nm(X) dbnm(Z) LP nmnum(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z).             {sqlite3Pragma(pParse,&X,&Z,0,0);}
nmnum(A) ::= plus_num(X).             {A = X;}
nmnum(A) ::= nm(X).                   {A = X;}

Changes to src/pragma.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
457
458
459
460
461
462
463
464

465
466

467
468
469
470
471
472
473
**    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 PRAGMA command.
**
** $Id: pragma.c,v 1.175 2008/04/17 17:02:02 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)
................................................................................
        **
        ** Also, the sqlite3.dfltJournalMode variable is set so that
        ** any subsequently attached databases also use the specified
        ** journal mode.
        */
        int ii;
        assert(pDb==&db->aDb[0]);
        for(ii=2; ii<db->nDb; ii++){

          pPager = sqlite3BtreePager(db->aDb[ii].pBt);
          sqlite3PagerJournalMode(pPager, eMode);

        }
        db->dfltJournalMode = eMode;
      }
      pPager = sqlite3BtreePager(pDb->pBt);
      eMode = sqlite3PagerJournalMode(pPager, eMode);
    }
    assert( eMode==PAGER_JOURNALMODE_DELETE







|







 







|
>
|
|
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
**    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 PRAGMA command.
**
** $Id: pragma.c,v 1.176 2008/04/17 20:59:38 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)
................................................................................
        **
        ** Also, the sqlite3.dfltJournalMode variable is set so that
        ** any subsequently attached databases also use the specified
        ** journal mode.
        */
        int ii;
        assert(pDb==&db->aDb[0]);
        for(ii=1; ii<db->nDb; ii++){
          if( db->aDb[ii].pBt ){
            pPager = sqlite3BtreePager(db->aDb[ii].pBt);
            sqlite3PagerJournalMode(pPager, eMode);
          }
        }
        db->dfltJournalMode = eMode;
      }
      pPager = sqlite3BtreePager(pDb->pBt);
      eMode = sqlite3PagerJournalMode(pPager, eMode);
    }
    assert( eMode==PAGER_JOURNALMODE_DELETE