SQLite

Check-in [600cefdd4d]
Login

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

Overview
Comment:Add SQLITE_ENABLE_OTA pre-processor directives so that this branch may be compiled with or without OTA.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | ota-update
Files: files | file ages | folders
SHA1: 600cefdd4d29c1de4d107fa7ddeb76a18edce4f5
User & Date: dan 2014-11-22 09:09:50.320
Context
2014-11-27
18:09
Update ota so that the hidden columns of virtual tables may be written. (check-in: ccee999649 user: dan tags: ota-update)
2014-11-22
09:09
Add SQLITE_ENABLE_OTA pre-processor directives so that this branch may be compiled with or without OTA. (check-in: 600cefdd4d user: dan tags: ota-update)
2014-11-21
14:37
Merge latest trunk changes with this branch. (check-in: 7ef44c5b5b user: dan tags: ota-update)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/ota/sqlite3ota.c.
13
14
15
16
17
18
19


20
21
22
23
24
25
26

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#include "sqlite3.h"


#include "sqlite3ota.h"


/*
** The ota_state table is used to save the state of a partially applied
** update so that it can be resumed later. The table consists of integer
** keys mapped to values as follows:







>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#include "sqlite3.h"

#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_OTA)
#include "sqlite3ota.h"


/*
** The ota_state table is used to save the state of a partially applied
** update so that it can be resumed later. The table consists of integer
** keys mapped to values as follows:
1657
1658
1659
1660
1661
1662
1663

1664
1665
1666
1667
1668
1669
1670






1671
1672
1673
  zOta = Tcl_GetString(objv[3]);

  pOta = sqlite3ota_open(zTarget, zOta);
  Tcl_CreateObjCommand(interp, zCmd, test_sqlite3ota_cmd, (ClientData)pOta, 0);
  Tcl_SetObjResult(interp, objv[1]);
  return TCL_OK;
}


int SqliteOta_Init(Tcl_Interp *interp){ 
  Tcl_CreateObjCommand(interp, "sqlite3ota", test_sqlite3ota, 0, 0);
  return TCL_OK;
}

#endif                  /* ifdef SQLITE_TEST */
















>





<

>
>
>
>
>
>



1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671

1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
  zOta = Tcl_GetString(objv[3]);

  pOta = sqlite3ota_open(zTarget, zOta);
  Tcl_CreateObjCommand(interp, zCmd, test_sqlite3ota_cmd, (ClientData)pOta, 0);
  Tcl_SetObjResult(interp, objv[1]);
  return TCL_OK;
}


int SqliteOta_Init(Tcl_Interp *interp){ 
  Tcl_CreateObjCommand(interp, "sqlite3ota", test_sqlite3ota, 0, 0);
  return TCL_OK;
}

#endif                  /* ifdef SQLITE_TEST */
#else   /* !SQLITE_CORE || SQLITE_ENABLE_OTA */
# ifdef SQLITE_TEST
#include <tcl.h>
int SqliteOta_Init(Tcl_Interp *interp){ return TCL_OK; }
# endif
#endif 



Changes to src/main.c.
1956
1957
1958
1959
1960
1961
1962

1963
1964
1965
1966
1967
1968
1969
  }
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
#endif
}


/*
** Open an incremental checkpoint handle.
*/
int sqlite3_ckpt_open(
  sqlite3 *db, 
  unsigned char *a, int n, 
  sqlite3_ckpt **ppCkpt







>







1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
  }
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
#endif
}

#ifdef SQLITE_ENABLE_OTA
/*
** Open an incremental checkpoint handle.
*/
int sqlite3_ckpt_open(
  sqlite3 *db, 
  unsigned char *a, int n, 
  sqlite3_ckpt **ppCkpt
1980
1981
1982
1983
1984
1985
1986

1987
1988
1989
1990
1991
1992
1993
    pPager = sqlite3BtreePager(db->aDb[0].pBt);
  }

  rc = sqlite3PagerWalCheckpointStart(db, pPager, a, n, ppCkpt);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}



/*
** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points
** to contains a zero-length string, all attached databases are 
** checkpointed.
*/







>







1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
    pPager = sqlite3BtreePager(db->aDb[0].pBt);
  }

  rc = sqlite3PagerWalCheckpointStart(db, pPager, a, n, ppCkpt);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}
#endif /* SQLITE_ENABLE_OTA */


/*
** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points
** to contains a zero-length string, all attached databases are 
** checkpointed.
*/
Changes to src/pager.c.
638
639
640
641
642
643
644

645

646
647
648
649
650
651
652
  u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
  u8 walSyncFlags;            /* SYNC_NORMAL or SYNC_FULL for wal writes */
  u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
  u8 tempFile;                /* zFilename is a temporary or immutable file */
  u8 noLock;                  /* Do not lock (except in WAL mode) */
  u8 readOnly;                /* True for a read-only database */
  u8 memDb;                   /* True to inhibit all file I/O */

  u8 otaMode;                 /* Non-zero if in ota_mode */


  /**************************************************************************
  ** The following block contains those class members that change during
  ** routine operation.  Class members not in this block are either fixed
  ** when the pager is first created or else only change when there is a
  ** significant mode change (such as changing the page_size, locking_mode,
  ** or the journal_mode).  From another view, these class members describe







>

>







638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
  u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
  u8 walSyncFlags;            /* SYNC_NORMAL or SYNC_FULL for wal writes */
  u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
  u8 tempFile;                /* zFilename is a temporary or immutable file */
  u8 noLock;                  /* Do not lock (except in WAL mode) */
  u8 readOnly;                /* True for a read-only database */
  u8 memDb;                   /* True to inhibit all file I/O */
#ifdef SQLITE_ENABLE_OTA
  u8 otaMode;                 /* Non-zero if in ota_mode */
#endif

  /**************************************************************************
  ** The following block contains those class members that change during
  ** routine operation.  Class members not in this block are either fixed
  ** when the pager is first created or else only change when there is a
  ** significant mode change (such as changing the page_size, locking_mode,
  ** or the journal_mode).  From another view, these class members describe
712
713
714
715
716
717
718










719
720
721
722
723
724
725
  PCache *pPCache;            /* Pointer to page cache object */
#ifndef SQLITE_OMIT_WAL
  Wal *pWal;                  /* Write-ahead log used by "journal_mode=wal" */
  char *zWal;                 /* File name for write-ahead log */
#endif
};











/*
** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains
** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS 
** or CACHE_WRITE to sqlite3_db_status().
*/
#define PAGER_STAT_HIT   0
#define PAGER_STAT_MISS  1







>
>
>
>
>
>
>
>
>
>







714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
  PCache *pPCache;            /* Pointer to page cache object */
#ifndef SQLITE_OMIT_WAL
  Wal *pWal;                  /* Write-ahead log used by "journal_mode=wal" */
  char *zWal;                 /* File name for write-ahead log */
#endif
};

/*
** Return the value of the pager otaMode flag (0, 1 or 2). Or, if
** SQLITE_ENABLE_OTA is not defined, return constant value 0.
*/
#ifdef SQLITE_ENABLE_OTA
# define PagerOtaMode(pPager) ((pPager)->otaMode)
#else
# define PagerOtaMode(pPager) 0
#endif

/*
** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains
** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS 
** or CACHE_WRITE to sqlite3_db_status().
*/
#define PAGER_STAT_HIT   0
#define PAGER_STAT_MISS  1
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
  }

  if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){
    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0);
    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
  }

  if( !pPager->exclusiveMode && !pPager->otaMode
   && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
  ){
    rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
    pPager->changeCountDone = 0;
  }
  pPager->eState = PAGER_READER;
  pPager->setMaster = 0;







|







2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
  }

  if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){
    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0);
    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
  }

  if( !pPager->exclusiveMode && !PagerOtaMode(pPager)
   && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
  ){
    rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
    pPager->changeCountDone = 0;
  }
  pPager->eState = PAGER_READER;
  pPager->setMaster = 0;
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
  disable_simulated_io_errors();
  sqlite3BeginBenignMalloc();
  pagerFreeMapHdrs(pPager);
  /* pPager->errCode = 0; */
  pPager->exclusiveMode = 0;
#ifndef SQLITE_OMIT_WAL
  sqlite3WalClose(pPager->pWal, 
      pPager->ckptSyncFlags, pPager->pageSize, (pPager->otaMode?0:pTmp)
  );
  pPager->pWal = 0;
#endif
  pager_reset(pPager);
  if( MEMDB ){
    pager_unlock(pPager);
  }else{







|







3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
  disable_simulated_io_errors();
  sqlite3BeginBenignMalloc();
  pagerFreeMapHdrs(pPager);
  /* pPager->errCode = 0; */
  pPager->exclusiveMode = 0;
#ifndef SQLITE_OMIT_WAL
  sqlite3WalClose(pPager->pWal, 
      pPager->ckptSyncFlags, pPager->pageSize, (PagerOtaMode(pPager)?0:pTmp)
  );
  pPager->pWal = 0;
#endif
  pager_reset(pPager);
  if( MEMDB ){
    pager_unlock(pPager);
  }else{
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213

5214

5215
5216
5217
5218
5219
5220
5221
      }
    }

    /* If there is a WAL file in the file-system, open this database in WAL
    ** mode. Otherwise, the following function call is a no-op.
    */
    rc = pagerOpenWalIfPresent(pPager);
    if( rc==SQLITE_OK && pPager->otaMode ){
      int nWal = sqlite3Strlen30(pPager->zWal);
      pPager->zWal[nWal-3] = 'o';
      rc = pagerOpenWalInternal(pPager, 0);
    }

#ifndef SQLITE_OMIT_WAL
    assert( pPager->pWal==0 || rc==SQLITE_OK );
#endif
  }

  if( pagerUseWal(pPager) ){
    assert( rc==SQLITE_OK );
    rc = pagerBeginReadTransaction(pPager);
    if( rc==SQLITE_OK && pPager->otaMode==1 ){
      rc = sqlite3WalCheckSalt(pPager->pWal, pPager->fd);
      if( rc!=SQLITE_OK ){
        sqlite3WalClose(pPager->pWal, 0, 0, 0);
        pPager->pWal = 0;
      }else{

        pPager->otaMode = 2;

      }
    }
  }

  if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
    rc = pagerPagecount(pPager, &pPager->dbSize);
  }







|













|





>

>







5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
      }
    }

    /* If there is a WAL file in the file-system, open this database in WAL
    ** mode. Otherwise, the following function call is a no-op.
    */
    rc = pagerOpenWalIfPresent(pPager);
    if( rc==SQLITE_OK && PagerOtaMode(pPager) ){
      int nWal = sqlite3Strlen30(pPager->zWal);
      pPager->zWal[nWal-3] = 'o';
      rc = pagerOpenWalInternal(pPager, 0);
    }

#ifndef SQLITE_OMIT_WAL
    assert( pPager->pWal==0 || rc==SQLITE_OK );
#endif
  }

  if( pagerUseWal(pPager) ){
    assert( rc==SQLITE_OK );
    rc = pagerBeginReadTransaction(pPager);
    if( rc==SQLITE_OK && PagerOtaMode(pPager)==1 ){
      rc = sqlite3WalCheckSalt(pPager->pWal, pPager->fd);
      if( rc!=SQLITE_OK ){
        sqlite3WalClose(pPager->pWal, 0, 0, 0);
        pPager->pWal = 0;
      }else{
#ifdef SQLITE_ENABLE_OTA
        pPager->otaMode = 2;
#endif
      }
    }
  }

  if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
    rc = pagerPagecount(pPager, &pPager->dbSize);
  }
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
** or wal_blocking_checkpoint() API functions.
**
** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
*/
int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
  int rc = SQLITE_OK;
  if( pPager->pWal && pPager->otaMode==0 ){
    rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
        pPager->xBusyHandler, pPager->pBusyHandlerArg,
        pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
        pnLog, pnCkpt
    );
  }
  return rc;







|







7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
** or wal_blocking_checkpoint() API functions.
**
** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
*/
int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
  int rc = SQLITE_OK;
  if( pPager->pWal && PagerOtaMode(pPager)==0 ){
    rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
        pPager->xBusyHandler, pPager->pBusyHandlerArg,
        pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
        pnLog, pnCkpt
    );
  }
  return rc;
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183








7184
7185
7186
7187
7188
7189
7190
  }

  /* Open the connection to the log file. If this operation fails, 
  ** (e.g. due to malloc() failure), return an error code.
  */
  if( rc==SQLITE_OK ){
    rc = sqlite3WalOpen(pPager->pVfs,
        pPager->fd, pPager->zWal, pPager->exclusiveMode || pPager->otaMode,
        pPager->journalSizeLimit, &pPager->pWal
    );
  }
  pagerFixMaplimit(pPager);

  return rc;
}









static int pagerOpenWalInternal(
  Pager *pPager,                  /* Pager object */
  int *pbOpen                     /* OUT: Set to true if call is a no-op */
){
  int rc = SQLITE_OK;             /* Return code */

  assert( assert_pager_state(pPager) );







|








>
>
>
>
>
>
>
>







7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
  }

  /* Open the connection to the log file. If this operation fails, 
  ** (e.g. due to malloc() failure), return an error code.
  */
  if( rc==SQLITE_OK ){
    rc = sqlite3WalOpen(pPager->pVfs,
        pPager->fd, pPager->zWal, pPager->exclusiveMode || PagerOtaMode(pPager),
        pPager->journalSizeLimit, &pPager->pWal
    );
  }
  pagerFixMaplimit(pPager);

  return rc;
}

/*
** Open the WAL file if it is not open. If it is already open, set *pbOpen
** to 1 before returning. Return SQLITE_OK if successful, or an SQLite error
** code otherwise.
**
** The difference between this function and sqlite3PagerOpenWal() is that
** PagerOpenWal() does not open the WAL file if the pager is in OTA mode.
*/
static int pagerOpenWalInternal(
  Pager *pPager,                  /* Pager object */
  int *pbOpen                     /* OUT: Set to true if call is a no-op */
){
  int rc = SQLITE_OK;             /* Return code */

  assert( assert_pager_state(pPager) );
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK
** without doing anything.
*/
int sqlite3PagerOpenWal(
  Pager *pPager,                  /* Pager object */
  int *pbOpen                     /* OUT: Set to true if call is a no-op */
){
  if( pPager->otaMode ) return SQLITE_CANTOPEN;
  return pagerOpenWalInternal(pPager, pbOpen);
}

/*
** This function is called to close the connection to the log file prior
** to switching from WAL to rollback mode.
**







|







7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK
** without doing anything.
*/
int sqlite3PagerOpenWal(
  Pager *pPager,                  /* Pager object */
  int *pbOpen                     /* OUT: Set to true if call is a no-op */
){
  if( PagerOtaMode(pPager) ) return SQLITE_CANTOPEN_BKPT;
  return pagerOpenWalInternal(pPager, pbOpen);
}

/*
** This function is called to close the connection to the log file prior
** to switching from WAL to rollback mode.
**
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
/*
** This function is called by the wal.c module to obtain the 8 bytes of 
** "salt" written into the wal file header. In OTA mode, this is a copy
** of bytes 24-31 of the database file. In non-OTA mode, it is 8 bytes
** of pseudo-random data.
*/
void sqlite3PagerWalSalt(Pager *pPager, u32 *aSalt){
  if( pPager->otaMode ){
    memcpy(aSalt, pPager->dbFileVers, 8);
  }else{
    sqlite3_randomness(8, aSalt);
  }
}

#endif /* !SQLITE_OMIT_WAL */







|







7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
/*
** This function is called by the wal.c module to obtain the 8 bytes of 
** "salt" written into the wal file header. In OTA mode, this is a copy
** of bytes 24-31 of the database file. In non-OTA mode, it is 8 bytes
** of pseudo-random data.
*/
void sqlite3PagerWalSalt(Pager *pPager, u32 *aSalt){
  if( PagerOtaMode(pPager) ){
    memcpy(aSalt, pPager->dbFileVers, 8);
  }else{
    sqlite3_randomness(8, aSalt);
  }
}

#endif /* !SQLITE_OMIT_WAL */
7306
7307
7308
7309
7310
7311
7312

7313
7314
7315
7316
7317
7318
7319
*/
int sqlite3PagerWalFramesize(Pager *pPager){
  assert( pPager->eState>=PAGER_READER );
  return sqlite3WalFramesize(pPager->pWal);
}
#endif


/*
** Set or clear the "OTA mode" flag.
*/
int sqlite3PagerSetOtaMode(Pager *pPager, int iOta){
  assert( iOta==1 || iOta==2 );
  if( iOta==1 && (pPager->pWal || pPager->eState!=PAGER_OPEN) ){
    return SQLITE_ERROR;







>







7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
*/
int sqlite3PagerWalFramesize(Pager *pPager){
  assert( pPager->eState>=PAGER_READER );
  return sqlite3WalFramesize(pPager->pWal);
}
#endif

#ifdef SQLITE_ENABLE_OTA
/*
** Set or clear the "OTA mode" flag.
*/
int sqlite3PagerSetOtaMode(Pager *pPager, int iOta){
  assert( iOta==1 || iOta==2 );
  if( iOta==1 && (pPager->pWal || pPager->eState!=PAGER_OPEN) ){
    return SQLITE_ERROR;
7337
7338
7339
7340
7341
7342
7343

7344
7345
  }else{
    return sqlite3WalCheckpointStart(db, pPager->pWal, a, n,
        pPager->xBusyHandler, pPager->pBusyHandlerArg,
        pPager->ckptSyncFlags, ppCkpt
    );
  }
}


#endif /* SQLITE_OMIT_DISKIO */







>


7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
  }else{
    return sqlite3WalCheckpointStart(db, pPager->pWal, a, n,
        pPager->xBusyHandler, pPager->pBusyHandlerArg,
        pPager->ckptSyncFlags, ppCkpt
    );
  }
}
#endif /* !SQLITE_ENABLE_OTA */

#endif /* SQLITE_OMIT_DISKIO */
Changes to src/pragma.c.
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
    /* ePragFlag: */ PragFlag_NeedSchema,
    /* iArg:      */ 0 },
  { /* zName:     */ "mmap_size",
    /* ePragTyp:  */ PragTyp_MMAP_SIZE,
    /* ePragFlag: */ 0,
    /* iArg:      */ 0 },
#endif

  { /* zName:     */ "ota_mode",
    /* ePragTyp:  */ PragTyp_FLAG,
    /* ePragFlag: */ 0,
    /* iArg:      */ SQLITE_OtaMode },

#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
  { /* zName:     */ "page_count",
    /* ePragTyp:  */ PragTyp_PAGE_COUNT,
    /* ePragFlag: */ PragFlag_NeedSchema,
    /* iArg:      */ 0 },
  { /* zName:     */ "page_size",
    /* ePragTyp:  */ PragTyp_PAGE_SIZE,
    /* ePragFlag: */ 0,
    /* iArg:      */ 0 },
#endif

  { /* zName:     */ "pager_ota_mode",
    /* ePragTyp:  */ PragTyp_PAGER_OTA_MODE,
    /* ePragFlag: */ 0,
    /* iArg:      */ 0 },

#if defined(SQLITE_DEBUG)
  { /* zName:     */ "parser_trace",
    /* ePragTyp:  */ PragTyp_PARSER_TRACE,
    /* ePragFlag: */ 0,
    /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)







>




>










>




>







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
    /* ePragFlag: */ PragFlag_NeedSchema,
    /* iArg:      */ 0 },
  { /* zName:     */ "mmap_size",
    /* ePragTyp:  */ PragTyp_MMAP_SIZE,
    /* ePragFlag: */ 0,
    /* iArg:      */ 0 },
#endif
#if defined(SQLITE_ENABLE_OTA)
  { /* zName:     */ "ota_mode",
    /* ePragTyp:  */ PragTyp_FLAG,
    /* ePragFlag: */ 0,
    /* iArg:      */ SQLITE_OtaMode },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
  { /* zName:     */ "page_count",
    /* ePragTyp:  */ PragTyp_PAGE_COUNT,
    /* ePragFlag: */ PragFlag_NeedSchema,
    /* iArg:      */ 0 },
  { /* zName:     */ "page_size",
    /* ePragTyp:  */ PragTyp_PAGE_SIZE,
    /* ePragFlag: */ 0,
    /* iArg:      */ 0 },
#endif
#if defined(SQLITE_ENABLE_OTA)
  { /* zName:     */ "pager_ota_mode",
    /* ePragTyp:  */ PragTyp_PAGER_OTA_MODE,
    /* ePragFlag: */ 0,
    /* iArg:      */ 0 },
#endif
#if defined(SQLITE_DEBUG)
  { /* zName:     */ "parser_trace",
    /* ePragTyp:  */ PragTyp_PARSER_TRACE,
    /* ePragFlag: */ 0,
    /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  { /* zName:     */ "writable_schema",
    /* ePragTyp:  */ PragTyp_FLAG,
    /* ePragFlag: */ 0,
    /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
#endif
};
/* Number of pragmas: 59 on by default, 72 total. */
/* End of the automatically generated pragma table.
***************************************************************************/

/*
** Interpret the given string as a safety level.  Return 0 for OFF,
** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or 
** unrecognized string argument.  The FULL option is disallowed







|







481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  { /* zName:     */ "writable_schema",
    /* ePragTyp:  */ PragTyp_FLAG,
    /* ePragFlag: */ 0,
    /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
#endif
};
/* Number of pragmas: 57 on by default, 72 total. */
/* End of the automatically generated pragma table.
***************************************************************************/

/*
** Interpret the given string as a safety level.  Return 0 for OFF,
** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or 
** unrecognized string argument.  The FULL option is disallowed
892
893
894
895
896
897
898

899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918

919
920
921
922
923
924
925
  ** heap-memory. If the *-oal file already exists but the database file has
  ** been modified since it was created, an SQLITE_BUSY_SNAPSHOT error is
  ** returned and the read-transaction cannot be opened.
  **
  ** Other clients see a rollback-mode database on which the pager_ota_mode
  ** client is holding a SHARED lock.
  */

  case PragTyp_PAGER_OTA_MODE: {
    Btree *pBt = pDb->pBt;
    assert( pBt!=0 );
    if( zRight ){
      int iArg = sqlite3Atoi(zRight);
      Pager *pPager = sqlite3BtreePager(pBt);
      if( sqlite3BtreeIsInReadTrans(pBt) ){
        sqlite3ErrorMsg(pParse, 
            "cannot set pager_ota_mode with open transaction"
        );
      }else if( sqlite3PagerWalSupported(pPager)==0 ){
        sqlite3ErrorMsg(pParse,
            "cannot set pager_ota_mode without wal support"
        );
      }else if( sqlite3PagerSetOtaMode(sqlite3BtreePager(pBt), iArg) ){
        sqlite3ErrorMsg(pParse, "cannot set pager_ota_mode in wal mode");
      }
    }
    break;
  }


#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
  /*
  **  PRAGMA [database.]page_size
  **  PRAGMA [database.]page_size=N
  **
  ** The first form reports the current setting for the







>




















>







896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
  ** heap-memory. If the *-oal file already exists but the database file has
  ** been modified since it was created, an SQLITE_BUSY_SNAPSHOT error is
  ** returned and the read-transaction cannot be opened.
  **
  ** Other clients see a rollback-mode database on which the pager_ota_mode
  ** client is holding a SHARED lock.
  */
#ifdef SQLITE_ENABLE_OTA
  case PragTyp_PAGER_OTA_MODE: {
    Btree *pBt = pDb->pBt;
    assert( pBt!=0 );
    if( zRight ){
      int iArg = sqlite3Atoi(zRight);
      Pager *pPager = sqlite3BtreePager(pBt);
      if( sqlite3BtreeIsInReadTrans(pBt) ){
        sqlite3ErrorMsg(pParse, 
            "cannot set pager_ota_mode with open transaction"
        );
      }else if( sqlite3PagerWalSupported(pPager)==0 ){
        sqlite3ErrorMsg(pParse,
            "cannot set pager_ota_mode without wal support"
        );
      }else if( sqlite3PagerSetOtaMode(sqlite3BtreePager(pBt), iArg) ){
        sqlite3ErrorMsg(pParse, "cannot set pager_ota_mode in wal mode");
      }
    }
    break;
  }
#endif /* SQLITE_ENABLE_OTA */

#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
  /*
  **  PRAGMA [database.]page_size
  **  PRAGMA [database.]page_size=N
  **
  ** The first form reports the current setting for the
Changes to src/sqlite.h.in.
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
*/
#define SQLITE_ROLLBACK 1
/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
#define SQLITE_FAIL     3
/* #define SQLITE_ABORT 4  // Also an error code */
#define SQLITE_REPLACE  5

/*
** Allocate a statement handle that may be used to write directly to an
** index b-tree. This allows the user to create a corrupt database. Once
** the statement handle is allocated, it may be used with the same APIs
** as any statement handle created with sqlite3_prepare().
**
** The statement writes to the index specified by parameter zIndex, which
** must be in the "main" database. If argument bDelete is false, then each
** time the statement is sqlite3_step()ed, an entry is inserted into the
** b-tree index. If it is true, then an entry may be deleted (or may not, if 
** the specified key is not found) each time the statement is 
** sqlite3_step()ed.
**
** If statement compilation is successful, *ppStmt is set to point to the 
** new statement handle and SQLITE_OK is returned. Otherwise, if an error
** occurs, *ppStmt is set to NULL and an error code returned. An error
** message may be left in the database handle in this case.
**
** If statement compilation succeeds, output variable *pnCol is set to the
** total number of columns in the index, including the primary key columns
** at the end. Variable *paiCol is set to point to an array *pnCol entries 
** in size. Each entry is the table column index, numbered from zero from left 
** to right, of the corresponding index column. For example, if:
**
**       CREATE TABLE t1(a, b, c, d);
**       CREATE INDEX i1 ON t1(b, c);
**
** then *pnCol is 3 and *paiCol points to an array containing {1, 2, -1}.
** If table t1 had an explicit INTEGER PRIMARY KEY, then the "-1" in the
** *paiCol array would be replaced by its column index. Or if:
**
**       CREATE TABLE t2(a, b, c, d, PRIMARY KEY(d, c)) WITHOUT ROWID;
**       CREATE INDEX i2 ON t2(a);
**
** then (*pnCol) is 3 and *paiCol points to an array containing {0, 3, 2}.
**
** The lifetime of the array is the same as that of the statement handle -
** it is automatically freed when the statement handle is passed to
** sqlite3_finalize().
**
** The statement has (*pnCol) SQL variables that values may be bound to.
** They correspond to the values used to create the index key that is
** inserted or deleted when the statement is stepped.
**
** If the index is a UNIQUE index, the usual checking and error codes apply
** to insert operations.
*/
int sqlite3_index_writer(
  sqlite3 *db, 
  int bDelete,                    /* Zero for insert, non-zero for delete */
  const char *zIndex,             /* Index to write to */
  sqlite3_stmt**,                 /* OUT: New statement handle */
  const char ***pazColl,          /* OUT: Collation sequences for each column */
  int **paiCol, int *pnCol        /* OUT: See above */
);

/*
** CAPI3REF: Prepared Statement Scan Status Opcodes
** KEYWORDS: {scanstatus options}
**
** The following constants can be used for the T parameter to the
** [sqlite3_stmt_scanstatus(S,X,T,V)] interface.  Each constant designates a
** different metric for sqlite3_stmt_scanstatus() to return.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







7441
7442
7443
7444
7445
7446
7447
























































7448
7449
7450
7451
7452
7453
7454
*/
#define SQLITE_ROLLBACK 1
/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
#define SQLITE_FAIL     3
/* #define SQLITE_ABORT 4  // Also an error code */
#define SQLITE_REPLACE  5

























































/*
** CAPI3REF: Prepared Statement Scan Status Opcodes
** KEYWORDS: {scanstatus options}
**
** The following constants can be used for the T parameter to the
** [sqlite3_stmt_scanstatus(S,X,T,V)] interface.  Each constant designates a
** different metric for sqlite3_stmt_scanstatus() to return.
7590
7591
7592
7593
7594
7595
7596




























































7597
7598
7599
7600
7601
7602
7603
** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
**
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);





























































/*
** Incremental checkpoint API.
**
** An incremental checkpoint handle is opened using the sqlite3_ckpt_open()
** API. To begin a new checkpoint, the second and third arguments should both
** be passed zero. To resume an earlier checkpoint, the second and third
** arguments should specify a buffer returned by an earlier call to







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







7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
**
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);

/*
** Allocate a statement handle that may be used to write directly to an
** index b-tree. This allows the user to create a corrupt database. Once
** the statement handle is allocated, it may be used with the same APIs
** as any statement handle created with sqlite3_prepare().
**
** The statement writes to the index specified by parameter zIndex, which
** must be in the "main" database. If argument bDelete is false, then each
** time the statement is sqlite3_step()ed, an entry is inserted into the
** b-tree index. If it is true, then an entry may be deleted (or may not, if 
** the specified key is not found) each time the statement is 
** sqlite3_step()ed.
**
** If statement compilation is successful, *ppStmt is set to point to the 
** new statement handle and SQLITE_OK is returned. Otherwise, if an error
** occurs, *ppStmt is set to NULL and an error code returned. An error
** message may be left in the database handle in this case.
**
** If statement compilation succeeds, output variable *pnCol is set to the
** total number of columns in the index, including the primary key columns
** at the end. Variable *paiCol is set to point to an array *pnCol entries 
** in size. Each entry is the table column index, numbered from zero from left 
** to right, of the corresponding index column. For example, if:
**
**       CREATE TABLE t1(a, b, c, d);
**       CREATE INDEX i1 ON t1(b, c);
**
** then *pnCol is 3 and *paiCol points to an array containing {1, 2, -1}.
** If table t1 had an explicit INTEGER PRIMARY KEY, then the "-1" in the
** *paiCol array would be replaced by its column index. Or if:
**
**       CREATE TABLE t2(a, b, c, d, PRIMARY KEY(d, c)) WITHOUT ROWID;
**       CREATE INDEX i2 ON t2(a);
**
** then (*pnCol) is 3 and *paiCol points to an array containing {0, 3, 2}.
**
** The lifetime of the array is the same as that of the statement handle -
** it is automatically freed when the statement handle is passed to
** sqlite3_finalize().
**
** The statement has (*pnCol) SQL variables that values may be bound to.
** They correspond to the values used to create the index key that is
** inserted or deleted when the statement is stepped.
**
** If the index is a UNIQUE index, the usual checking and error codes apply
** to insert operations.
**
** This API is only available if SQLITE_ENABLE_OTA is defined at compile
** time. It is intended for use by the OTA extension only. As such, it is 
** subject to change or removal at any point.
*/
int sqlite3_index_writer(
  sqlite3 *db, 
  int bDelete,                    /* Zero for insert, non-zero for delete */
  const char *zIndex,             /* Index to write to */
  sqlite3_stmt**,                 /* OUT: New statement handle */
  const char ***pazColl,          /* OUT: Collation sequence for each column */
  int **paiCol, int *pnCol        /* OUT: See above */
);

/*
** Incremental checkpoint API.
**
** An incremental checkpoint handle is opened using the sqlite3_ckpt_open()
** API. To begin a new checkpoint, the second and third arguments should both
** be passed zero. To resume an earlier checkpoint, the second and third
** arguments should specify a buffer returned by an earlier call to
7618
7619
7620
7621
7622
7623
7624




7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
** error code is returned and the two output parameters are zeroed. Finally,
** if the checkpoint is not finished but no error has occurred, SQLITE_OK is
** returned and the first output variable set to point to a buffer allocated 
** using sqlite3_malloc() containing the serialized state of the checkpoint. 
** The contents of this buffer may be passed to a later call to
** sqlite3_ckpt_open() to restart the checkpoint. The second output variable 
** is set to the size of the buffer in bytes.




*/
typedef struct sqlite3_ckpt sqlite3_ckpt;
int sqlite3_ckpt_open(sqlite3*, unsigned char *a, int n, sqlite3_ckpt **ppCkpt);
int sqlite3_ckpt_step(sqlite3_ckpt*);
int sqlite3_ckpt_close(sqlite3_ckpt*, unsigned char **pa, int *pn);

/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/







>
>
>
>


|







7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
** error code is returned and the two output parameters are zeroed. Finally,
** if the checkpoint is not finished but no error has occurred, SQLITE_OK is
** returned and the first output variable set to point to a buffer allocated 
** using sqlite3_malloc() containing the serialized state of the checkpoint. 
** The contents of this buffer may be passed to a later call to
** sqlite3_ckpt_open() to restart the checkpoint. The second output variable 
** is set to the size of the buffer in bytes.
**
** These APIs are only available if SQLITE_ENABLE_OTA is defined at compile
** time. They are intended for use by the OTA extension only. As such, they 
** are subject to change or removal at any point.
*/
typedef struct sqlite3_ckpt sqlite3_ckpt;
int sqlite3_ckpt_open(sqlite3*, unsigned char*, int n, sqlite3_ckpt **ppCkpt);
int sqlite3_ckpt_step(sqlite3_ckpt*);
int sqlite3_ckpt_close(sqlite3_ckpt*, unsigned char **pa, int *pn);

/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
Changes to src/sqliteInt.h.
1192
1193
1194
1195
1196
1197
1198

1199
1200


1201
1202
1203
1204
1205
1206
1207
#define SQLITE_PreferBuiltin  0x00200000  /* Preference to built-in funcs */
#define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
#define SQLITE_EnableTrigger  0x00800000  /* True to enable triggers */
#define SQLITE_DeferFKs       0x01000000  /* Defer all FK constraints */
#define SQLITE_QueryOnly      0x02000000  /* Disable database changes */
#define SQLITE_VdbeEQP        0x04000000  /* Debug EXPLAIN QUERY PLAN */


#define SQLITE_OtaMode        0x08000000  /* True in "ota mode" */




/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
#define SQLITE_QueryFlattener 0x0001   /* Query flattening */







>
|
|
>
>







1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
#define SQLITE_PreferBuiltin  0x00200000  /* Preference to built-in funcs */
#define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
#define SQLITE_EnableTrigger  0x00800000  /* True to enable triggers */
#define SQLITE_DeferFKs       0x01000000  /* Defer all FK constraints */
#define SQLITE_QueryOnly      0x02000000  /* Disable database changes */
#define SQLITE_VdbeEQP        0x04000000  /* Debug EXPLAIN QUERY PLAN */

#ifdef SQLITE_ENABLE_OTA
# define SQLITE_OtaMode       0x08000000  /* True in "ota mode" */
#else
# define SQLITE_OtaMode       0x00000000
#endif

/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
#define SQLITE_QueryFlattener 0x0001   /* Query flattening */
Changes to src/test_config.c.
425
426
427
428
429
430
431






432
433
434
435
436
437
438
Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);

#ifdef SQLITE_OMIT_OR_OPTIMIZATION
  Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY);
#endif







#ifdef SQLITE_OMIT_PAGER_PRAGMAS
  Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "1", TCL_GLOBAL_ONLY);
#endif








>
>
>
>
>
>







425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);

#ifdef SQLITE_OMIT_OR_OPTIMIZATION
  Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_ENABLE_OTA
  Tcl_SetVar2(interp, "sqlite_options", "ota", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "ota", "0", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_PAGER_PRAGMAS
  Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "1", TCL_GLOBAL_ONLY);
#endif

Changes to src/trigger.c.
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
**
** If the SQLITE_OtaMode flag is set, do not include any non-temporary
** triggers in the returned list.
*/
Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
  Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
  Trigger *pList = 0;                  /* List of triggers to return */
  int bOta = !!(pParse->db->flags & SQLITE_OtaMode);

  if( pParse->disableTriggers ){
    return 0;
  }

  if( pTmpSchema!=pTab->pSchema ){
    HashElem *p;







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
**
** If the SQLITE_OtaMode flag is set, do not include any non-temporary
** triggers in the returned list.
*/
Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
  Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
  Trigger *pList = 0;                  /* List of triggers to return */
  const int bOta = !!(pParse->db->flags & SQLITE_OtaMode);

  if( pParse->disableTriggers ){
    return 0;
  }

  if( pTmpSchema!=pTab->pSchema ){
    HashElem *p;
Changes to src/vdbeblob.c.
463
464
465
466
467
468
469





470
471
472
473
474
475
476

  rc = sqlite3ApiExit(db, rc);
  assert( rc==SQLITE_OK || p->pStmt==0 );
  sqlite3_mutex_leave(db->mutex);
  return rc;
}






static int indexWriterOutputVars(
  sqlite3 *db,
  Index *pIdx,
  const char ***pazColl,          /* OUT: Array of collation sequences */
  int **paiCol,                   /* OUT: Array of column indexes */
  int *pnCol                      /* OUT: Total columns in index keys */
){







>
>
>
>
>







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

  rc = sqlite3ApiExit(db, rc);
  assert( rc==SQLITE_OK || p->pStmt==0 );
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

#ifdef SQLITE_ENABLE_OTA
/*
** Allocate and populate the output arrays returned by the 
** sqlite3_index_writer() function.
*/
static int indexWriterOutputVars(
  sqlite3 *db,
  Index *pIdx,
  const char ***pazColl,          /* OUT: Array of collation sequences */
  int **paiCol,                   /* OUT: Array of column indexes */
  int *pnCol                      /* OUT: Total columns in index keys */
){
525
526
527
528
529
530
531
532



533
534
535
536
537
538
539
    memcpy(pCsr, zColl, nColl);
    pCsr += nColl;
  }

  return SQLITE_OK;
}





int sqlite3_index_writer(
  sqlite3 *db, 
  int bDelete,
  const char *zIndex, 
  sqlite3_stmt **ppStmt,
  const char ***pazColl,          /* OUT: Array of collation sequences */
  int **paiCol,                   /* OUT: Array of column indexes */







|
>
>
>







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
    memcpy(pCsr, zColl, nColl);
    pCsr += nColl;
  }

  return SQLITE_OK;
}

/*
** Prepare and return an SQL statement handle that can be used to write
** directly to an index b-tree.
*/
int sqlite3_index_writer(
  sqlite3 *db, 
  int bDelete,
  const char *zIndex, 
  sqlite3_stmt **ppStmt,
  const char ***pazColl,          /* OUT: Array of collation sequences */
  int **paiCol,                   /* OUT: Array of column indexes */
630
631
632
633
634
635
636

637
638
  sqlite3ParserReset(pParse);
  sqlite3StackFree(db, pParse);
  sqlite3BtreeLeaveAll(db);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}


#endif /* #ifndef SQLITE_OMIT_INCRBLOB */







>


638
639
640
641
642
643
644
645
646
647
  sqlite3ParserReset(pParse);
  sqlite3StackFree(db, pParse);
  sqlite3BtreeLeaveAll(db);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}
#endif /* SQLITE_ENABLE_OTA */

#endif /* #ifndef SQLITE_OMIT_INCRBLOB */
Changes to src/wal.c.
479
480
481
482
483
484
485







486
487
488
489
490
491
492
493
    u32 *aPgno;                   /* Array of page numbers. */
    int nEntry;                   /* Nr. of entries in aPgno[] and aIndex[] */
    int iZero;                    /* Frame number associated with aPgno[0] */
  } aSegment[1];                  /* One for every 32KB page in the wal-index */
};

/*







** walCheckpoint
*/
typedef struct WalCkpt WalCkpt;
struct WalCkpt {
  sqlite3 *db;                    /* Database pointer (incremental only) */
  int szPage;                     /* Database page-size */
  int sync_flags;                 /* Flags for OsSync() (or 0) */
  u32 mxSafeFrame;                /* Max frame that can be backfilled */







>
>
>
>
>
>
>
|







479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
    u32 *aPgno;                   /* Array of page numbers. */
    int nEntry;                   /* Nr. of entries in aPgno[] and aIndex[] */
    int iZero;                    /* Frame number associated with aPgno[0] */
  } aSegment[1];                  /* One for every 32KB page in the wal-index */
};

/*
** An object of the following type is used to store state information for
** an ongoing checkpoint operation. For normal checkpoints, the instance 
** is allocated on the stack by the walCheckpoint() function. For the special
** incremental checkpoints performed by OTA clients, it is allocated in
** heap memory by sqlite3WalCheckpointStart().
**
** See the implementations of walCheckpointStart(), walCheckpointStep() and 
** walCheckpointFinalize() for further details.
*/
typedef struct WalCkpt WalCkpt;
struct WalCkpt {
  sqlite3 *db;                    /* Database pointer (incremental only) */
  int szPage;                     /* Database page-size */
  int sync_flags;                 /* Flags for OsSync() (or 0) */
  u32 mxSafeFrame;                /* Max frame that can be backfilled */
1638
1639
1640
1641
1642
1643
1644







1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
** The cache of the wal-index header must be valid to call this function.
** Return the page-size in bytes used by the database.
*/
static int walPagesize(Wal *pWal){
  return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
}








static int walCheckpointStart(
  Wal *pWal, 
  u8 *aBuf,                       /* Page-sized temporary buffer */
  int nBuf,                       /* Size of aBuf[] in bytes */
  int (*xBusy)(void*),            /* Function to call when busy (or NULL) */
  void *pBusyArg,                 /* Context argument for xBusyHandler */
  int sync_flags,                 /* Flags for OsSync() (or 0) */
  WalCkpt *p                      /* Allocated object to populate */
){
  int rc;                         /* Return code */
  int i;                          /* Iterator variable */

  memset(p, 0, sizeof(WalCkpt));

  if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
    return SQLITE_CORRUPT_BKPT;
  }

  p->szPage = walPagesize(pWal);
  p->pWal = pWal;
  p->aBuf = aBuf;







>
>
>
>
>
>
>

|











<







1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671

1672
1673
1674
1675
1676
1677
1678
** The cache of the wal-index header must be valid to call this function.
** Return the page-size in bytes used by the database.
*/
static int walPagesize(Wal *pWal){
  return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
}

/*
** Initialize the contents of the WalCkpt object indicated by the final
** argument and begin a checkpoint operation. The CKPT lock must already
** be held when this function is called.
**
** Return SQLITE_OK if successful or an error code otherwise.
*/
static int walCheckpointStart(
  Wal *pWal,                      /* Wal connection */
  u8 *aBuf,                       /* Page-sized temporary buffer */
  int nBuf,                       /* Size of aBuf[] in bytes */
  int (*xBusy)(void*),            /* Function to call when busy (or NULL) */
  void *pBusyArg,                 /* Context argument for xBusyHandler */
  int sync_flags,                 /* Flags for OsSync() (or 0) */
  WalCkpt *p                      /* Allocated object to populate */
){
  int rc;                         /* Return code */
  int i;                          /* Iterator variable */

  memset(p, 0, sizeof(WalCkpt));

  if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
    return SQLITE_CORRUPT_BKPT;
  }

  p->szPage = walPagesize(pWal);
  p->pWal = pWal;
  p->aBuf = aBuf;
1725
1726
1727
1728
1729
1730
1731






1732
1733
1734
1735
1736
1737
1738
      }
    }
  }

  return rc;
}







static int walCheckpointStep(WalCkpt *p){
  u32 iDbpage = 0;                /* Next database page to write */
  u32 iFrame = 0;                 /* Wal frame containing data for iDbpage */
  int rc = SQLITE_DONE;

  assert( p->rc==SQLITE_OK );
  while( p->pIter && 0==walIteratorNext(p->pIter, &iDbpage, &iFrame) ){







>
>
>
>
>
>







1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
      }
    }
  }

  return rc;
}

/*
** Attempt to copy the next frame from the wal file to the database file. If
** there are no more frames to copy to the database file return SQLITE_DONE.
** If the frame is successfully copied, return SQLITE_OK. Or, if an error
** occurs, return an SQLite error code.
*/
static int walCheckpointStep(WalCkpt *p){
  u32 iDbpage = 0;                /* Next database page to write */
  u32 iFrame = 0;                 /* Wal frame containing data for iDbpage */
  int rc = SQLITE_DONE;

  assert( p->rc==SQLITE_OK );
  while( p->pIter && 0==walIteratorNext(p->pIter, &iDbpage, &iFrame) ){
1756
1757
1758
1759
1760
1761
1762










1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782


1783
1784
1785




1786
1787
1788
1789
1790
1791
1792
    break;
  }

  p->rc = rc;
  return rc;
}











static int walCheckpointFinalize(WalCkpt *p){
  if( p->pIter ){
    int rc = p->rc;
    Wal *pWal = p->pWal;

    if( rc==SQLITE_DONE ){
      /* If work was completed */
      rc = SQLITE_OK;
      if( p->mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
        i64 szDb = pWal->hdr.nPage*(i64)p->szPage;
        testcase( IS_BIG_INT(szDb) );
        rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
        if( rc==SQLITE_OK && p->sync_flags ){
          rc = sqlite3OsSync(pWal->pDbFd, p->sync_flags);
        }
      }
      if( rc==SQLITE_OK ){
        p->pInfo->nBackfill = p->mxSafeFrame;
      }
      p->rc = rc;


    }else if( rc==SQLITE_OK && p->sync_flags ){
      /* If work was not completed, but no error has occured. */
      p->rc = sqlite3OsSync(pWal->pDbFd, p->sync_flags);




    }

    /* Release the reader lock held while backfilling */
    walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
    walIteratorFree(p->pIter);
    p->pIter = 0;
  }







>
>
>
>
>
>
>
>
>
>




















>
>
|
|
|
>
>
>
>







1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
    break;
  }

  p->rc = rc;
  return rc;
}

/*
** The current round of checkpointing work using the object indicated by
** the only argument is now finished. If no error occcurred, this function
** saves the results to shared memory (i.e. updates the WalCkptInfo.nBackfill
** variable), and truncates and syncs the database file as required.
**
** All dynamic resources currently held by the WalCkpt object are released. 
** It is the responsibility of the caller to delete the WalCkpt itself if
** required.
*/
static int walCheckpointFinalize(WalCkpt *p){
  if( p->pIter ){
    int rc = p->rc;
    Wal *pWal = p->pWal;

    if( rc==SQLITE_DONE ){
      /* If work was completed */
      rc = SQLITE_OK;
      if( p->mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
        i64 szDb = pWal->hdr.nPage*(i64)p->szPage;
        testcase( IS_BIG_INT(szDb) );
        rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
        if( rc==SQLITE_OK && p->sync_flags ){
          rc = sqlite3OsSync(pWal->pDbFd, p->sync_flags);
        }
      }
      if( rc==SQLITE_OK ){
        p->pInfo->nBackfill = p->mxSafeFrame;
      }
      p->rc = rc;
    }else{
#ifdef SQLITE_ENABLE_OTA
      if( rc==SQLITE_OK && p->sync_flags ){
        /* If work was not completed, but no error has occured. */
        p->rc = sqlite3OsSync(pWal->pDbFd, p->sync_flags);
      }
#else
      assert( rc!=SQLITE_OK );
#endif
    }

    /* Release the reader lock held while backfilling */
    walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
    walIteratorFree(p->pIter);
    p->pIter = 0;
  }
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
  rc = walCheckpointStart(pWal, zBuf, nBuf, xBusy, pBusyArg, sync_flags, &sC);
  if( sC.pIter==0 ) goto walcheckpoint_out;
  assert( rc==SQLITE_OK );

  /* Step the checkpoint object until it reports something other than 
  ** SQLITE_OK.  */
  while( SQLITE_OK==(rc = walCheckpointStep(&sC)) );
  if( rc==SQLITE_DONE ) rc = SQLITE_OK;
  rc = walCheckpointFinalize(&sC);

  /* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal
  ** file has been copied into the database file, then block until all
  ** readers have finished using the wal file. This ensures that the next
  ** process to write to the database restarts the wal file.
  */







<







1877
1878
1879
1880
1881
1882
1883

1884
1885
1886
1887
1888
1889
1890
  rc = walCheckpointStart(pWal, zBuf, nBuf, xBusy, pBusyArg, sync_flags, &sC);
  if( sC.pIter==0 ) goto walcheckpoint_out;
  assert( rc==SQLITE_OK );

  /* Step the checkpoint object until it reports something other than 
  ** SQLITE_OK.  */
  while( SQLITE_OK==(rc = walCheckpointStep(&sC)) );

  rc = walCheckpointFinalize(&sC);

  /* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal
  ** file has been copied into the database file, then block until all
  ** readers have finished using the wal file. This ensures that the next
  ** process to write to the database restarts the wal file.
  */
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916

1917


1918
1919
1920
1921
1922
1923
1924
    sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
  }
}

/*
** Close a connection to a log file.
**
** If parameter zBuf is not NULL, attempt to obtain an exclusive lock 
** and run a checkpoint.
*/
int sqlite3WalClose(
  Wal *pWal,                      /* Wal to close */
  int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
  int nBuf,
  u8 *zBuf                        /* Buffer of at least nBuf bytes */
){
  int rc = SQLITE_OK;
  if( pWal ){
    int isDelete = 0;             /* True to unlink wal and wal-index files */

    /* If an EXCLUSIVE lock can be obtained on the database file (using the
    ** ordinary, rollback-mode locking methods, this guarantees that the
    ** connection associated with this log file is the only connection to
    ** the database. In this case checkpoint the database and unlink both
    ** the wal and wal-index files.
    **
    ** The EXCLUSIVE lock is not released before returning.
    */

    if( zBuf ){


      rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
      if( rc==SQLITE_OK ){
        if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
          pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
        }
        rc = sqlite3WalCheckpoint(
            pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0







|
|



















>
|
>
>







1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
    sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
  }
}

/*
** Close a connection to a log file.
**
** If parameter zBuf is not NULL, also attempt to obtain an exclusive 
** lock and run a checkpoint.
*/
int sqlite3WalClose(
  Wal *pWal,                      /* Wal to close */
  int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
  int nBuf,
  u8 *zBuf                        /* Buffer of at least nBuf bytes */
){
  int rc = SQLITE_OK;
  if( pWal ){
    int isDelete = 0;             /* True to unlink wal and wal-index files */

    /* If an EXCLUSIVE lock can be obtained on the database file (using the
    ** ordinary, rollback-mode locking methods, this guarantees that the
    ** connection associated with this log file is the only connection to
    ** the database. In this case checkpoint the database and unlink both
    ** the wal and wal-index files.
    **
    ** The EXCLUSIVE lock is not released before returning.
    */
#ifdef SQLITE_ENABLE_OTA
    if( zBuf )          /* In non-OTA builds, zBuf is always non-NULL */
#endif
    {
      rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
      if( rc==SQLITE_OK ){
        if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
          pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
        }
        rc = sqlite3WalCheckpoint(
            pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
3067
3068
3069
3070
3071
3072
3073





3074
3075
3076
3077
3078
3079
3080
3081
3082








3083
3084
3085
3086
3087
3088
3089
  sqlite3WalEndWriteTransaction(pWal);
  walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
  pWal->ckptLock = 0;
  WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
  return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
}






int sqlite3_ckpt_step(sqlite3_ckpt *pCkpt){
  int rc;
  WalCkpt *p = (WalCkpt*)pCkpt;
  sqlite3_mutex_enter(p->db->mutex);
  rc = walCheckpointStep(p);
  sqlite3_mutex_leave(p->db->mutex);
  return rc;
}









int sqlite3_ckpt_close(sqlite3_ckpt *pCkpt, u8 **paState, int *pnState){
  int rc;
  WalCkpt *p = (WalCkpt*)pCkpt;
  sqlite3 *db = p->db;
  Wal *pWal = p->pWal;
  sqlite3_mutex_enter(db->mutex);
  if( paState ){







>
>
>
>
>









>
>
>
>
>
>
>
>







3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
  sqlite3WalEndWriteTransaction(pWal);
  walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
  pWal->ckptLock = 0;
  WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
  return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
}

#ifdef SQLITE_ENABLE_OTA

/*
** Step the checkpoint object passed as the first argument.
*/
int sqlite3_ckpt_step(sqlite3_ckpt *pCkpt){
  int rc;
  WalCkpt *p = (WalCkpt*)pCkpt;
  sqlite3_mutex_enter(p->db->mutex);
  rc = walCheckpointStep(p);
  sqlite3_mutex_leave(p->db->mutex);
  return rc;
}

/*
** Close the checkpoint object passed as the first argument. If the checkpoint
** was completed, zero the two output variables. Otherwise, set *paState to
** point to a buffer containing data that may be passed to a subsequent 
** call to ckpt_open() to resume the checkpoint. In this case *pnState is
** set to the size of the buffer in bytes. The buffer should be eventually
** freed by the caller using sqlite3_free().
*/
int sqlite3_ckpt_close(sqlite3_ckpt *pCkpt, u8 **paState, int *pnState){
  int rc;
  WalCkpt *p = (WalCkpt*)pCkpt;
  sqlite3 *db = p->db;
  Wal *pWal = p->pWal;
  sqlite3_mutex_enter(db->mutex);
  if( paState ){
3188
3189
3190
3191
3192
3193
3194



















3195
3196
3197
3198
3199
3200
3201
    sqlite3_free(p);
    p = 0;
  }
  *ppCkpt = (sqlite3_ckpt*)p;
  return rc;
}




















/* Return the value to pass to a sqlite3_wal_hook callback, the
** number of frames in the WAL at the point of the last commit since
** sqlite3WalCallback() was called.  If no commits have occurred since
** the last call, then return 0.
*/
int sqlite3WalCallback(Wal *pWal){
  u32 ret = 0;







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







3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
    sqlite3_free(p);
    p = 0;
  }
  *ppCkpt = (sqlite3_ckpt*)p;
  return rc;
}

/*
** Unless the wal file is empty, check that the 8 bytes of salt stored in
** the wal header are identical to those in the buffer indicated by the
** second argument. If they are not, return SQLITE_BUSY_SNAPSHOT. Otherwise,
** if the buffers match or the WAL file is empty, return SQLITE_OK.
*/
int sqlite3WalCheckSalt(Wal *pWal, sqlite3_file *pFd){
  int rc = SQLITE_OK;
  if( pWal->hdr.mxFrame>0 ){
    u8 aData[16];
    rc = sqlite3OsRead(pFd, aData, sizeof(aData), 24);
    if( rc==SQLITE_OK && memcmp(pWal->hdr.aSalt, aData, 8) ){
      rc = SQLITE_BUSY_SNAPSHOT;
    }
  }
  return rc;
}
#endif /* SQLITE_ENABLE_OTA */

/* Return the value to pass to a sqlite3_wal_hook callback, the
** number of frames in the WAL at the point of the last commit since
** sqlite3WalCallback() was called.  If no commits have occurred since
** the last call, then return 0.
*/
int sqlite3WalCallback(Wal *pWal){
  u32 ret = 0;
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
** WAL module is using shared-memory, return false. 
*/
int sqlite3WalHeapMemory(Wal *pWal){
  return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
}

/*
** Unless the wal file is empty, check that the 8 bytes of salt stored in
** the wal header are identical to those in the buffer indicated by the
** second argument. If they are not, return SQLITE_BUSY_SNAPSHOT. Otherwise,
** if the buffers match or the WAL file is empty, return SQLITE_OK.
*/
int sqlite3WalCheckSalt(Wal *pWal, sqlite3_file *pFd){
  int rc = SQLITE_OK;
  if( pWal->hdr.mxFrame>0 ){
    u8 aData[16];
    rc = sqlite3OsRead(pFd, aData, sizeof(aData), 24);
    if( rc==SQLITE_OK && memcmp(pWal->hdr.aSalt, aData, 8) ){
      rc = SQLITE_BUSY_SNAPSHOT;
    }
  }
  return rc;
}

#ifdef SQLITE_ENABLE_ZIPVFS
/*
** If the argument is not NULL, it points to a Wal object that holds a
** read-lock. This function returns the database page-size if it is known,
** or zero if it is not (or if pWal is NULL).
*/
int sqlite3WalFramesize(Wal *pWal){
  assert( pWal==0 || pWal->readLock>=0 );
  return (pWal ? pWal->szPage : 0);
}
#endif

#endif /* #ifndef SQLITE_OMIT_WAL */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













3341
3342
3343
3344
3345
3346
3347


















3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
** WAL module is using shared-memory, return false. 
*/
int sqlite3WalHeapMemory(Wal *pWal){
  return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
}



















#ifdef SQLITE_ENABLE_ZIPVFS
/*
** If the argument is not NULL, it points to a Wal object that holds a
** read-lock. This function returns the database page-size if it is known,
** or zero if it is not (or if pWal is NULL).
*/
int sqlite3WalFramesize(Wal *pWal){
  assert( pWal==0 || pWal->readLock>=0 );
  return (pWal ? pWal->szPage : 0);
}
#endif

#endif /* #ifndef SQLITE_OMIT_WAL */
Changes to test/ota.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16

# 2014 September 20
#
#    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 rtree related tests.
#

set testdir [file dirname $argv0]
source $testdir/permutations.test

run_test_suite ota


finish_test














|

>

>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 2014 September 20
#
#    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 rtree related tests.
#

set testdir [file dirname $argv0]
source $testdir/permutations.test

ifcapable !ota { finish_test ; return }

run_test_suite ota
finish_test

Changes to tool/mkpragmatab.tcl.
294
295
296
297
298
299
300

301
302
303
304

305
306
307
308
309
310
311
  IF:   defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)

  NAME: soft_heap_limit

  NAME: threads

  NAME: pager_ota_mode


  NAME: ota_mode
  TYPE: FLAG
  ARG:  SQLITE_OtaMode

}
fconfigure stdout -translation lf
set name {}
set type {}
set if {}
set flags {}
set arg 0







>




>







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
  IF:   defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)

  NAME: soft_heap_limit

  NAME: threads

  NAME: pager_ota_mode
  IF:   defined(SQLITE_ENABLE_OTA)

  NAME: ota_mode
  TYPE: FLAG
  ARG:  SQLITE_OtaMode
  IF:   defined(SQLITE_ENABLE_OTA)
}
fconfigure stdout -translation lf
set name {}
set type {}
set if {}
set flags {}
set arg 0