SQLite

Check-in [dcc407972a]
Login

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

Overview
Comment:Make the freelist format a separate feature from the page-level locking. Freelist format is now configure using "PRAGMA freelist_format".
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | server-process-edition
Files: files | file ages | folders
SHA3-256: dcc407972aa213d28f95cbaf4da5ab7d89ddbad2740f41cfb44b2c2ce20a3132
User & Date: dan 2017-07-13 21:06:51.922
Context
2017-07-14
08:15
Add simple tests for "PRAGMA freelist_format". (check-in: 98a36f4cf1 user: dan tags: server-process-edition)
2017-07-13
21:06
Make the freelist format a separate feature from the page-level locking. Freelist format is now configure using "PRAGMA freelist_format". (check-in: dcc407972a user: dan tags: server-process-edition)
2017-07-11
18:38
Add SQL function usleep() to test program tserver.c. (check-in: 8cbe8f2b2f user: dan tags: server-process-edition)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
234
235
236
237
238
239
240









241
242
243
244
245
246
247
      return 1;
    }
  }
  return 0;
}
#endif    /* #ifdef SQLITE_DEBUG */










/*
** Query to see if Btree handle p may obtain a lock of type eLock 
** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
** SQLITE_OK if the lock may be obtained (by calling
** setSharedCacheTableLock()), or SQLITE_LOCKED if not.
*/
static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){







>
>
>
>
>
>
>
>
>







234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
      return 1;
    }
  }
  return 0;
}
#endif    /* #ifdef SQLITE_DEBUG */

#ifdef SQLITE_SERVER_EDITION
/*
** Return true if the b-tree uses free-list format 2. Or false otherwise.
*/
static int btreeFreelistFormat2(BtShared *pBt){
  return (pBt->pPage1->aData[18] > 2);
}
#endif

/*
** Query to see if Btree handle p may obtain a lock of type eLock 
** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
** SQLITE_OK if the lock may be obtained (by calling
** setSharedCacheTableLock()), or SQLITE_LOCKED if not.
*/
static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){
2923
2924
2925
2926
2927
2928
2929









2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
  if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
    nPage = nPageFile;
  }
  if( nPage>0 ){
    u32 pageSize;
    u32 usableSize;
    u8 *page1 = pPage1->aData;









    rc = SQLITE_NOTADB;
    /* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins
    ** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d
    ** 61 74 20 33 00. */
    if( memcmp(page1, zMagicHeader, 16)!=0 ){
      goto page1_init_failed;
    }

#ifdef SQLITE_OMIT_WAL
    if( page1[18]>1 ){
      pBt->btsFlags |= BTS_READ_ONLY;
    }
    if( page1[19]>1 ){
      goto page1_init_failed;
    }
#else
    if( page1[18]>2 ){
      pBt->btsFlags |= BTS_READ_ONLY;
    }
    if( page1[19]>2 ){
      goto page1_init_failed;
    }

    /* If the write version is set to 2, this database should be accessed
    ** in WAL mode. If the log is not already open, open it now. Then 
    ** return SQLITE_OK and return without populating BtShared.pPage1.
    ** The caller detects this and calls this function again. This is
    ** required as the version of page 1 currently in the page1 buffer
    ** may not be the latest version - there may be a newer one in the log
    ** file.
    */
    if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){
      int isOpen = 0;
      rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen);
      if( rc!=SQLITE_OK ){
        goto page1_init_failed;
      }else{
        setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1);
        if( isOpen==0 ){







>
>
>
>
>
>
>
>
>









|


|



|


|











|







2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
  if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
    nPage = nPageFile;
  }
  if( nPage>0 ){
    u32 pageSize;
    u32 usableSize;
    u8 *page1 = pPage1->aData;
    u8 i18 = page1[18];
    u8 i19 = page1[19];
#ifdef SQLITE_SERVER_EDITION
    if( i18==i19 && i18>2 ){
      i18 -= 2;
      i19 -= 2;
    }
#endif

    rc = SQLITE_NOTADB;
    /* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins
    ** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d
    ** 61 74 20 33 00. */
    if( memcmp(page1, zMagicHeader, 16)!=0 ){
      goto page1_init_failed;
    }

#ifdef SQLITE_OMIT_WAL
    if( i18>1 ){
      pBt->btsFlags |= BTS_READ_ONLY;
    }
    if( i19>1 ){
      goto page1_init_failed;
    }
#else
    if( i18>2 ){
      pBt->btsFlags |= BTS_READ_ONLY;
    }
    if( i19>2 ){
      goto page1_init_failed;
    }

    /* If the write version is set to 2, this database should be accessed
    ** in WAL mode. If the log is not already open, open it now. Then 
    ** return SQLITE_OK and return without populating BtShared.pPage1.
    ** The caller detects this and calls this function again. This is
    ** required as the version of page 1 currently in the page1 buffer
    ** may not be the latest version - there may be a newer one in the log
    ** file.
    */
    if( i19==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){
      int isOpen = 0;
      rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen);
      if( rc!=SQLITE_OK ){
        goto page1_init_failed;
      }else{
        setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1);
        if( isOpen==0 ){
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
  int rc;
  u32 n;     /* Number of pages on the freelist */
  u32 k;     /* Number of leaves on the trunk of the freelist */
  MemPage *pTrunk = 0;
  MemPage *pPrevTrunk = 0;
  Pgno mxPage;     /* Total size of the database file */

  if( sqlite3PagerIsServer(pBt->pPager) ){
    return allocateServerPage(pBt, ppPage, pPgno, nearby, eMode); 
  }

  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) );
  pPage1 = pBt->pPage1;
  mxPage = btreePagecount(pBt);







|







5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
  int rc;
  u32 n;     /* Number of pages on the freelist */
  u32 k;     /* Number of leaves on the trunk of the freelist */
  MemPage *pTrunk = 0;
  MemPage *pPrevTrunk = 0;
  Pgno mxPage;     /* Total size of the database file */

  if( btreeFreelistFormat2(pBt) ){
    return allocateServerPage(pBt, ppPage, pPgno, nearby, eMode); 
  }

  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) );
  pPage1 = pBt->pPage1;
  mxPage = btreePagecount(pBt);
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
     ||            ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
    ){
      goto freepage_out;
    }
    memset(pPage->aData, 0, pPage->pBt->pageSize);
  }
  
  if( sqlite3PagerIsServer(pBt->pPager) ){
    rc = freeServerPage2(pBt, pPage, iPage);
    goto freepage_out;
  }

  /* Increment the free page count on pPage1 */
  rc = sqlite3PagerWrite(pPage1->pDbPage);
  if( rc ) goto freepage_out;







|







6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
     ||            ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
    ){
      goto freepage_out;
    }
    memset(pPage->aData, 0, pPage->pBt->pageSize);
  }
  
  if( btreeFreelistFormat2(pBt) ){
    rc = freeServerPage2(pBt, pPage, iPage);
    goto freepage_out;
  }

  /* Increment the free page count on pPage1 */
  rc = sqlite3PagerWrite(pPage1->pDbPage);
  if( rc ) goto freepage_out;
9812
9813
9814
9815
9816
9817
9818
9819
9820
9821
9822
9823
9824
9825
9826
  i = PENDING_BYTE_PAGE(pBt);
  if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);

  /* Check the integrity of the freelist
  */
  sCheck.zPfx = "Main freelist: ";
#ifdef SQLITE_SERVER_EDITION
  if( sqlite3PagerIsServer(pBt->pPager) ){
    checkServerList(&sCheck);
  }else
#endif
  {
    checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
        get4byte(&pBt->pPage1->aData[36]));
  }







|







9830
9831
9832
9833
9834
9835
9836
9837
9838
9839
9840
9841
9842
9843
9844
  i = PENDING_BYTE_PAGE(pBt);
  if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);

  /* Check the integrity of the freelist
  */
  sCheck.zPfx = "Main freelist: ";
#ifdef SQLITE_SERVER_EDITION
  if( btreeFreelistFormat2(pBt) ){
    checkServerList(&sCheck);
  }else
#endif
  {
    checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
        get4byte(&pBt->pPage1->aData[36]));
  }
10087
10088
10089
10090
10091
10092
10093































10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110



10111
10112

10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127

10128
10129
10130
10131
10132
10133
10134
** Mark this cursor as an incremental blob cursor.
*/
void sqlite3BtreeIncrblobCursor(BtCursor *pCur){
  pCur->curFlags |= BTCF_Incrblob;
  pCur->pBtree->hasIncrblobCur = 1;
}
#endif
































/*
** Set both the "read version" (single byte at byte offset 18) and 
** "write version" (single byte at byte offset 19) fields in the database
** header to iVersion.
*/
int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
  BtShared *pBt = pBtree->pBt;
  int rc;                         /* Return code */
 
  assert( iVersion==1 || iVersion==2 );

  /* If setting the version fields to 1, do not automatically open the
  ** WAL connection, even if the version fields are currently set to 2.
  */
  pBt->btsFlags &= ~BTS_NO_WAL;
  if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL;




  rc = sqlite3BtreeBeginTrans(pBtree, 0);

  if( rc==SQLITE_OK ){
    u8 *aData = pBt->pPage1->aData;
    if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){
      rc = sqlite3BtreeBeginTrans(pBtree, 2);
      if( rc==SQLITE_OK ){
        rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
        if( rc==SQLITE_OK ){
          aData[18] = (u8)iVersion;
          aData[19] = (u8)iVersion;
        }
      }
    }
  }

  pBt->btsFlags &= ~BTS_NO_WAL;

  return rc;
}

/*
** Return true if the cursor has a hint specified.  This routine is
** only used from within assert() statements
*/







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

















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







10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131
10132
10133
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145
10146
10147
10148
10149
10150
10151
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166


10167
10168
10169

10170
10171
10172
10173


10174

10175
10176
10177
10178
10179
10180
10181
10182
** Mark this cursor as an incremental blob cursor.
*/
void sqlite3BtreeIncrblobCursor(BtCursor *pCur){
  pCur->curFlags |= BTCF_Incrblob;
  pCur->pBtree->hasIncrblobCur = 1;
}
#endif

int btreeSetVersion(Btree *pBtree, int iVersion, int iFreelistFmt){
  BtShared *pBt = pBtree->pBt;
  int rc = sqlite3BtreeBeginTrans(pBtree, 0);
  if( rc==SQLITE_OK ){
    u8 iVal;
    u8 *aData = pBt->pPage1->aData;

    assert( (iVersion==0 && (iFreelistFmt==1 || iFreelistFmt==2))
         || (iFreelistFmt==0 && (iVersion==1 || iVersion==2))
    );
    if( iVersion==0 ){
      iVal = ((aData[18] & 0x01) ? 1 : 2) + (u8)(iFreelistFmt==2 ? 2 : 0);
    }else{
      iVal = (u8)iVersion + (u8)(aData[18]>2 ? 2 : 0);
    }

    if( aData[18]!=iVal || aData[19]!=iVal ){
      rc = sqlite3BtreeBeginTrans(pBtree, 2);
      if( rc==SQLITE_OK ){
        rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
        if( rc==SQLITE_OK ){
          aData[18] = iVal;
          aData[19] = iVal;
        }
      }
    }
  }

  return rc;
}

/*
** Set both the "read version" (single byte at byte offset 18) and 
** "write version" (single byte at byte offset 19) fields in the database
** header to iVersion.
*/
int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
  BtShared *pBt = pBtree->pBt;
  int rc;                         /* Return code */
 
  assert( iVersion==1 || iVersion==2 );

  /* If setting the version fields to 1, do not automatically open the
  ** WAL connection, even if the version fields are currently set to 2.
  */
  pBt->btsFlags &= ~BTS_NO_WAL;
  if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL;
  rc = btreeSetVersion(pBtree, iVersion, 0); 
  pBt->btsFlags &= ~BTS_NO_WAL;
  return rc;
}

int sqlite3BtreeFreelistFormat(Btree *p, int eParam, int *peFmt){
  int rc = SQLITE_OK;


  sqlite3BtreeEnter(p);
  if( eParam ){
    u8 *aData = p->pBt->pPage1->aData;

    if( 0==get4byte(&aData[32]) ){
      rc = btreeSetVersion(p, 0, eParam);
    }
  }


  *peFmt = (btreeFreelistFormat2(p->pBt) ? 2 : 1);

  sqlite3BtreeLeave(p);
  return rc;
}

/*
** Return true if the cursor has a hint specified.  This routine is
** only used from within assert() statements
*/
Changes to src/btree.h.
363
364
365
366
367
368
369



370
371
# define sqlite3BtreeLeaveAll(X)

# define sqlite3BtreeHoldsMutex(X) 1
# define sqlite3BtreeHoldsAllMutexes(X) 1
# define sqlite3SchemaMutexHeld(X,Y,Z) 1
#endif





#endif /* SQLITE_BTREE_H */







>
>
>


363
364
365
366
367
368
369
370
371
372
373
374
# define sqlite3BtreeLeaveAll(X)

# define sqlite3BtreeHoldsMutex(X) 1
# define sqlite3BtreeHoldsAllMutexes(X) 1
# define sqlite3SchemaMutexHeld(X,Y,Z) 1
#endif

#ifdef SQLITE_SERVER_EDITION
int sqlite3BtreeFreelistFormat(Btree *p, int eParam, int *peFmt);
#endif

#endif /* SQLITE_BTREE_H */
Changes to src/pragma.c.
651
652
653
654
655
656
657



























658
659
660
661
662
663
664
        sqlite3VdbeUsesBtree(v, ii);
        sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode);
      }
    }
    sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
    break;
  }




























  /*
  **  PRAGMA [schema.]journal_size_limit
  **  PRAGMA [schema.]journal_size_limit=N
  **
  ** Get or set the size limit on rollback journal files.
  */







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







651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
        sqlite3VdbeUsesBtree(v, ii);
        sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode);
      }
    }
    sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
    break;
  }

#ifdef SQLITE_SERVER_EDITION
  /*
  **  PRAGMA [schema.]freelist_format
  **  PRAGMA [schema.]freelist_format = (1|2)
  */
  case PragTyp_FREELIST_FORMAT: {
    sqlite3VdbeUsesBtree(v, iDb);
    static const VdbeOpList freelist[] = {
      { OP_Transaction,    0,  0,  0},    /* 0 */
      { OP_FreelistFmt,    0,  1,  0},    /* 1 */
      { OP_ResultRow,      1,  1,  0}     /* 2 */
    };
    VdbeOp *aOp;
    sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(freelist));
    aOp = sqlite3VdbeAddOpList(v, ArraySize(freelist), freelist,0);
    aOp[0].p1 = iDb;
    aOp[1].p1 = iDb;

    if( zRight && (zRight[0]=='1' || zRight[0]=='2') && zRight[1]=='\0' ){
      aOp[0].p2 = 1;              /* Open a write transaction */
      aOp[1].p3 = (int)(zRight[0] - '0');
    }

    break;
  }
#endif

  /*
  **  PRAGMA [schema.]journal_size_limit
  **  PRAGMA [schema.]journal_size_limit=N
  **
  ** Get or set the size limit on rollback journal files.
  */
Changes to src/pragma.h.
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
47
48
49
50
51
52
53
54
55
56
57
58
#define PragTyp_COMPILE_OPTIONS                8
#define PragTyp_DATA_STORE_DIRECTORY           9
#define PragTyp_DATABASE_LIST                 10
#define PragTyp_DEFAULT_CACHE_SIZE            11
#define PragTyp_ENCODING                      12
#define PragTyp_FOREIGN_KEY_CHECK             13
#define PragTyp_FOREIGN_KEY_LIST              14

#define PragTyp_INCREMENTAL_VACUUM            15
#define PragTyp_INDEX_INFO                    16
#define PragTyp_INDEX_LIST                    17
#define PragTyp_INTEGRITY_CHECK               18
#define PragTyp_JOURNAL_MODE                  19
#define PragTyp_JOURNAL_SIZE_LIMIT            20
#define PragTyp_LOCK_PROXY_FILE               21
#define PragTyp_LOCKING_MODE                  22
#define PragTyp_PAGE_COUNT                    23
#define PragTyp_MMAP_SIZE                     24
#define PragTyp_OPTIMIZE                      25
#define PragTyp_PAGE_SIZE                     26
#define PragTyp_SECURE_DELETE                 27
#define PragTyp_SHRINK_MEMORY                 28
#define PragTyp_SOFT_HEAP_LIMIT               29
#define PragTyp_SYNCHRONOUS                   30
#define PragTyp_TABLE_INFO                    31
#define PragTyp_TEMP_STORE                    32
#define PragTyp_TEMP_STORE_DIRECTORY          33
#define PragTyp_THREADS                       34
#define PragTyp_WAL_AUTOCHECKPOINT            35
#define PragTyp_WAL_CHECKPOINT                36
#define PragTyp_ACTIVATE_EXTENSIONS           37
#define PragTyp_HEXKEY                        38
#define PragTyp_KEY                           39
#define PragTyp_REKEY                         40
#define PragTyp_LOCK_STATUS                   41
#define PragTyp_PARSER_TRACE                  42
#define PragTyp_STATS                         43

/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
#define PragFlg_NoColumns  0x02 /* OP_ResultRow called with zero columns */
#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
#define PragFlg_ReadOnly   0x08 /* Read-only HEADER_VALUE */
#define PragFlg_Result0    0x10 /* Acts as query when no argument */







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







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
47
48
49
50
51
52
53
54
55
56
57
58
59
#define PragTyp_COMPILE_OPTIONS                8
#define PragTyp_DATA_STORE_DIRECTORY           9
#define PragTyp_DATABASE_LIST                 10
#define PragTyp_DEFAULT_CACHE_SIZE            11
#define PragTyp_ENCODING                      12
#define PragTyp_FOREIGN_KEY_CHECK             13
#define PragTyp_FOREIGN_KEY_LIST              14
#define PragTyp_FREELIST_FORMAT               15
#define PragTyp_INCREMENTAL_VACUUM            16
#define PragTyp_INDEX_INFO                    17
#define PragTyp_INDEX_LIST                    18
#define PragTyp_INTEGRITY_CHECK               19
#define PragTyp_JOURNAL_MODE                  20
#define PragTyp_JOURNAL_SIZE_LIMIT            21
#define PragTyp_LOCK_PROXY_FILE               22
#define PragTyp_LOCKING_MODE                  23
#define PragTyp_PAGE_COUNT                    24
#define PragTyp_MMAP_SIZE                     25
#define PragTyp_OPTIMIZE                      26
#define PragTyp_PAGE_SIZE                     27
#define PragTyp_SECURE_DELETE                 28
#define PragTyp_SHRINK_MEMORY                 29
#define PragTyp_SOFT_HEAP_LIMIT               30
#define PragTyp_SYNCHRONOUS                   31
#define PragTyp_TABLE_INFO                    32
#define PragTyp_TEMP_STORE                    33
#define PragTyp_TEMP_STORE_DIRECTORY          34
#define PragTyp_THREADS                       35
#define PragTyp_WAL_AUTOCHECKPOINT            36
#define PragTyp_WAL_CHECKPOINT                37
#define PragTyp_ACTIVATE_EXTENSIONS           38
#define PragTyp_HEXKEY                        39
#define PragTyp_KEY                           40
#define PragTyp_REKEY                         41
#define PragTyp_LOCK_STATUS                   42
#define PragTyp_PARSER_TRACE                  43
#define PragTyp_STATS                         44

/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
#define PragFlg_NoColumns  0x02 /* OP_ResultRow called with zero columns */
#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
#define PragFlg_ReadOnly   0x08 /* Read-only HEADER_VALUE */
#define PragFlg_Result0    0x10 /* Acts as query when no argument */
289
290
291
292
293
294
295







296
297
298
299
300
301
302
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
 {/* zName:     */ "freelist_count",
  /* ePragTyp:  */ PragTyp_HEADER_VALUE,
  /* ePragFlg:  */ PragFlg_ReadOnly|PragFlg_Result0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ BTREE_FREE_PAGE_COUNT },







#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 {/* zName:     */ "full_column_names",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_FullColNames },







>
>
>
>
>
>
>







290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
 {/* zName:     */ "freelist_count",
  /* ePragTyp:  */ PragTyp_HEADER_VALUE,
  /* ePragFlg:  */ PragFlg_ReadOnly|PragFlg_Result0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ BTREE_FREE_PAGE_COUNT },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && defined(SQLITE_SERVER_EDITION)
 {/* zName:     */ "freelist_format",
  /* ePragTyp:  */ PragTyp_FREELIST_FORMAT,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 {/* zName:     */ "full_column_names",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_FullColNames },
609
610
611
612
613
614
615
616
 {/* zName:     */ "writable_schema",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_WriteSchema },
#endif
};
/* Number of pragmas: 60 on by default, 74 total. */







|
617
618
619
620
621
622
623
624
 {/* zName:     */ "writable_schema",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_WriteSchema },
#endif
};
/* Number of pragmas: 60 on by default, 75 total. */
Changes to src/vdbe.c.
3372
3373
3374
3375
3376
3377
3378



























3379
3380
3381
3382
3383
3384
3385
    ** schema is changed.  Ticket #1644 */
    sqlite3ExpirePreparedStatements(db);
    p->expired = 0;
  }
  if( rc ) goto abort_due_to_error;
  break;
}




























/* Opcode: OpenRead P1 P2 P3 P4 P5
** Synopsis: root=P2 iDb=P3
**
** Open a read-only cursor for the database table whose root page is
** P2 in a database file.  The database file is determined by P3. 
** P3==0 means the main database, P3==1 means the database used for 







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







3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
    ** schema is changed.  Ticket #1644 */
    sqlite3ExpirePreparedStatements(db);
    p->expired = 0;
  }
  if( rc ) goto abort_due_to_error;
  break;
}

#ifdef SQLITE_SERVER_EDITION
/* Opcode: FreelistFmt P1 P2 P3 * *
**
** Parameter P3 must be 0, 1 or 2. If it is not 0, attempt to set the
** freelist format of database P1 to format 1 or format 2. Before
** returning, store the final freelist format (either 1 or 2) of 
** database P1 into register P2.
*/
case OP_FreelistFmt: {  /* out2 */
  Db *pDb;
  int iVal;

  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( DbMaskTest(p->btreeMask, pOp->p1) );
  assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
  pDb = &db->aDb[pOp->p1];
  assert( pDb->pBt!=0 );

  pOut = out2Prerelease(p, pOp);
  rc = sqlite3BtreeFreelistFormat(pDb->pBt, pOp->p3, &iVal);
  if( rc ) goto abort_due_to_error;
  pOut->u.i = iVal;

  break;
}
#endif

/* Opcode: OpenRead P1 P2 P3 P4 P5
** Synopsis: root=P2 iDb=P3
**
** Open a read-only cursor for the database table whose root page is
** P2 in a database file.  The database file is determined by P3. 
** P3==0 means the main database, P3==1 means the database used for 
Changes to tool/mkpragmatab.tcl.
360
361
362
363
364
365
366




367
368
369
370
371
372
373
  FLAG: Result0

  NAME: threads
  FLAG: Result0

  NAME: optimize
  FLAG: Result1 NeedSchema




}

# Open the output file
#
set destfile "[file dir [file dir [file normal $argv0]]]/src/pragma.h"
puts "Overwriting $destfile with new pragma table..."
set fd [open $destfile wb]







>
>
>
>







360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
  FLAG: Result0

  NAME: threads
  FLAG: Result0

  NAME: optimize
  FLAG: Result1 NeedSchema

  NAME: freelist_format
  FLAG: NeedSchema Result0 SchemaReq
  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS) && defined(SQLITE_SERVER_EDITION)
}

# Open the output file
#
set destfile "[file dir [file dir [file normal $argv0]]]/src/pragma.h"
puts "Overwriting $destfile with new pragma table..."
set fd [open $destfile wb]